diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 53db3d11474e..de92334ba3a7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -7,45 +7,45 @@ Tasks/AndroidSigningV3/ @microsoft/akvelon-build-task-team Tasks/ANTV1/ @microsoft/akvelon-build-task-team -Tasks/AppCenterDistributeV1/ @imenkov @lucen-ms @DergachevE @vsebesta +Tasks/AppCenterDistributeV1/ @imenkov @lucen-ms @DergachevE -Tasks/AppCenterDistributeV2/ @imenkov @lucen-ms @DergachevE @vsebesta +Tasks/AppCenterDistributeV2/ @imenkov @lucen-ms @DergachevE -Tasks/AppCenterDistributeV3/ @imenkov @lucen-ms @DergachevE @vsebesta +Tasks/AppCenterDistributeV3/ @imenkov @lucen-ms @DergachevE -Tasks/AppCenterTestV1/ @imenkov @lucen-ms @DergachevE @vsebesta +Tasks/AppCenterTestV1/ @imenkov @lucen-ms @DergachevE Tasks/ArchiveFilesV2/ @microsoft/akvelon-build-task-team -Tasks/AzureAppServiceManageV0/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureAppServiceManageV0/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureAppServiceSettingsV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureAppServiceSettingsV1/ @rvairavelu @microsoft/pipeline-environment-team Tasks/AzureCLIV1/ @rvairavelu @manolerazvan Tasks/AzureCLIV2/ @rvairavelu @manolerazvan -Tasks/AzureCloudPowerShellDeploymentV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureCloudPowerShellDeploymentV1/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureCloudPowerShellDeploymentV2/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureCloudPowerShellDeploymentV2/ @rvairavelu @microsoft/pipeline-environment-team Tasks/AzureContainerAppsV0/ @cormacpayne @daniv-msft Tasks/AzureContainerAppsV1/ @cormacpayne @daniv-msft -Tasks/AzureFileCopyV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureFileCopyV1/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureFileCopyV2/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureFileCopyV2/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureFileCopyV3/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureFileCopyV3/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureFileCopyV4/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureFileCopyV4/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureFunctionAppV1/ @finvamp1 @patelchandni @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureFunctionAppV1/ @finvamp1 @patelchandni @vsebesta @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureFunctionAppV2/ @finvamp1 @patelchandni @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureFunctionAppV2/ @finvamp1 @patelchandni @vsebesta @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureFunctionAppContainerV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureFunctionAppContainerV1/ @rvairavelu @microsoft/pipeline-environment-team Tasks/AzureFunctionOnKubernetesV0/ @rvairavelu @manolerazvan @@ -63,36 +63,38 @@ Tasks/AzureMonitorV0/ @rvairavelu @manolerazvan Tasks/AzureMonitorV1/ @rvairavelu @manolerazvan -Tasks/AzureMysqlDeploymentV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureMysqlDeploymentV1/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureNLBManagementV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureNLBManagementV1/ @rvairavelu @microsoft/pipeline-environment-team Tasks/AzurePolicyV0/ @rvairavelu @manolerazvan -Tasks/AzurePowerShellV2/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzurePowerShellV2/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzurePowerShellV3/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzurePowerShellV3/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzurePowerShellV4/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzurePowerShellV4/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzurePowerShellV5/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzurePowerShellV5/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team Tasks/AzureResourceGroupDeploymentV2/ @rvairavelu @manolerazvan Tasks/AzureResourceManagerTemplateDeploymentV3/ @rvairavelu @manolerazvan -Tasks/AzureRmWebAppDeploymentV3/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureRmWebAppDeploymentV3/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team -Tasks/AzureRmWebAppDeploymentV4/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureRmWebAppDeploymentV4/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team # DRI rotation: Azure Spring Apps/AzDMSS-Support Tasks/AzureSpringCloudV0 @microsoft/azure-spring-apps @ruoyuwang @menxiao Tasks/AzureStaticWebAppV0/ @microsoft/azure-static-web-apps @mkarmark @joslinmicrosoft -Tasks/AzureWebAppV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureTestPlanV0/ @rasunkar @microsoft\adoautotest -Tasks/AzureWebAppContainerV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/AzureWebAppV1/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team + +Tasks/AzureWebAppContainerV1/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team Tasks/AzureVmssDeploymentV0/ @bishal-pdmsft @@ -108,9 +110,9 @@ Tasks/CacheBetaV1/ @johnterickson Tasks/CargoAuthenticateV0/ @microsoft/azure-artifacts-packages -Tasks/ChefV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/ChefV1/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/ChefKnifeV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/ChefKnifeV1/ @rvairavelu @microsoft/pipeline-environment-team Tasks/CMakeV1/ @microsoft/akvelon-build-task-team @@ -120,7 +122,7 @@ Tasks/CocoaPodsV0/ @microsoft/akvelon-build-task-team Tasks/Common/artifacts-common/ @microsoft/azure-artifacts-packages -Tasks/Common/AzureRmDeploy-common/ @vincentdass @vsebesta @rvairavelu @pipeline-environment-team +Tasks/Common/AzureRmDeploy-common/ @vincentdass @vsebesta @rvairavelu @microsoft/pipeline-environment-team Tasks/Common/Deployment/ @bishal-pdMSFT @vsebesta @rvairavelu @@ -140,7 +142,7 @@ Tasks/Common/VstsAzureRestHelpers_/ @Ajay-MS @rajatagrawal-dev Tasks/Common/azure-arm-rest/ @rvairavelu @manolerazvan -Tasks/Common/azure-arm-rest-v2/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/Common/azure-arm-rest-v2/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team Tasks/Common/azure-blobstorage-artifactProvider/ @omeshp @hiyadav @bishal-pdmsft @@ -162,7 +164,7 @@ Tasks/Common/securefiles-common/ @microsoft/akvelon-build-task-team @hashtag Tasks/Common/utility-common/ @nishubansal @ds-ms -Tasks/Common/webdeployment-common/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/Common/webdeployment-common/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team Tasks/CondaAuthenticateV0/ @microsoft/azure-artifacts-packages @@ -228,9 +230,9 @@ Tasks/DuffleInstallerV0/ @rvairavelu @manolerazvan Tasks/ExtractFilesV1/ @microsoft/akvelon-build-task-team -Tasks/FileTransformV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/FileTransformV1/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/FileTransformV2/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/FileTransformV2/ @rvairavelu @microsoft/pipeline-environment-team Tasks/FtpUploadV1/ @microsoft/akvelon-build-task-team @@ -262,11 +264,11 @@ Tasks/HelmInstallerV0/ @rvairavelu @manolerazvan Tasks/HelmInstallerV1/ @rvairavelu @manolerazvan -Tasks/IISWebAppDeployment/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/IISWebAppDeployment/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/IISWebAppDeploymentOnMachineGroupV0/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/IISWebAppDeploymentOnMachineGroupV0/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/IISWebAppManagementOnMachineGroupV0/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/IISWebAppManagementOnMachineGroupV0/ @rvairavelu @microsoft/pipeline-environment-team Tasks/InstallAppleCertificateV2/ @microsoft/akvelon-build-task-team @@ -308,7 +310,7 @@ Tasks/MavenV4/ @microsoft/akvelon-build-task-team Tasks/MSBuildV1/ @microsoft/akvelon-build-task-team -Tasks/MysqlDeploymentOnMachineGroupV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/MysqlDeploymentOnMachineGroupV1/ @rvairavelu @microsoft/pipeline-environment-team Tasks/NodeTaskRunnerInstallerV0/ @microsoft/akvelon-build-task-team @@ -353,11 +355,11 @@ Tasks/PipAuthenticateV1/ @microsoft/azure-artifacts-packages Tasks/PowerShellV2/ @microsoft/akvelon-build-task-team -Tasks/PowerShellOnTargetMachinesV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/PowerShellOnTargetMachinesV1/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/PowerShellOnTargetMachinesV2/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/PowerShellOnTargetMachinesV2/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/PowerShellOnTargetMachinesV3/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/PowerShellOnTargetMachinesV3/ @rvairavelu @microsoft/pipeline-environment-team Tasks/PublishBuildArtifactsV1/ @microsoft/akvelon-build-task-team @@ -407,11 +409,11 @@ Tasks/ServiceFabricUpdateManifestsV2/ @rvairavelu @manolerazvan Tasks/ShellScriptV2/ @microsoft/akvelon-build-task-team -Tasks/SqlAzureDacpacDeploymentV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/SqlAzureDacpacDeploymentV1/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team -Tasks/SqlDacpacDeploymentOnMachineGroupV0/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/SqlDacpacDeploymentOnMachineGroupV0/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/SqlServerDacpacDeployment/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/SqlServerDacpacDeployment/ @vsebesta @rvairavelu @microsoft/pipeline-environment-team Tasks/SshV0/ @microsoft/akvelon-build-task-team @@ -439,9 +441,9 @@ Tasks/VsTestV3/ @rasunkar @microsoft\adoautotest Tasks/VsTestPlatformToolInstallerV1/ @rasunkar @microsoft\adoautotest -Tasks/WindowsMachineFileCopyV1/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/WindowsMachineFileCopyV1/ @rvairavelu @microsoft/pipeline-environment-team -Tasks/WindowsMachineFileCopyV2/ @vsebesta @rvairavelu @pipeline-environment-team +Tasks/WindowsMachineFileCopyV2/ @rvairavelu @microsoft/pipeline-environment-team Tasks/XamarinAndroidV1/ @microsoft/akvelon-build-task-team diff --git a/.github/workflows/autoAssignABTT.yml b/.github/workflows/autoAssignABTT.yml index 96c00a080514..e82e103baa44 100644 --- a/.github/workflows/autoAssignABTT.yml +++ b/.github/workflows/autoAssignABTT.yml @@ -9,6 +9,8 @@ on: jobs: assign_one_project: runs-on: ubuntu-latest + permissions: + issues: write name: Assign to ABTT Project steps: - name: "Assign issues with 'Area: ABTT' label to project board" diff --git a/.github/workflows/autoAssignRM.yml b/.github/workflows/autoAssignRM.yml index 160871c25c29..8fd292a8df3d 100644 --- a/.github/workflows/autoAssignRM.yml +++ b/.github/workflows/autoAssignRM.yml @@ -9,6 +9,8 @@ on: jobs: assign_one_project: runs-on: ubuntu-latest + permissions: + issues: write name: Assign to RM Project steps: - name: "Assign issues with 'Area: RM' label to project board" diff --git a/.github/workflows/blank.yml b/.github/workflows/blank.yml index 74c85416fec4..97552501d733 100644 --- a/.github/workflows/blank.yml +++ b/.github/workflows/blank.yml @@ -7,7 +7,8 @@ jobs: label: runs-on: ubuntu-latest - + permissions: + issues: write steps: - uses: actions/checkout@v1 - uses: damccorm/tag-ur-it@master diff --git a/.github/workflows/localization-automerge.yml b/.github/workflows/localization-automerge.yml index eca1b651c74a..d24ab21d2742 100644 --- a/.github/workflows/localization-automerge.yml +++ b/.github/workflows/localization-automerge.yml @@ -10,7 +10,8 @@ on: jobs: worker: runs-on: ubuntu-latest - + permissions: + issues: write if: github.actor == 'csigs' steps: - uses: actions/github-script@v3 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 643ab68bbc91..eb0659644c18 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -7,6 +7,8 @@ on: jobs: stale: runs-on: ubuntu-latest + permissions: + issues: write steps: - uses: actions/stale@v3 with: diff --git a/Tasks/AppCenterDistributeV1/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AppCenterDistributeV1/Strings/resources.resjson/en-US/resources.resjson index b06ecc2d0491..c946550ca471 100644 --- a/Tasks/AppCenterDistributeV1/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AppCenterDistributeV1/Strings/resources.resjson/en-US/resources.resjson @@ -38,5 +38,6 @@ "loc.messages.CannotFindAnyFile": "Cannot find any file based on %s.", "loc.messages.FoundMultipleFiles": "Found multiple files matching %s.", "loc.messages.FailedToCreateFile": "Failed to create %s with error: %s.", - "loc.messages.FailedToFindFile": "Failed to find %s at %s." + "loc.messages.FailedToFindFile": "Failed to find %s at %s.", + "loc.messages.DeprecatedTask": "The AppCenterDistribute@1 (App Center distribute) task has been deprecated since November 14, 2022 and will soon be retired. Use the AppCenterDistribute@3 task instead." } \ No newline at end of file diff --git a/Tasks/AppCenterDistributeV1/appcenterdistribute.ts b/Tasks/AppCenterDistributeV1/appcenterdistribute.ts index d587a73552f2..6742d8e9a352 100644 --- a/Tasks/AppCenterDistributeV1/appcenterdistribute.ts +++ b/Tasks/AppCenterDistributeV1/appcenterdistribute.ts @@ -558,6 +558,12 @@ async function run() { await commitSymbols(effectiveApiServer, effectiveApiVersion, appSlug, symbolsUploadInfo.symbol_upload_id, apiToken, userAgent); } + let shouldFail = tl.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + + if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(tl.loc("DeprecatedTask")); + } + tl.setResult(tl.TaskResult.Succeeded, tl.loc("Succeeded")); } catch (err) { tl.setResult(tl.TaskResult.Failed, `${err}`); diff --git a/Tasks/AppCenterDistributeV1/task.json b/Tasks/AppCenterDistributeV1/task.json index 61d771498883..79f0701d7155 100644 --- a/Tasks/AppCenterDistributeV1/task.json +++ b/Tasks/AppCenterDistributeV1/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "minimumAgentVersion": "2.144.0", @@ -201,6 +201,7 @@ "CannotFindAnyFile": "Cannot find any file based on %s.", "FoundMultipleFiles": "Found multiple files matching %s.", "FailedToCreateFile": "Failed to create %s with error: %s.", - "FailedToFindFile": "Failed to find %s at %s." + "FailedToFindFile": "Failed to find %s at %s.", + "DeprecatedTask": "The AppCenterDistribute@1 (App Center distribute) task has been deprecated since November 14, 2022 and will soon be retired. Use the AppCenterDistribute@3 task instead." } } \ No newline at end of file diff --git a/Tasks/AppCenterDistributeV1/task.loc.json b/Tasks/AppCenterDistributeV1/task.loc.json index 28213344c602..3ad7a018bd43 100644 --- a/Tasks/AppCenterDistributeV1/task.loc.json +++ b/Tasks/AppCenterDistributeV1/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "minimumAgentVersion": "2.144.0", @@ -201,6 +201,7 @@ "CannotFindAnyFile": "ms-resource:loc.messages.CannotFindAnyFile", "FoundMultipleFiles": "ms-resource:loc.messages.FoundMultipleFiles", "FailedToCreateFile": "ms-resource:loc.messages.FailedToCreateFile", - "FailedToFindFile": "ms-resource:loc.messages.FailedToFindFile" + "FailedToFindFile": "ms-resource:loc.messages.FailedToFindFile", + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" } } \ No newline at end of file diff --git a/Tasks/AppCenterDistributeV2/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AppCenterDistributeV2/Strings/resources.resjson/en-US/resources.resjson index 9c3ec1f83437..0d154f652428 100644 --- a/Tasks/AppCenterDistributeV2/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/AppCenterDistributeV2/Strings/resources.resjson/en-US/resources.resjson @@ -39,5 +39,6 @@ "loc.messages.CannotFindAnyFile": "Cannot find any file based on %s.", "loc.messages.FoundMultipleFiles": "Found multiple files matching %s.", "loc.messages.FailedToCreateFile": "Failed to create %s with error: %s.", - "loc.messages.FailedToFindFile": "Failed to find %s at %s." + "loc.messages.FailedToFindFile": "Failed to find %s at %s.", + "loc.messages.DeprecatedTask": "The AppCenterDistribute@2 (App Center distribute) task has been deprecated since November 14, 2022 and will soon be retired. Use the AppCenterDistribute@3 task instead." } \ No newline at end of file diff --git a/Tasks/AppCenterDistributeV2/appcenterdistribute.ts b/Tasks/AppCenterDistributeV2/appcenterdistribute.ts index 66415fd7328d..1857f439e3df 100644 --- a/Tasks/AppCenterDistributeV2/appcenterdistribute.ts +++ b/Tasks/AppCenterDistributeV2/appcenterdistribute.ts @@ -547,6 +547,12 @@ async function run() { await commitSymbols(effectiveApiServer, effectiveApiVersion, appSlug, symbolsUploadInfo.symbol_upload_id, apiToken, userAgent); } + let shouldFail = tl.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + + if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(tl.loc("DeprecatedTask")); + } + tl.setResult(tl.TaskResult.Succeeded, tl.loc("Succeeded")); } catch (err) { tl.setResult(tl.TaskResult.Failed, `${err}`); diff --git a/Tasks/AppCenterDistributeV2/task.json b/Tasks/AppCenterDistributeV2/task.json index 7ac99376ee57..96d662b08ddb 100644 --- a/Tasks/AppCenterDistributeV2/task.json +++ b/Tasks/AppCenterDistributeV2/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "minimumAgentVersion": "2.144.0", @@ -203,6 +203,7 @@ "CannotFindAnyFile": "Cannot find any file based on %s.", "FoundMultipleFiles": "Found multiple files matching %s.", "FailedToCreateFile": "Failed to create %s with error: %s.", - "FailedToFindFile": "Failed to find %s at %s." + "FailedToFindFile": "Failed to find %s at %s.", + "DeprecatedTask": "The AppCenterDistribute@2 (App Center distribute) task has been deprecated since November 14, 2022 and will soon be retired. Use the AppCenterDistribute@3 task instead." } } diff --git a/Tasks/AppCenterDistributeV2/task.loc.json b/Tasks/AppCenterDistributeV2/task.loc.json index fb0fbc936cd6..acf7b5407c68 100644 --- a/Tasks/AppCenterDistributeV2/task.loc.json +++ b/Tasks/AppCenterDistributeV2/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "minimumAgentVersion": "2.144.0", @@ -203,6 +203,7 @@ "CannotFindAnyFile": "ms-resource:loc.messages.CannotFindAnyFile", "FoundMultipleFiles": "ms-resource:loc.messages.FoundMultipleFiles", "FailedToCreateFile": "ms-resource:loc.messages.FailedToCreateFile", - "FailedToFindFile": "ms-resource:loc.messages.FailedToFindFile" + "FailedToFindFile": "ms-resource:loc.messages.FailedToFindFile", + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" } } \ No newline at end of file diff --git a/Tasks/AzureCloudPowerShellDeploymentV1/Utility.ps1 b/Tasks/AzureCloudPowerShellDeploymentV1/Utility.ps1 index de6800dd4d51..38a3c793b961 100644 --- a/Tasks/AzureCloudPowerShellDeploymentV1/Utility.ps1 +++ b/Tasks/AzureCloudPowerShellDeploymentV1/Utility.ps1 @@ -1,4 +1,8 @@ -function Get-SingleFile($files, $pattern) +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + +function Get-SingleFile($files, $pattern) { if ($files -is [system.array]) { @@ -57,12 +61,29 @@ function Get-AzureStoragePrimaryKey($storageAccount, [bool]$isArm) { if ($isArm) { - $storageAccountResource = Get-AzureRmResource | where-object { $_.Name -eq $storageAccount -and $_.ResourceType -eq "Microsoft.Storage/storageAccounts" } + if ($featureFlags.retireAzureRM) + { + $storageAccountResource = Get-AzResource | where-object { $_.Name -eq $storageAccount -and $_.ResourceType -eq "Microsoft.Storage/storageAccounts" } + } + else + { + $storageAccountResource = Get-AzureRmResource | where-object { $_.Name -eq $storageAccount -and $_.ResourceType -eq "Microsoft.Storage/storageAccounts" } + } + if (!$storageAccountResource) { Write-Error -Message "Could not find resource $storageAccount that has a type of Microsoft.Storage/storageAccounts" } - $storageAccountKeys = Get-AzureRmStorageAccountKey -ResourceGroupName $storageAccountResource.ResourceGroupName -Name $storageAccount + + if ($featureFlags.retireAzureRM) + { + $storageAccountKeys = Get-AzStorageAccountKey -ResourceGroupName $storageAccountResource.ResourceGroupName -Name $storageAccount + } + else + { + $storageAccountKeys = Get-AzureRmStorageAccountKey -ResourceGroupName $storageAccountResource.ResourceGroupName -Name $storageAccount + } + if(!$storageAccountKeys) { Write-Error -Message "Could not retrieve storage account keys from storage account resource $Storage" @@ -185,7 +206,14 @@ function Get-DiagnosticsExtensions($storageAccount, $extensionsPath, $storageAcc { try { - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey + } Write-Host "New-AzureServiceDiagnosticsExtensionConfig -Role $role -StorageContext $StorageContext -DiagnosticsConfigurationPath $fullExtPath" $wadconfig = New-AzureServiceDiagnosticsExtensionConfig -Role $role -StorageContext $StorageContext -DiagnosticsConfigurationPath $fullExtPath } diff --git a/Tasks/AzureCloudPowerShellDeploymentV1/task.json b/Tasks/AzureCloudPowerShellDeploymentV1/task.json index 08ccbe6f0722..a143fd615400 100644 --- a/Tasks/AzureCloudPowerShellDeploymentV1/task.json +++ b/Tasks/AzureCloudPowerShellDeploymentV1/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 226, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/AzureCloudPowerShellDeploymentV1/task.loc.json b/Tasks/AzureCloudPowerShellDeploymentV1/task.loc.json index 164b59b88705..ab56978980a6 100644 --- a/Tasks/AzureCloudPowerShellDeploymentV1/task.loc.json +++ b/Tasks/AzureCloudPowerShellDeploymentV1/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 226, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/AzureCloudPowerShellDeploymentV2/task.json b/Tasks/AzureCloudPowerShellDeploymentV2/task.json index 665ffc5f3624..84fb5706b5f4 100644 --- a/Tasks/AzureCloudPowerShellDeploymentV2/task.json +++ b/Tasks/AzureCloudPowerShellDeploymentV2/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 226, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/AzureCloudPowerShellDeploymentV2/task.loc.json b/Tasks/AzureCloudPowerShellDeploymentV2/task.loc.json index 44dd596fafab..3b824cd662e4 100644 --- a/Tasks/AzureCloudPowerShellDeploymentV2/task.loc.json +++ b/Tasks/AzureCloudPowerShellDeploymentV2/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 226, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/AzureFileCopyV1/AzureFileCopy.ps1 b/Tasks/AzureFileCopyV1/AzureFileCopy.ps1 index a8aef3f5d0fd..0dc104988072 100644 --- a/Tasks/AzureFileCopyV1/AzureFileCopy.ps1 +++ b/Tasks/AzureFileCopyV1/AzureFileCopy.ps1 @@ -3,6 +3,10 @@ param() Trace-VstsEnteringInvocation $MyInvocation +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + # Get inputs for the task $connectedServiceNameSelector = Get-VstsInput -Name ConnectedServiceNameSelector -Require $sourcePath = Get-VstsInput -Name SourcePath -Require @@ -168,7 +172,15 @@ try { } if(-not [string]::IsNullOrEmpty($outputStorageContainerSASToken)) { - $storageContainerSaSToken = New-AzureStorageContainerSASToken -Container $containerName -Context $storageContext -Permission r -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + if ($featureFlags.retireAzureRM) + { + $storageContainerSaSToken = New-AzStorageContainerSASToken -Name $containerName -Context $storageContext -Permission r -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + } + else + { + $storageContainerSaSToken = New-AzureStorageContainerSASToken -Container $containerName -Context $storageContext -Permission r -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + } + Write-Host "##vso[task.setvariable variable=$outputStorageContainerSASToken;]$storageContainerSasToken" } @@ -221,4 +233,4 @@ try { } finally { Disconnect-AzureAndClearContext -authScheme $connectionType -ErrorAction SilentlyContinue -} \ No newline at end of file +} diff --git a/Tasks/AzureFileCopyV1/AzureUtilityGTE1.0.ps1 b/Tasks/AzureFileCopyV1/AzureUtilityGTE1.0.ps1 index e161e00a6373..66ad08cd5171 100644 --- a/Tasks/AzureFileCopyV1/AzureUtilityGTE1.0.ps1 +++ b/Tasks/AzureFileCopyV1/AzureUtilityGTE1.0.ps1 @@ -1,5 +1,9 @@ # This file implements IAzureUtility for Azure PowerShell version >= 1.0.0 +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageKeyFromRDFE { param([string]$storageAccountName, @@ -26,11 +30,26 @@ function Get-AzureStorageAccountResourceGroupName Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" if (CmdletHasMember -cmdlet "Get-AzureRMResource" -memberName "Name") { - $azureStorageAccountResourceDetails = (Get-AzureRMResource -ErrorAction Stop) | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = (Get-AzResource -ErrorAction Stop) | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } + else + { + $azureStorageAccountResourceDetails = (Get-AzureRMResource -ErrorAction Stop) | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } + } else { - $azureStorageAccountResourceDetails = (Get-AzureRMResource -ErrorAction Stop) | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.ResourceName -eq $storageAccountName)} + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = (Get-AzResource -ErrorAction Stop) | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.ResourceName -eq $storageAccountName)} + } + else + { + $azureStorageAccountResourceDetails = (Get-AzureRMResource -ErrorAction Stop) | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.ResourceName -eq $storageAccountName)} + } } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" @@ -58,7 +77,14 @@ function Get-AzureStorageKeyFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage key for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageKeyDetails = Get-AzureRMStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageKeyDetails = Get-AzStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageKeyDetails = Get-AzureRMStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageKey = $storageKeyDetails.Key1 Write-Verbose "[Azure Call]Retrieved storage key successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -74,7 +100,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -110,7 +143,14 @@ function Get-AzureBlobStorageEndpointFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account endpoint for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageAccountInfo = Get-AzStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageAccountEnpoint = $storageAccountInfo.PrimaryEndpoints[0].blob Write-Verbose "[Azure Call]Retrieved storage account endpoint successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -147,7 +187,14 @@ function Get-AzureStorageAccountTypeFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account type for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageAccountInfo = Get-AzStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageAccountType = $storageAccountInfo.AccountType Write-Verbose "[Azure Call]Retrieved storage account type successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -168,9 +215,23 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -186,7 +247,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -273,7 +341,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -356,17 +431,39 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -375,15 +472,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -409,7 +527,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInHours hours" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -424,7 +549,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -443,7 +575,14 @@ function Get-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $customScriptExtension = Get-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + } + else + { + $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -463,7 +602,14 @@ function Set-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -482,7 +628,14 @@ function Remove-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + if ($featureFlags.retireAzureRM) + { + $response = Remove-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + } + else + { + $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -499,7 +652,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -521,7 +681,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -559,7 +726,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -576,11 +750,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -591,7 +779,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -620,7 +815,14 @@ function Remove-NetworkSecurityRuleConfig foreach($securityGroup in $securityGroups) { Write-Verbose "[Azure Call]Removing the Rule $ruleName" - $result = Remove-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzureRmNetworkSecurityGroup + if ($featureFlags.retireAzureRM) + { + $result = Remove-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzNetworkSecurityGroup + } + else + { + $result = Remove-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzureRmNetworkSecurityGroup + } Write-Verbose "[Azure Call]Removed the Rule $ruleName" } } diff --git a/Tasks/AzureFileCopyV1/AzureUtilityGTE1.1.0.ps1 b/Tasks/AzureFileCopyV1/AzureUtilityGTE1.1.0.ps1 index acf2f971551e..a4d4ece4473f 100644 --- a/Tasks/AzureFileCopyV1/AzureUtilityGTE1.1.0.ps1 +++ b/Tasks/AzureFileCopyV1/AzureUtilityGTE1.1.0.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityGTE1.0.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureRMVMsInResourceGroup { param([string]$resourceGroupName) @@ -11,7 +15,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -41,7 +52,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -55,3 +73,4 @@ function Set-AzureMachineCustomScriptExtension return $result } + diff --git a/Tasks/AzureFileCopyV1/AzureUtilityLTE9.8.ps1 b/Tasks/AzureFileCopyV1/AzureUtilityLTE9.8.ps1 index a8ba50244ae5..6d44eb076d6b 100644 --- a/Tasks/AzureFileCopyV1/AzureUtilityLTE9.8.ps1 +++ b/Tasks/AzureFileCopyV1/AzureUtilityLTE9.8.ps1 @@ -1,5 +1,9 @@ # This file implements IAzureUtility for Azure PowerShell version <= 0.9.8 +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageKeyFromRDFE { param([string]$storageAccountName, @@ -78,7 +82,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -180,11 +191,25 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -200,7 +225,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -376,7 +408,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInHours hours" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -598,3 +637,4 @@ function Remove-NetworkSecurityRuleConfig Write-Verbose "[Azure Call]Removed the Rule $ruleName" } } + diff --git a/Tasks/AzureFileCopyV1/task.json b/Tasks/AzureFileCopyV1/task.json index 81b2cc315bc1..10265e188e55 100644 --- a/Tasks/AzureFileCopyV1/task.json +++ b/Tasks/AzureFileCopyV1/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 231, - "Patch": 1 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzureFileCopyV1/task.loc.json b/Tasks/AzureFileCopyV1/task.loc.json index 16f1427f1fb2..95cd57487120 100644 --- a/Tasks/AzureFileCopyV1/task.loc.json +++ b/Tasks/AzureFileCopyV1/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 231, - "Patch": 1 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzureFileCopyV2/AzureFileCopy.ps1 b/Tasks/AzureFileCopyV2/AzureFileCopy.ps1 index 6b64ce4a6c72..b69f23805337 100644 --- a/Tasks/AzureFileCopyV2/AzureFileCopy.ps1 +++ b/Tasks/AzureFileCopyV2/AzureFileCopy.ps1 @@ -3,6 +3,10 @@ param() Trace-VstsEnteringInvocation $MyInvocation +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + # Get inputs for the task $connectedServiceNameSelector = Get-VstsInput -Name ConnectedServiceNameSelector -Require $sourcePath = Get-VstsInput -Name SourcePath -Require @@ -211,7 +215,14 @@ try { } if(-not [string]::IsNullOrEmpty($outputStorageContainerSASToken)) { - $storageContainerSaSToken = New-AzureStorageContainerSASToken -Container $containerName -Context $storageContext -Permission rl -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + if ($featureFlags.retireAzureRM) + { + $storageContainerSaSToken = New-AzStorageContainerSASToken -Name $containerName -Context $storageContext -Permission rl -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + } + else + { + $storageContainerSaSToken = New-AzureStorageContainerSASToken -Container $containerName -Context $storageContext -Permission rl -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + } Write-Host "##vso[task.setvariable variable=$outputStorageContainerSASToken;]$storageContainerSasToken" } @@ -280,4 +291,4 @@ try { } finally { Disconnect-AzureAndClearContext -authScheme $connectionType -ErrorAction SilentlyContinue -} \ No newline at end of file +} diff --git a/Tasks/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 b/Tasks/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 index 3b9642fcf36c..67408989a140 100644 --- a/Tasks/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 +++ b/Tasks/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 @@ -1,5 +1,9 @@ # This file implements IAzureUtility for Azure PowerShell version >= 1.0.0 +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageKeyFromRDFE { param([string]$storageAccountName, @@ -24,7 +28,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -50,7 +61,14 @@ function Get-AzureStorageKeyFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage key for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageKeyDetails = Get-AzureRMStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageKeyDetails = Get-AzStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageKeyDetails = Get-AzureRMStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageKey = $storageKeyDetails.Key1 Write-Verbose "[Azure Call]Retrieved storage key successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -66,7 +84,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -102,7 +127,14 @@ function Get-AzureBlobStorageEndpointFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account endpoint for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageAccountInfo = Get-AzStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageAccountEnpoint = $storageAccountInfo.PrimaryEndpoints[0].blob Write-Verbose "[Azure Call]Retrieved storage account endpoint successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -139,7 +171,14 @@ function Get-AzureStorageAccountTypeFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account type for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageAccountInfo = Get-AzStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageAccountType = $storageAccountInfo.AccountType Write-Verbose "[Azure Call]Retrieved storage account type successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -160,9 +199,23 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -178,7 +231,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -265,7 +325,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -348,17 +415,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -367,15 +455,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -401,7 +510,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInHours hours" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -416,7 +532,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -435,7 +558,14 @@ function Get-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $customScriptExtension = Get-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + } + else + { + $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -455,7 +585,14 @@ function Set-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -474,7 +611,14 @@ function Remove-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + if ($featureFlags.retireAzureRM) + { + $response = Remove-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + } + else + { + $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -491,7 +635,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -513,7 +664,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -551,7 +709,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -568,11 +733,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -583,7 +762,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -612,7 +798,15 @@ function Remove-NetworkSecurityRuleConfig foreach($securityGroup in $securityGroups) { Write-Verbose "[Azure Call]Removing the Rule $ruleName" - $result = Remove-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzureRmNetworkSecurityGroup + if ($featureFlags.retireAzureRM) + { + $result = Remove-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzNetworkSecurityGroup + } + else + { + $result = Remove-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzureRmNetworkSecurityGroup + } Write-Verbose "[Azure Call]Removed the Rule $ruleName" } } + diff --git a/Tasks/AzureFileCopyV2/AzureUtilityGTE1.1.0.ps1 b/Tasks/AzureFileCopyV2/AzureUtilityGTE1.1.0.ps1 index acf2f971551e..b00250086d92 100644 --- a/Tasks/AzureFileCopyV2/AzureUtilityGTE1.1.0.ps1 +++ b/Tasks/AzureFileCopyV2/AzureUtilityGTE1.1.0.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityGTE1.0.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureRMVMsInResourceGroup { param([string]$resourceGroupName) @@ -11,7 +15,13 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -41,7 +51,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -55,3 +72,4 @@ function Set-AzureMachineCustomScriptExtension return $result } + diff --git a/Tasks/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 b/Tasks/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 index dcdd33a0c368..a8f7f9e869a7 100644 --- a/Tasks/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 +++ b/Tasks/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 @@ -1,5 +1,9 @@ # This file implements IAzureUtility for Azure PowerShell version <= 0.9.8 +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageKeyFromRDFE { param([string]$storageAccountName, @@ -80,7 +84,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -182,11 +193,25 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -202,7 +227,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -378,7 +410,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInHours hours" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -600,3 +639,4 @@ function Remove-NetworkSecurityRuleConfig Write-Verbose "[Azure Call]Removed the Rule $ruleName" } } + diff --git a/Tasks/AzureFileCopyV2/task.json b/Tasks/AzureFileCopyV2/task.json index 7b53f6fa3d3f..40c9ec9050b9 100644 --- a/Tasks/AzureFileCopyV2/task.json +++ b/Tasks/AzureFileCopyV2/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzureFileCopyV2/task.loc.json b/Tasks/AzureFileCopyV2/task.loc.json index c70207ecb3bd..915b442cf554 100644 --- a/Tasks/AzureFileCopyV2/task.loc.json +++ b/Tasks/AzureFileCopyV2/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzureFileCopyV3/AzureUtilityARM.ps1 b/Tasks/AzureFileCopyV3/AzureUtilityARM.ps1 index 9ed07921a74d..f89fefb0776d 100644 --- a/Tasks/AzureFileCopyV3/AzureUtilityARM.ps1 +++ b/Tasks/AzureFileCopyV3/AzureUtilityARM.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityRest.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageAccountResourceGroupName { param([string]$storageAccountName) @@ -10,7 +14,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -33,7 +44,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -53,9 +71,25 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop - } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + } + else + { + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -71,7 +105,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -85,7 +126,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -112,17 +160,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -131,15 +200,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -165,7 +255,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInMinutes minutes" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -180,7 +277,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -201,7 +305,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -224,7 +335,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -246,7 +364,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -284,7 +409,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -301,11 +433,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -316,7 +462,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -335,3 +488,4 @@ function Add-NetworkSecurityRuleConfig } } } + diff --git a/Tasks/AzureFileCopyV3/task.json b/Tasks/AzureFileCopyV3/task.json index a52d78534923..29b5ffea6340 100644 --- a/Tasks/AzureFileCopyV3/task.json +++ b/Tasks/AzureFileCopyV3/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzureFileCopyV3/task.loc.json b/Tasks/AzureFileCopyV3/task.loc.json index dcd2330c9965..a6f97d416aca 100644 --- a/Tasks/AzureFileCopyV3/task.loc.json +++ b/Tasks/AzureFileCopyV3/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzureFileCopyV4/AzureUtilityARM.ps1 b/Tasks/AzureFileCopyV4/AzureUtilityARM.ps1 index e31f5c2bfd6d..4313603a7bbf 100644 --- a/Tasks/AzureFileCopyV4/AzureUtilityARM.ps1 +++ b/Tasks/AzureFileCopyV4/AzureUtilityARM.ps1 @@ -10,7 +10,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -33,7 +40,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -50,7 +64,14 @@ function Create-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } } @@ -69,7 +90,14 @@ function Get-AzureContainer Write-Verbose "[Azure Call]Getting container: $containerName in storage account: $storageAccountName" try { - $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = Get-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } catch { @@ -90,7 +118,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -104,7 +139,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -131,17 +173,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -150,15 +213,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -184,7 +268,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInMinutes minutes" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -199,7 +290,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -220,7 +318,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -243,7 +348,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -265,7 +377,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -303,7 +422,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -320,11 +446,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -335,7 +475,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -354,3 +501,4 @@ function Add-NetworkSecurityRuleConfig } } } + diff --git a/Tasks/AzureFileCopyV4/task.json b/Tasks/AzureFileCopyV4/task.json index a19ea319a245..9c73db35de9e 100644 --- a/Tasks/AzureFileCopyV4/task.json +++ b/Tasks/AzureFileCopyV4/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzureFileCopyV4/task.loc.json b/Tasks/AzureFileCopyV4/task.loc.json index e9c72e811a3c..e4a424f032ae 100644 --- a/Tasks/AzureFileCopyV4/task.loc.json +++ b/Tasks/AzureFileCopyV4/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzureFileCopyV5/AzureUtilityARM.ps1 b/Tasks/AzureFileCopyV5/AzureUtilityARM.ps1 index e31f5c2bfd6d..bc0b524ddd79 100644 --- a/Tasks/AzureFileCopyV5/AzureUtilityARM.ps1 +++ b/Tasks/AzureFileCopyV5/AzureUtilityARM.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityRest.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageAccountResourceGroupName { param([string]$storageAccountName) @@ -10,7 +14,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -33,7 +44,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -50,7 +68,14 @@ function Create-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } } @@ -69,7 +94,14 @@ function Get-AzureContainer Write-Verbose "[Azure Call]Getting container: $containerName in storage account: $storageAccountName" try { - $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = Get-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } catch { @@ -90,7 +122,15 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -104,7 +144,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -131,17 +178,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -150,15 +218,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -184,7 +273,15 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInMinutes minutes" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -199,7 +296,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -220,7 +324,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -243,7 +354,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -265,7 +383,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -303,7 +428,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -320,11 +452,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -335,7 +481,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -354,3 +507,4 @@ function Add-NetworkSecurityRuleConfig } } } + diff --git a/Tasks/AzureFileCopyV5/task.json b/Tasks/AzureFileCopyV5/task.json index 06794562cc86..cd47b6404b1f 100644 --- a/Tasks/AzureFileCopyV5/task.json +++ b/Tasks/AzureFileCopyV5/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzureFileCopyV5/task.loc.json b/Tasks/AzureFileCopyV5/task.loc.json index d7816a031b08..2309f0aff8be 100644 --- a/Tasks/AzureFileCopyV5/task.loc.json +++ b/Tasks/AzureFileCopyV5/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" diff --git a/Tasks/AzurePowerShellV2/task.json b/Tasks/AzurePowerShellV2/task.json index d0901e6044bd..889001ec42e4 100644 --- a/Tasks/AzurePowerShellV2/task.json +++ b/Tasks/AzurePowerShellV2/task.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 230, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/AzurePowerShellV2/task.loc.json b/Tasks/AzurePowerShellV2/task.loc.json index 908450ded4a6..ebd5d3cdd397 100644 --- a/Tasks/AzurePowerShellV2/task.loc.json +++ b/Tasks/AzurePowerShellV2/task.loc.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 230, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/AzurePowerShellV3/task.json b/Tasks/AzurePowerShellV3/task.json index 49f434610548..b7bedfd12a43 100644 --- a/Tasks/AzurePowerShellV3/task.json +++ b/Tasks/AzurePowerShellV3/task.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 230, + "Minor": 234, "Patch": 0 }, "releaseNotes": "Added support for Fail on standard error and ErrorActionPreference", diff --git a/Tasks/AzurePowerShellV3/task.loc.json b/Tasks/AzurePowerShellV3/task.loc.json index 564890333d0a..137f2f1e1dd2 100644 --- a/Tasks/AzurePowerShellV3/task.loc.json +++ b/Tasks/AzurePowerShellV3/task.loc.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 230, + "Minor": 234, "Patch": 0 }, "releaseNotes": "ms-resource:loc.releaseNotes", diff --git a/Tasks/AzurePowerShellV4/task.json b/Tasks/AzurePowerShellV4/task.json index d969e0fc869f..054f5cf29402 100644 --- a/Tasks/AzurePowerShellV4/task.json +++ b/Tasks/AzurePowerShellV4/task.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, + "Minor": 234, "Patch": 0 }, "releaseNotes": "Added support for Az Module and cross platform agents.", diff --git a/Tasks/AzurePowerShellV4/task.loc.json b/Tasks/AzurePowerShellV4/task.loc.json index 2760af563388..85c401f1a388 100644 --- a/Tasks/AzurePowerShellV4/task.loc.json +++ b/Tasks/AzurePowerShellV4/task.loc.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, + "Minor": 234, "Patch": 0 }, "releaseNotes": "ms-resource:loc.releaseNotes", diff --git a/Tasks/AzurePowerShellV5/task.json b/Tasks/AzurePowerShellV5/task.json index 5ecd922d52b8..b455caf9c233 100644 --- a/Tasks/AzurePowerShellV5/task.json +++ b/Tasks/AzurePowerShellV5/task.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, + "Minor": 234, "Patch": 0 }, "releaseNotes": "Added support for Az Module and cross platform agents.", diff --git a/Tasks/AzurePowerShellV5/task.loc.json b/Tasks/AzurePowerShellV5/task.loc.json index 99e49202c27e..923af84c1915 100644 --- a/Tasks/AzurePowerShellV5/task.loc.json +++ b/Tasks/AzurePowerShellV5/task.loc.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, + "Minor": 234, "Patch": 0 }, "releaseNotes": "ms-resource:loc.releaseNotes", diff --git a/Tasks/AzureTestPlanV0/Invokers/gradleinvoker.ts b/Tasks/AzureTestPlanV0/Invokers/gradleinvoker.ts new file mode 100644 index 000000000000..02dcc2bea99a --- /dev/null +++ b/Tasks/AzureTestPlanV0/Invokers/gradleinvoker.ts @@ -0,0 +1,31 @@ +import { spawn } from '../testexecutor' +import tl = require('azure-pipelines-task-lib/task'); +import utils = require('../utils'); +import constants = require('../constants'); +export async function executegradletests(testsToBeExecuted: string[]) { + + //public doc link: https://docs.gradle.org/current/userguide/command_line_interface.html + //gradle command like "gradle test --tests= --tests=" + + const executable = constants.GRADLE_EXECUTABLE; + const args = [] + + args.push('test'); + + for (let testcase of testsToBeExecuted) { + + // in some cases found that gradle is including () in test name + utils.removeParenthesesFromEnd(testcase); + args.push('--tests=' + testcase); + } + + tl.debug("Executing gradle tests with executable : " + executable); + tl.debug("Executing gradle tests with args :" + args); + + const { status, error } = await spawn(executable, args) + if (error) { + tl.error("Error executing gradle command, " + error); + } + + return { exitCode: status ?? 1 } +} \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/Invokers/maveninvoker.ts b/Tasks/AzureTestPlanV0/Invokers/maveninvoker.ts new file mode 100644 index 000000000000..5dd8faa44c28 --- /dev/null +++ b/Tasks/AzureTestPlanV0/Invokers/maveninvoker.ts @@ -0,0 +1,39 @@ +import { spawn } from '../testexecutor' +import tl = require('azure-pipelines-task-lib/task'); +import utils = require('../utils'); +import constants = require('../constants'); + +export async function executemaventests(testsToBeExecuted: string[]) { + + //public doc link: https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html + //maven command like "mvn test -Dtest=," + + const executable = constants.MVN_EXECUTABLE; + const args = [] + const testsToRun =[] + + for (let tests of testsToBeExecuted) { + const modifiedTest = utils.replaceLastDotWithHash(tests); + testsToRun.push(modifiedTest); + } + + if (testsToRun.length > 0) + { + const testsList = testsToRun.join(',') + const dtest = constants.MAVEN_DTEST; + const combinedTestArgs = dtest + testsList; + + args.push('test'); + args.push(combinedTestArgs); + } + + tl.debug("Executing java maven tests with executable : " + executable); + tl.debug("Executing java maven tests with args :" + args); + + const { status, error } = await spawn(executable, args) + if (error) { + tl.error("Error executing mvn command, " + error); + } + + return { exitCode: status ?? 1 } + } \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/Invokers/pythonivoker.ts b/Tasks/AzureTestPlanV0/Invokers/pythonivoker.ts new file mode 100644 index 000000000000..9188f8822fe2 --- /dev/null +++ b/Tasks/AzureTestPlanV0/Invokers/pythonivoker.ts @@ -0,0 +1,29 @@ +import { spawn } from '../testexecutor' +import tl = require('azure-pipelines-task-lib/task'); +import constants = require('../constants'); + +export async function executepythontests(testsToBeExecuted: string[]) { + + //public doc link: https://docs.pytest.org/en/7.1.x/how-to/usage.html#specifying-which-tests-to-run + //pytest command like "pytest -v --junitxml=junit.xml" + + const executable = constants.PYTEST_EXECUTABLE; + let args: string[] = []; + + for (let testcase of testsToBeExecuted) { + args.push(testcase); + } + + args.push('--junitxml=junit.xml') + + tl.debug("Executing python tests with executable : " + executable); + tl.debug("Executing python tests with args :" + args); + + const { status, error } = await spawn(executable, args) + + if (error) { + tl.error("Error executing pytest command, " + error); + } + + return { exitCode: status ?? 1 } +} \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/Strings/resources.resjson/en-US/resources.resjson b/Tasks/AzureTestPlanV0/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..ab005739518c --- /dev/null +++ b/Tasks/AzureTestPlanV0/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,22 @@ +{ + "loc.friendlyName": "Azure Test Plan", + "loc.helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613742)", + "loc.description": "Run manual and automated tests in test plan in Java and python language", + "loc.instanceNameFormat": "Azure Test Plan - $(testSelector)", + "loc.input.label.testSelector": "Test cases to be executed", + "loc.input.help.testSelector": "
  • Manual tests: Use this option to trigger manual tests from your test plan.
  • Automated tests: Use this option to run tests from your test plan that have automated test method associated with it.
  • ", + "loc.input.label.testPlan": "Test plan", + "loc.input.help.testPlan": "Select a test plan containing test suites with test cases.", + "loc.input.label.testSuite": "Test suite", + "loc.input.help.testSuite": "Select one or more test suites containing test cases.", + "loc.input.label.testConfiguration": "Test configuration", + "loc.input.help.testConfiguration": "Select Test Configuration.", + "loc.input.label.testLanguageInput": "Select Test framework language", + "loc.input.help.testLanguageInput": "Test Framework Language of automated tests in test plan", + "loc.messages.testPlanInput": "Test plan Id : %s", + "loc.messages.testplanConfigInput": "Test plan configuration Id : %s", + "loc.messages.testSuiteSelected": "Test suite Id selected: %s", + "loc.messages.automatedTestsTriggered": "Trigerring execution of Automated tests from test plan", + "loc.messages.ErrorFailTaskOnExecutingTests": "Error occured while executing test command", + "loc.messages.ErrorFailTaskOnAPIFailure": "Error occured while fetching automated tests from test plan inputs" +} \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/_buildConfigs/Node20/package-lock.json b/Tasks/AzureTestPlanV0/_buildConfigs/Node20/package-lock.json new file mode 100644 index 000000000000..df8150002c7a --- /dev/null +++ b/Tasks/AzureTestPlanV0/_buildConfigs/Node20/package-lock.json @@ -0,0 +1,964 @@ +{ + "name": "azure-tasks-runTestPlan", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==" + }, + "@types/node": { + "version": "20.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/q": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.7.tgz", + "integrity": "sha512-HBPgtzp44867rkL+IzQ3560/E/BlobwCjeXsuKqogrcE99SKgZR4tvBBCuNJZMhUFMz26M7cjKWZg785lllwpA==" + }, + "@types/qs": { + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz", + "integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==" + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + }, + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + }, + "adm-zip": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==" + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, + "azure-pipelines-task-lib": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.6.1.tgz", + "integrity": "sha512-3/LFgNNHY0Cw9vArQPxM6ZgPWt3/G2Yy6F75k2AJzKUCotp5X9gZcvF399tVo6T6lTOlp3Vm7VBXq+kzZ6hZmw==", + "requires": { + "adm-zip": "^0.5.10", + "deasync": "^0.1.28", + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "nodejs-file-downloader": "^4.11.1", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "uuid": "^3.0.1" + } + }, + "azure-pipelines-tasks-docker-common": { + "version": "2.198.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-docker-common/-/azure-pipelines-tasks-docker-common-2.198.1.tgz", + "integrity": "sha512-lgN/sNVhxVxnIM1HoUy8BO8A7idw1ypICBmdPOJUdw21Oy+7cplWfTnygFLPvGSFCN3VnSJFbzBe8LewcWplow==", + "requires": { + "@types/mocha": "^5.2.7", + "@types/node": "^10.17.0", + "@types/q": "1.5.4", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^3.1.0", + "del": "2.2.0", + "q": "1.4.1" + }, + "dependencies": { + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" + }, + "azure-pipelines-task-lib": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.4.0.tgz", + "integrity": "sha512-3eC4OTFw+7xD7A2aUhxR/j+jRlTI+vVfS0CGxt1pCLs4c/KmY0tQWgbqjD3157kmiucWxELBvgZHaD2gCBe9fg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + } + } + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha512-/CdEdaw49VZVmyIDGUQKDDT53c7qBkO6g5CefWz91Ae+l4+cRtcDYwMTXh6me4O8TMldeGHG3N2Bl84V78Ywbg==" + } + } + }, + "azure-pipelines-tasks-utility-common": { + "version": "3.225.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-utility-common/-/azure-pipelines-tasks-utility-common-3.225.1.tgz", + "integrity": "sha512-4wtVKuvx2PcQI0W8xkMdS/S+tf9Qu7wMJl4HSTLE1gjQ2x9o/6QbhMogz6O1+8ofxvTqmI4scA7GHKccDAwQpQ==", + "requires": { + "@types/node": "^16.11.39", + "azure-pipelines-task-lib": "^4.4.0", + "azure-pipelines-tool-lib": "^2.0.0-preview", + "js-yaml": "3.13.1", + "semver": "^5.4.1" + }, + "dependencies": { + "@types/node": { + "version": "16.18.70", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.70.tgz", + "integrity": "sha512-8eIk20G5VVVQNZNouHjLA2b8utE2NvGybLjMaF4lyhA9uhGwnmXF8o+icdXKGSQSNANJewXva/sFUoZLwAaYAg==" + } + } + }, + "azure-pipelines-tool-lib": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/azure-pipelines-tool-lib/-/azure-pipelines-tool-lib-2.0.6.tgz", + "integrity": "sha512-972uj4vMieY2tHrVowjHDR5N8rvuJP7eIOzchjUz+eHTEtRCLWbQbfJpVxcbfsA+KZJOomqTxgZ3+icS642hqw==", + "requires": { + "@types/semver": "^5.3.0", + "@types/uuid": "^3.4.5", + "azure-pipelines-task-lib": "^4.1.0", + "semver": "^5.7.0", + "semver-compare": "^1.0.0", + "typed-rest-client": "^1.8.6", + "uuid": "^3.3.2" + }, + "dependencies": { + "@types/uuid": { + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.12.tgz", + "integrity": "sha512-4mZWvs9415R6KNlPUZaMDgpnNpFZrO7yZoFfVc6phuOpnUlU06KGu4+83e857jfWkYBMNVZF/1HDoG/aEbePow==" + } + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "requires": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "deasync": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.29.tgz", + "integrity": "sha512-EBtfUhVX23CE9GR6m+F8WPeImEE4hR/FW9RkK0PMl9V1t283s0elqsTD8EZjaKX28SY1BW2rYfCgNsAYdpamUw==", + "requires": { + "bindings": "^1.5.0", + "node-addon-api": "^1.7.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "del": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.0.tgz", + "integrity": "sha512-AZDiRb78EEGYCsAZTG3v+CM5q8J0BIs+wI7QeUtyosm+zIMm4XSmp6aI/K7cU9l+YaKpDKN9dYP1xTrNjLQ+LA==", + "requires": { + "globby": "^4.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "requires": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" + }, + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globby": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", + "integrity": "sha512-JPDtMSr0bt25W64q792rvlrSwIaZwqUAhqdYKSr57Wh/xBcQ5JDWLM85ndn+Q1WdBQXLb9YGCl0QN/T0HpqU0A==", + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^6.0.1", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "requires": { + "get-intrinsic": "^1.2.2" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + } + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "requires": { + "hasown": "^2.0.0" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha512-cnS56eR9SPAscL77ik76ATVqoPARTqPIVkMDVxRaWH06zT+6+CzIroYRJ0VVvm0Z1zfAvxvz9i/D3Ppjaqt5Nw==" + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==", + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mockery": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-2.1.0.tgz", + "integrity": "sha512-9VkOmxKlWXoDO/h1jDZaS4lH33aWfRiJiNT/tKj+8OGzrcFDLo8d0syGdbsc3Bc4GvRXPb+NMMvojotmuGJTvA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==" + }, + "nodejs-file-downloader": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/nodejs-file-downloader/-/nodejs-file-downloader-4.12.1.tgz", + "integrity": "sha512-LpfCTNhh805AlLnJnzt1PuEj+RmbrccbAQZ6hBRw2e6QPVR0Qntuo6qqyvPHG5s77/0w0IEKgRAD4nbSnr/X4w==", + "requires": { + "follow-redirects": "^1.15.1", + "https-proxy-agent": "^5.0.0", + "mime-types": "^2.1.27", + "sanitize-filename": "^1.6.3" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "requires": { + "pinkie": "^2.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "requires": { + "asap": "~2.0.6" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" + }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + } + } + }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "typed-rest-client": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "dev": true + }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + } + } +} diff --git a/Tasks/AzureTestPlanV0/_buildConfigs/Node20/package.json b/Tasks/AzureTestPlanV0/_buildConfigs/Node20/package.json new file mode 100644 index 000000000000..a62592d1e683 --- /dev/null +++ b/Tasks/AzureTestPlanV0/_buildConfigs/Node20/package.json @@ -0,0 +1,34 @@ +{ + "name": "azure-tasks-runTestPlan", + "version": "1.0.0", + "description": "Azure Pipelines Run Manual and Automated Test execution Task", + "main": "runTestPlan.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/azure-pipelines-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/azure-pipelines-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/azure-pipelines-tasks#readme", + "dependencies": { + "@types/node": "^20.3.1", + "@types/q": "^1.0.7", + "@types/mocha": "^9.1.1", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^4.1.0", + "azure-pipelines-tasks-docker-common": "2.198.1", + "azure-pipelines-tasks-utility-common": "^3.212.0", + "azure-pipelines-tool-lib": "^2.0.0-preview", + "typed-rest-client": "^1.8.9", + "axios": "^1.6.2" + }, + "devDependencies": { + "typescript": "5.1.6" + } +} diff --git a/Tasks/AzureTestPlanV0/automatedTestInvoker.ts b/Tasks/AzureTestPlanV0/automatedTestInvoker.ts new file mode 100644 index 000000000000..e4645c0ceb9f --- /dev/null +++ b/Tasks/AzureTestPlanV0/automatedTestInvoker.ts @@ -0,0 +1,36 @@ +import * as tl from 'azure-pipelines-task-lib/task' +import { executepythontests } from './Invokers/pythonivoker' +import { executemaventests } from './Invokers/maveninvoker' +import { executegradletests } from './Invokers/gradleinvoker' + +export async function testInvoker(testsToBeExecuted: string[]) { + + const testLanguageStrings = tl.getDelimitedInput('testLanguageInput', ',', true); + + for (const testLanguage of testLanguageStrings) { + + if (testLanguage === null || testLanguage === undefined) { + console.log("Please select the test framework language from the task dropdown list to execute automated tests"); + return; + } + + switch (testLanguage) { + case 'Java-Maven': + await executemaventests(testsToBeExecuted); + break; + + case 'Java-Gradle': + await executegradletests(testsToBeExecuted); + break; + + case 'Python': + await executepythontests(testsToBeExecuted); + break; + + default: + console.log('Invalid test Language Input selected.'); + } + + } + +} \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/automatedTests.ts b/Tasks/AzureTestPlanV0/automatedTests.ts new file mode 100644 index 000000000000..711e1fc3a57e --- /dev/null +++ b/Tasks/AzureTestPlanV0/automatedTests.ts @@ -0,0 +1,68 @@ +import tl = require('azure-pipelines-task-lib/task'); +import { testInvoker } from './automatedTestInvoker' +import { TestPlanData, getAutomatedTestData } from './getAutomatedTests'; +import { TestCase } from 'azure-devops-node-api/interfaces/TestPlanInterfaces'; + + +export async function automatedTestsFlow(testSelectorInput: string) { + + let listOfTestsToBeExecuted: string[] = []; + + console.log(tl.loc('automatedTestsTriggered')); + await getFQNsOfAutomatedTestCases() + .then((testsToBeExecuted) => { + listOfTestsToBeExecuted = testsToBeExecuted; + }) + .catch((error) => { + tl.error("Error while fetching FqnsOfAutomatedTestCases :" + error); + tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnAPIFailure')); + }); + + tl.debug("Invoking test execution for tests: " + listOfTestsToBeExecuted); + + if (listOfTestsToBeExecuted !== null && listOfTestsToBeExecuted !== undefined && listOfTestsToBeExecuted.length > 0) { + testInvoker(listOfTestsToBeExecuted); + } + else { + console.log("No automated tests found for given test plan inputs "); + if (testSelectorInput === 'automatedTests') { + tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnNoAutomatedTestsFound')); + } + else { + tl.setResult(tl.TaskResult.Succeeded, "Successfully triggered manual test execution"); + } + } + +} + +export async function getFQNsOfAutomatedTestCases(): Promise{ + + let testpointidslist: number[]; + let fqnlist: string[]; + + const testPlan = parseInt(tl.getInput('testPlan')); + const testPlanConfigId = parseInt(tl.getInput('testConfiguration')); + const testSuiteStrings = tl.getDelimitedInput('testSuite', ',', true); + const testSuites = new Array(); + testSuiteStrings.forEach(element => { + const testSuiteId = parseInt(element); + testSuites.push(testSuiteId); + }) + + console.log('Test Plan Id:' + testPlan); + console.log('Test Plan Configuration Id:' + testPlanConfigId); + console.log('Test Suite Ids:' + testSuites); + + await getAutomatedTestData(testPlan, testSuites, testPlanConfigId) + .then((testPlanData) => { + testpointidslist = testPlanData.testPointIds; + fqnlist = testPlanData.listOfFQNOfTestCases; + }) + .catch((error) => { + tl.error("Error while fetching Automated Test Cases Data :" + error); + tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnAPIFailure')); + }); + + return fqnlist; +} + diff --git a/Tasks/AzureTestPlanV0/constants.ts b/Tasks/AzureTestPlanV0/constants.ts new file mode 100644 index 000000000000..14970c3408da --- /dev/null +++ b/Tasks/AzureTestPlanV0/constants.ts @@ -0,0 +1,7 @@ +// Constants +export const MVN_EXECUTABLE: string = 'mvn'; +export const MAVEN_DTEST: string = '-Dtest='; +export const GRADLE_EXECUTABLE: string = 'gradle'; +export const PYTEST_EXECUTABLE: string = 'pytest'; +export const AUTOMATED_TEST_NAME = "Microsoft.VSTS.TCM.AutomatedTestName"; +export const AUTOMATED_TEST_STORAGE = "Microsoft.VSTS.TCM.AutomatedTestStorage"; diff --git a/Tasks/AzureTestPlanV0/getAutomatedTests.ts b/Tasks/AzureTestPlanV0/getAutomatedTests.ts new file mode 100644 index 000000000000..d7149d83032a --- /dev/null +++ b/Tasks/AzureTestPlanV0/getAutomatedTests.ts @@ -0,0 +1,105 @@ +import { Console } from "console"; +import tl = require('azure-pipelines-task-lib/task'); +import apim = require('azure-devops-node-api'); +import { WorkItemDetails, TestCase } from 'azure-devops-node-api/interfaces/TestPlanInterfaces'; +import { PagedList } from 'azure-devops-node-api/interfaces/common/VSSInterfaces'; +import TestPlanInterfaces = require('azure-devops-node-api/interfaces/TestPlanInterfaces'); +import VSSInterfaces = require('azure-devops-node-api/interfaces/common/VSSInterfaces'); +import constants = require('./constants'); + + +export interface TestPlanData { + testPointIds: number[]; + listOfFQNOfTestCases: string[]; +} +export async function getAutomatedTestData(testPlanId: number, testSuiteIds: number[], testConfigurationId: number): Promise { + + const testPlanData: TestPlanData = { testPointIds: [], listOfFQNOfTestCases: [] }; + let token = null; + const AutomatedTestName = constants.AUTOMATED_TEST_NAME; + const AutomatedTestStorage = constants.AUTOMATED_TEST_STORAGE; + + if (testPlanId == 0 || testConfigurationId == 0) { + return testPlanData; + } + + for (const testSuiteId of testSuiteIds) { + if (testSuiteId === 0) { + continue; + } + + let testCasesData: TestCase[] = []; + + do { + try { + let testCasesResponse = await fetchTestPlanList(testPlanId, testSuiteId, testConfigurationId.toString(), token); + + token = testCasesResponse.continuationToken; + + for (let key in testCasesResponse) { + if (testCasesResponse.hasOwnProperty(key)) { + testCasesData.push(testCasesResponse[key]); + } + } + + } catch (error) { + tl.error("Error fetching test cases list:" + error); + token = undefined; + } + } while ((token !== undefined) && (token !== null)); + + if (testCasesData.length === 0) { + console.log(`No test cases for test suite ${testSuiteId}`); + continue; + } + + testCasesData.forEach(testCase => { + let automatedTestName = ''; + let automatedTestStorage = ''; + + for (const witField of testCase.workItem?.workItemFields || []) { + const parsedWitField = JSON.parse(JSON.stringify(witField)); // Deep copy for safety + + if (parsedWitField[AutomatedTestName] !== undefined && parsedWitField[AutomatedTestName] !== null) { + automatedTestName = parsedWitField[AutomatedTestName].toString(); + testPlanData.listOfFQNOfTestCases.push(automatedTestName); + } + + if (parsedWitField[AutomatedTestStorage] !== undefined && parsedWitField[AutomatedTestStorage] !== null) { + automatedTestStorage = parsedWitField[AutomatedTestStorage].toString(); + } + } + + if (automatedTestName !== '' && automatedTestStorage !== '') { + if (testCase.pointAssignments.length > 0) { + testPlanData.testPointIds.push(testCase.pointAssignments[0].id); + } + } + }); + + } + + return testPlanData; +} + +export async function fetchTestPlanList(testPlanId: number, testSuiteId: number, testConfigurationId: string, continuationToken: string): Promise> { + + let url = tl.getEndpointUrl('SYSTEMVSSCONNECTION', false); + let token = tl.getEndpointAuthorizationParameter('SYSTEMVSSCONNECTION', 'ACCESSTOKEN', false); + let projectId = tl.getVariable('System.TeamProjectId'); + let auth = token.length == 52 ? apim.getPersonalAccessTokenHandler(token) : apim.getBearerHandler(token); + let vsts: apim.WebApi = new apim.WebApi(url, auth); + let testPlanApi = await vsts.getTestPlanApi(); + + tl.debug("Fetching test case list for test plan:" + testPlanId + " test suite id:" + testSuiteId + " test configuration id:" + testConfigurationId); + + return testPlanApi.getTestCaseList( + projectId, + testPlanId, + testSuiteId, + null, + testConfigurationId, + null, + continuationToken) + +} diff --git a/Tasks/AzureTestPlanV0/icon.png b/Tasks/AzureTestPlanV0/icon.png new file mode 100644 index 000000000000..686d0730e9fa Binary files /dev/null and b/Tasks/AzureTestPlanV0/icon.png differ diff --git a/Tasks/AzureTestPlanV0/icon.svg b/Tasks/AzureTestPlanV0/icon.svg new file mode 100644 index 000000000000..40206e1780c4 --- /dev/null +++ b/Tasks/AzureTestPlanV0/icon.svg @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/Tasks/AzureTestPlanV0/manualTests.ts b/Tasks/AzureTestPlanV0/manualTests.ts new file mode 100644 index 000000000000..e435be48fd58 --- /dev/null +++ b/Tasks/AzureTestPlanV0/manualTests.ts @@ -0,0 +1,6 @@ +import tl = require('azure-pipelines-task-lib/task'); + +export function manualTestsFlow() { + console.log("To do:"); + console.log("Manual trigger flow to be implemented"); +} \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/package-lock.json b/Tasks/AzureTestPlanV0/package-lock.json new file mode 100644 index 000000000000..fc956cfb6ebe --- /dev/null +++ b/Tasks/AzureTestPlanV0/package-lock.json @@ -0,0 +1,958 @@ +{ + "name": "azure-tasks-runTestPlan", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==" + }, + "@types/node": { + "version": "16.18.59", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.59.tgz", + "integrity": "sha512-PJ1w2cNeKUEdey4LiPra0ZuxZFOGvetswE8qHRriV/sUkL5Al4tTmPV9D2+Y/TPIxTHHgxTfRjZVKWhPw/ORhQ==" + }, + "@types/q": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.7.tgz", + "integrity": "sha512-HBPgtzp44867rkL+IzQ3560/E/BlobwCjeXsuKqogrcE99SKgZR4tvBBCuNJZMhUFMz26M7cjKWZg785lllwpA==" + }, + "@types/qs": { + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz", + "integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==" + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + }, + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + }, + "adm-zip": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==" + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, + "azure-devops-node-api": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.2.0.tgz", + "integrity": "sha512-htza/rAmMNdLWpoFh5kG7CQFaZ17ylDEGCcQCTIu39R33YFCB8LIJNzjIL9Uqudzc5VdU47sxcXxAJvcuwc3Tw==", + "requires": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "azure-pipelines-task-lib": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.6.1.tgz", + "integrity": "sha512-3/LFgNNHY0Cw9vArQPxM6ZgPWt3/G2Yy6F75k2AJzKUCotp5X9gZcvF399tVo6T6lTOlp3Vm7VBXq+kzZ6hZmw==", + "requires": { + "adm-zip": "^0.5.10", + "deasync": "^0.1.28", + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "nodejs-file-downloader": "^4.11.1", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "uuid": "^3.0.1" + } + }, + "azure-pipelines-tasks-docker-common": { + "version": "2.198.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-docker-common/-/azure-pipelines-tasks-docker-common-2.198.1.tgz", + "integrity": "sha512-lgN/sNVhxVxnIM1HoUy8BO8A7idw1ypICBmdPOJUdw21Oy+7cplWfTnygFLPvGSFCN3VnSJFbzBe8LewcWplow==", + "requires": { + "@types/mocha": "^5.2.7", + "@types/node": "^10.17.0", + "@types/q": "1.5.4", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^3.1.0", + "del": "2.2.0", + "q": "1.4.1" + }, + "dependencies": { + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" + }, + "azure-pipelines-task-lib": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.4.0.tgz", + "integrity": "sha512-3eC4OTFw+7xD7A2aUhxR/j+jRlTI+vVfS0CGxt1pCLs4c/KmY0tQWgbqjD3157kmiucWxELBvgZHaD2gCBe9fg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + } + } + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha512-/CdEdaw49VZVmyIDGUQKDDT53c7qBkO6g5CefWz91Ae+l4+cRtcDYwMTXh6me4O8TMldeGHG3N2Bl84V78Ywbg==" + } + } + }, + "azure-pipelines-tasks-utility-common": { + "version": "3.225.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-utility-common/-/azure-pipelines-tasks-utility-common-3.225.1.tgz", + "integrity": "sha512-4wtVKuvx2PcQI0W8xkMdS/S+tf9Qu7wMJl4HSTLE1gjQ2x9o/6QbhMogz6O1+8ofxvTqmI4scA7GHKccDAwQpQ==", + "requires": { + "@types/node": "^16.11.39", + "azure-pipelines-task-lib": "^4.4.0", + "azure-pipelines-tool-lib": "^2.0.0-preview", + "js-yaml": "3.13.1", + "semver": "^5.4.1" + } + }, + "azure-pipelines-tool-lib": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/azure-pipelines-tool-lib/-/azure-pipelines-tool-lib-2.0.6.tgz", + "integrity": "sha512-972uj4vMieY2tHrVowjHDR5N8rvuJP7eIOzchjUz+eHTEtRCLWbQbfJpVxcbfsA+KZJOomqTxgZ3+icS642hqw==", + "requires": { + "@types/semver": "^5.3.0", + "@types/uuid": "^3.4.5", + "azure-pipelines-task-lib": "^4.1.0", + "semver": "^5.7.0", + "semver-compare": "^1.0.0", + "typed-rest-client": "^1.8.6", + "uuid": "^3.3.2" + }, + "dependencies": { + "@types/uuid": { + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.12.tgz", + "integrity": "sha512-4mZWvs9415R6KNlPUZaMDgpnNpFZrO7yZoFfVc6phuOpnUlU06KGu4+83e857jfWkYBMNVZF/1HDoG/aEbePow==" + } + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "requires": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "deasync": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.29.tgz", + "integrity": "sha512-EBtfUhVX23CE9GR6m+F8WPeImEE4hR/FW9RkK0PMl9V1t283s0elqsTD8EZjaKX28SY1BW2rYfCgNsAYdpamUw==", + "requires": { + "bindings": "^1.5.0", + "node-addon-api": "^1.7.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "del": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.0.tgz", + "integrity": "sha512-AZDiRb78EEGYCsAZTG3v+CM5q8J0BIs+wI7QeUtyosm+zIMm4XSmp6aI/K7cU9l+YaKpDKN9dYP1xTrNjLQ+LA==", + "requires": { + "globby": "^4.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "requires": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" + }, + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globby": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", + "integrity": "sha512-JPDtMSr0bt25W64q792rvlrSwIaZwqUAhqdYKSr57Wh/xBcQ5JDWLM85ndn+Q1WdBQXLb9YGCl0QN/T0HpqU0A==", + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^6.0.1", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "requires": { + "get-intrinsic": "^1.2.2" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + } + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "requires": { + "hasown": "^2.0.0" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha512-cnS56eR9SPAscL77ik76ATVqoPARTqPIVkMDVxRaWH06zT+6+CzIroYRJ0VVvm0Z1zfAvxvz9i/D3Ppjaqt5Nw==" + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==", + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mockery": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-2.1.0.tgz", + "integrity": "sha512-9VkOmxKlWXoDO/h1jDZaS4lH33aWfRiJiNT/tKj+8OGzrcFDLo8d0syGdbsc3Bc4GvRXPb+NMMvojotmuGJTvA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==" + }, + "nodejs-file-downloader": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/nodejs-file-downloader/-/nodejs-file-downloader-4.12.1.tgz", + "integrity": "sha512-LpfCTNhh805AlLnJnzt1PuEj+RmbrccbAQZ6hBRw2e6QPVR0Qntuo6qqyvPHG5s77/0w0IEKgRAD4nbSnr/X4w==", + "requires": { + "follow-redirects": "^1.15.1", + "https-proxy-agent": "^5.0.0", + "mime-types": "^2.1.27", + "sanitize-filename": "^1.6.3" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "requires": { + "pinkie": "^2.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "requires": { + "asap": "~2.0.6" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" + }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + } + } + }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "typed-rest-client": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "typescript": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "dev": true + }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + } + } +} diff --git a/Tasks/AzureTestPlanV0/package.json b/Tasks/AzureTestPlanV0/package.json new file mode 100644 index 000000000000..3c8edbd75d2e --- /dev/null +++ b/Tasks/AzureTestPlanV0/package.json @@ -0,0 +1,35 @@ +{ + "name": "azure-tasks-runTestPlan", + "version": "1.0.0", + "description": "Azure Pipelines Run Manual and Automated Test execution Task", + "main": "runTestPlan.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/azure-pipelines-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/azure-pipelines-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/azure-pipelines-tasks#readme", + "dependencies": { + "@types/node": "^16.11.39", + "@types/q": "^1.0.7", + "@types/mocha": "^9.1.1", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^4.1.0", + "azure-pipelines-tasks-docker-common": "2.198.1", + "azure-pipelines-tasks-utility-common": "^3.212.0", + "azure-devops-node-api": "^12.2.0", + "azure-pipelines-tool-lib": "^2.0.0-preview", + "typed-rest-client": "^1.8.9", + "axios": "^1.6.2" + }, + "devDependencies": { + "typescript": "4.0.2" + } +} diff --git a/Tasks/AzureTestPlanV0/runTestPlan.ts b/Tasks/AzureTestPlanV0/runTestPlan.ts new file mode 100644 index 000000000000..a1f3c4001a2e --- /dev/null +++ b/Tasks/AzureTestPlanV0/runTestPlan.ts @@ -0,0 +1,19 @@ +import * as tl from 'azure-pipelines-task-lib/task'; +import { manualTestsFlow} from './manualTests' +import { automatedTestsFlow} from './automatedTests' + +export async function run() { + + const testSelectorInput = tl.getInput('testSelector'); + console.log('Test Selector selected : ' + testSelectorInput); + + // trigger manual, automated or both tests based on user's input + if (testSelectorInput.includes('manualTests')) { + manualTestsFlow(); + } + if (testSelectorInput.includes('automatedTests')) { + automatedTestsFlow(testSelectorInput); + } +} + +run(); diff --git a/Tasks/AzureTestPlanV0/task.json b/Tasks/AzureTestPlanV0/task.json new file mode 100644 index 000000000000..240fa1ddcb26 --- /dev/null +++ b/Tasks/AzureTestPlanV0/task.json @@ -0,0 +1,136 @@ +{ + "id": "105e2492-460a-4da6-56d5-2fa9ab3f0174", + "name": "AzureTestPlan", + "friendlyName": "Azure Test Plan", + "description": "Run manual and automated tests in test plan in Java and python language", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/test/publish-test-results", + "helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613742)", + "category": "Test", + "visibility": [ + "Build", + "Release" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 234, + "Patch": 0 + }, + "preview": true, + "demands": [], + "minimumAgentVersion": "2.144.0", + "inputs": [ + { + "name": "testSelector", + "type": "pickList", + "label": "Test cases to be executed", + "required": true, + "helpMarkDown": "
    • Manual tests: Use this option to trigger manual tests from your test plan.
    • Automated tests: Use this option to run tests from your test plan that have automated test method associated with it.
    • ", + "options": { + "manualTests": "Manual tests", + "automatedTests": "Automated tests" + }, + "properties": { + "MultiSelectFlatList": "True" + } + }, + { + "name": "testPlan", + "type": "pickList", + "label": "Test plan", + "defaultValue": "", + "required": true, + "helpMarkDown": "Select a test plan containing test suites with test cases.", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testSuite", + "type": "pickList", + "label": "Test suite", + "defaultValue": "", + "helpMarkDown": "Select one or more test suites containing test cases.", + "required": true, + "properties": { + "MultiSelect": "True", + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testConfiguration", + "type": "pickList", + "label": "Test configuration", + "defaultValue": "", + "required": true, + "helpMarkDown": "Select Test Configuration.", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testLanguageInput", + "type": "pickList", + "label": "Select Test framework language", + "helpMarkDown": "Test Framework Language of automated tests in test plan", + "options": { + "Java-Maven": "Java-Maven", + "Java-Gradle": "Java-Gradle", + "Python": "Python" + }, + "properties": { + "MultiSelectFlatList": "True" + } + } + ], + "dataSourceBindings": [ + { + "target": "testPlan", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans?filterActivePlans=true&api-version=3.0-preview.2&$skip={{skip}}&$top=1000", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }", + "callbackContextTemplate": "{\"skip\": \"{{add skip 1000}}\"}", + "callbackRequiredTemplate": "{{isEqualNumber result.count 1000}}", + "initialContextTemplate": "{\"skip\": \"0\"}" + }, + { + "target": "testConfiguration", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/configurations?api-version=3.0-preview.1", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }" + }, + { + "target": "testSuite", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans/{{testPlan}}/suites?$asTreeView=true&api-version=3.0-preview.2", + "parameters": { + "testPlan": "$(testPlan)" + }, + "resultSelector": "jsonpath:$.value[*]" + } + ], + "instanceNameFormat": "Azure Test Plan - $(testSelector)", + "execution": { + "Node10": { + "target": "runTestPlan.js", + "argumentFormat": "" + }, + "Node16": { + "target": "runTestPlan.js", + "argumentFormat": "" + } + }, + "messages": { + "testPlanInput": "Test plan Id : %s", + "testplanConfigInput": "Test plan configuration Id : %s", + "testSuiteSelected": "Test suite Id selected: %s", + "automatedTestsTriggered": "Trigerring execution of Automated tests from test plan", + "ErrorFailTaskOnExecutingTests": "Error occured while executing test command", + "ErrorFailTaskOnAPIFailure": "Error occured while fetching automated tests from test plan inputs" + } +} \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/task.loc.json b/Tasks/AzureTestPlanV0/task.loc.json new file mode 100644 index 000000000000..80994abc0f67 --- /dev/null +++ b/Tasks/AzureTestPlanV0/task.loc.json @@ -0,0 +1,136 @@ +{ + "id": "105e2492-460a-4da6-56d5-2fa9ab3f0174", + "name": "AzureTestPlan", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/test/publish-test-results", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "category": "Test", + "visibility": [ + "Build", + "Release" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 234, + "Patch": 0 + }, + "preview": true, + "demands": [], + "minimumAgentVersion": "2.144.0", + "inputs": [ + { + "name": "testSelector", + "type": "pickList", + "label": "ms-resource:loc.input.label.testSelector", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testSelector", + "options": { + "manualTests": "Manual tests", + "automatedTests": "Automated tests" + }, + "properties": { + "MultiSelectFlatList": "True" + } + }, + { + "name": "testPlan", + "type": "pickList", + "label": "ms-resource:loc.input.label.testPlan", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testPlan", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testSuite", + "type": "pickList", + "label": "ms-resource:loc.input.label.testSuite", + "defaultValue": "", + "helpMarkDown": "ms-resource:loc.input.help.testSuite", + "required": true, + "properties": { + "MultiSelect": "True", + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testConfiguration", + "type": "pickList", + "label": "ms-resource:loc.input.label.testConfiguration", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testConfiguration", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testLanguageInput", + "type": "pickList", + "label": "ms-resource:loc.input.label.testLanguageInput", + "helpMarkDown": "ms-resource:loc.input.help.testLanguageInput", + "options": { + "Java-Maven": "Java-Maven", + "Java-Gradle": "Java-Gradle", + "Python": "Python" + }, + "properties": { + "MultiSelectFlatList": "True" + } + } + ], + "dataSourceBindings": [ + { + "target": "testPlan", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans?filterActivePlans=true&api-version=3.0-preview.2&$skip={{skip}}&$top=1000", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }", + "callbackContextTemplate": "{\"skip\": \"{{add skip 1000}}\"}", + "callbackRequiredTemplate": "{{isEqualNumber result.count 1000}}", + "initialContextTemplate": "{\"skip\": \"0\"}" + }, + { + "target": "testConfiguration", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/configurations?api-version=3.0-preview.1", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }" + }, + { + "target": "testSuite", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans/{{testPlan}}/suites?$asTreeView=true&api-version=3.0-preview.2", + "parameters": { + "testPlan": "$(testPlan)" + }, + "resultSelector": "jsonpath:$.value[*]" + } + ], + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "execution": { + "Node10": { + "target": "runTestPlan.js", + "argumentFormat": "" + }, + "Node16": { + "target": "runTestPlan.js", + "argumentFormat": "" + } + }, + "messages": { + "testPlanInput": "ms-resource:loc.messages.testPlanInput", + "testplanConfigInput": "ms-resource:loc.messages.testplanConfigInput", + "testSuiteSelected": "ms-resource:loc.messages.testSuiteSelected", + "automatedTestsTriggered": "ms-resource:loc.messages.automatedTestsTriggered", + "ErrorFailTaskOnExecutingTests": "ms-resource:loc.messages.ErrorFailTaskOnExecutingTests", + "ErrorFailTaskOnAPIFailure": "ms-resource:loc.messages.ErrorFailTaskOnAPIFailure" + } +} \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/testexecutor.ts b/Tasks/AzureTestPlanV0/testexecutor.ts new file mode 100644 index 000000000000..afb60df1681f --- /dev/null +++ b/Tasks/AzureTestPlanV0/testexecutor.ts @@ -0,0 +1,23 @@ +import * as path from 'path'; +import * as fs from 'fs'; +import * as semver from "semver" +import { spawnSync } from 'child_process' +import tl = require('azure-pipelines-task-lib/task'); + +export function spawn(executable: string, args: string[]): Promise { + + console.log("-------------------------------------------") + console.log("test execution begins") + console.log("-------------------------------------------") + console.log('Test command executable: ' + executable); + console.log('Test command args: ' + args); + + const { status, error } = spawnSync(executable, args, { stdio: 'inherit' }) + + return Promise.resolve({ status, error }) +} + +interface SpawnResult { + status: number | null + error?: Error +} \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/tsconfig.json b/Tasks/AzureTestPlanV0/tsconfig.json new file mode 100644 index 000000000000..0438b79f69ac --- /dev/null +++ b/Tasks/AzureTestPlanV0/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs" + } +} \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/utils.ts b/Tasks/AzureTestPlanV0/utils.ts new file mode 100644 index 000000000000..5ea70d7cea39 --- /dev/null +++ b/Tasks/AzureTestPlanV0/utils.ts @@ -0,0 +1,23 @@ +export function removeParenthesesFromEnd(inputString) { + // Check if the string ends with parentheses + if (inputString.endsWith('()')) { + // Remove the parentheses from the end + return inputString.slice(0, -2); + } else { + // If no parentheses at the end, return the original string + return inputString; + } +} + +export function replaceLastDotWithHash(inputString) { + const lastDotIndex = inputString.lastIndexOf('.'); + + if (lastDotIndex !== -1) { + const stringWithHash = inputString.slice(0, lastDotIndex) + '#' + inputString.slice(lastDotIndex + 1); + return stringWithHash; + } else { + // If there is no dot in the string, return the original string + return inputString; + } +} + diff --git a/Tasks/ChefKnifeV1/ChefKnife.ps1 b/Tasks/ChefKnifeV1/ChefKnife.ps1 index 74825d9f4aef..4ef50eff0033 100644 --- a/Tasks/ChefKnifeV1/ChefKnife.ps1 +++ b/Tasks/ChefKnifeV1/ChefKnife.ps1 @@ -31,6 +31,13 @@ try #setting up chef repo with the chef subscription details fetched before Initialize-ChefRepo $connectedServiceDetails Invoke-Expression -Command $scriptCommand + $featureFlags = @{ + failDeprecatedBuildTask = [System.Convert]::ToBoolean($env:FAIL_DEPRECATED_BUILD_TASK) + } + if ($featureFlags.failDeprecatedBuildTask) + { + throw "The ChefKnife@1 (Run scripts with Knife commands on your Chef workstation) task has been deprecated since March 5, 2018 and will soon be retired. To continue to use Chef Knife, use the Knife client directly from a bash/pwsh/script task. See https://docs.chef.io/workstation/knife_client/." + } } finally { diff --git a/Tasks/ChefKnifeV1/task.json b/Tasks/ChefKnifeV1/task.json index 4504da58d416..31b79240b2db 100644 --- a/Tasks/ChefKnifeV1/task.json +++ b/Tasks/ChefKnifeV1/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/ChefKnifeV1/task.loc.json b/Tasks/ChefKnifeV1/task.loc.json index 83ee87467296..1c79b96b5dc1 100644 --- a/Tasks/ChefKnifeV1/task.loc.json +++ b/Tasks/ChefKnifeV1/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/ChefV1/Chef.ps1 b/Tasks/ChefV1/Chef.ps1 index e52ffd191dc3..9286f242e733 100644 --- a/Tasks/ChefV1/Chef.ps1 +++ b/Tasks/ChefV1/Chef.ps1 @@ -186,6 +186,14 @@ try Invoke-Knife @("upload environments/$environment.json") Wait-ForChefNodeRunsToComplete $environment $totalWaitTimeForRunsInMinutes $pollIntervalForRunsInSeconds + + $featureFlags = @{ + failDeprecatedBuildTask = [System.Convert]::ToBoolean($env:FAIL_DEPRECATED_BUILD_TASK) + } + if ($featureFlags.failDeprecatedBuildTask) + { + throw "The Chef@1 (Deploy to Chef environments by editing environment attributes) task has been deprecated since March 5, 2018 and will soon be retired. To continue to use Chef, use the Chef CLI directly from a bash/pwsh/script task. See https://github.com/chef/chef-cli." + } } finally { diff --git a/Tasks/ChefV1/task.json b/Tasks/ChefV1/task.json index fb9951e8f50d..dafc21544d95 100644 --- a/Tasks/ChefV1/task.json +++ b/Tasks/ChefV1/task.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/ChefV1/task.loc.json b/Tasks/ChefV1/task.loc.json index d55735a39a7b..827412781d3b 100644 --- a/Tasks/ChefV1/task.loc.json +++ b/Tasks/ChefV1/task.loc.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/Common/VstsAzureHelpers_/InitializeAzureRMFunctions.ps1 b/Tasks/Common/VstsAzureHelpers_/InitializeAzureRMFunctions.ps1 index 1f2dafb8f638..90f75b003b56 100644 --- a/Tasks/Common/VstsAzureHelpers_/InitializeAzureRMFunctions.ps1 +++ b/Tasks/Common/VstsAzureHelpers_/InitializeAzureRMFunctions.ps1 @@ -1,6 +1,10 @@ # Dot source Utility functions. . $PSScriptRoot/Utility.ps1 +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Initialize-AzureRMModule { [CmdletBinding()] param( @@ -80,9 +84,23 @@ function Initialize-AzureRMSubscription { # Clear context if ($Endpoint.Auth.Scheme -eq 'ServicePrincipal' -and (Get-Command -Name "Clear-AzureRmContext" -ErrorAction "SilentlyContinue")) { Write-Host "##[command]Clear-AzureRmContext -Scope Process" - $null = Clear-AzureRmContext -Scope Process + if ($featureFlags.retireAzureRM) + { + $null = Clear-AzContext -Scope Process + } + else + { + $null = Clear-AzureRmContext -Scope Process + } Write-Host "##[command]Clear-AzureRmContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue" - $null = Clear-AzureRmContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $null = Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue + } + else + { + $null = Clear-AzureRmContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue + } } $environmentName = "AzureCloud" @@ -121,32 +139,75 @@ function Initialize-AzureRMSubscription { if ($Endpoint.Auth.Parameters.AuthenticationType -eq "SPNCertificate") { Write-Host "##[command]Add-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -CertificateThumbprint ****** -ApplicationId $($Endpoint.Auth.Parameters.ServicePrincipalId) -EnvironmentName $environmentName" - $null = Add-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -EnvironmentName $environmentName + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName + } + else + { + $null = Add-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -EnvironmentName $environmentName + } } else { Write-Host "##[command]Add-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -Credential $psCredential -EnvironmentName $environmentName" - $null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -EnvironmentName $environmentName + + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName + } + else + { + $null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -EnvironmentName $environmentName + } } } else { if ($Endpoint.Auth.Parameters.AuthenticationType -eq "SPNCertificate") { Write-Host "##[command]Add-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -CertificateThumbprint ****** -ApplicationId $($Endpoint.Auth.Parameters.ServicePrincipalId) -Environment $environmentName" - $null = Add-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName + } + else + { + $null = Add-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName + } } else { Write-Host "##[command]Add-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -Credential $psCredential -Environment $environmentName" - $null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName + } + else + { + $null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName + } } } } else { if ($Endpoint.Auth.Parameters.AuthenticationType -eq "SPNCertificate") { Write-Host "##[command]Connect-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -CertificateThumbprint ****** -ApplicationId $($Endpoint.Auth.Parameters.ServicePrincipalId) -Environment $environmentName" - $null = Connect-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName + if ($featureFlags.retireAzureRM) + { + $null = Connect-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName + } + else + { + $null = Connect-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName + } } else { Write-Host "##[command]Connect-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -Credential $psCredential -Environment $environmentName" - $null = Connect-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName + if ($featureFlags.retireAzureRM) + { + $null = Connect-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName + } + else + { + $null = Connect-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName + } } } } @@ -172,7 +233,14 @@ function Initialize-AzureRMSubscription { $access_token = Get-MsiAccessToken $Endpoint try { Write-Host "##[command]Add-AzureRmAccount -AccessToken ****** -AccountId $accountId " - $null = Add-AzureRmAccount -AccessToken $access_token -AccountId $accountId + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -AccessToken $access_token -AccountId $accountId + } + else + { + $null = Add-AzureRmAccount -AccessToken $access_token -AccountId $accountId + } } catch { # Provide an additional, custom, credentials-related error message. Write-VstsTaskError -Message $_.Exception.Message @@ -196,6 +264,14 @@ function Set-CurrentAzureRMSubscriptionV2 { if ($TenantId) { $additional['TenantId'] = $TenantId } Write-Host "##[command] Set-AzureRmContext -SubscriptionId $SubscriptionId $(Format-Splat $additional)" - $null = Set-AzureRmContext -SubscriptionId $SubscriptionId @additional + if ($featureFlags.retireAzureRM) + { + $null = Set-AzContext -Subscription $SubscriptionId @additional + } + else + { + $null = Set-AzureRmContext -SubscriptionId $SubscriptionId @additional + } } + diff --git a/Tasks/Common/VstsAzureHelpers_/InitializeFunctions.ps1 b/Tasks/Common/VstsAzureHelpers_/InitializeFunctions.ps1 index 0fb7cafedc21..f7733c2c5173 100644 --- a/Tasks/Common/VstsAzureHelpers_/InitializeFunctions.ps1 +++ b/Tasks/Common/VstsAzureHelpers_/InitializeFunctions.ps1 @@ -1,3 +1,6 @@ +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} function Initialize-AzureSubscription { [CmdletBinding()] @@ -13,14 +16,28 @@ function Initialize-AzureSubscription { # Clear context only for Azure RM if ($Endpoint.Auth.Scheme -eq 'ServicePrincipal' -and !$script:azureModule -and (Get-Command -Name "Clear-AzureRmContext" -ErrorAction "SilentlyContinue")) { Write-Host "##[command]Clear-AzureRmContext -Scope Process" - $null = Clear-AzureRmContext -Scope Process + if ($featureFlags.retireAzureRM) + { + $null = Clear-AzContext -Scope Process + } + else + { + $null = Clear-AzureRmContext -Scope Process + } } if (Get-Command -Name "Disable-AzureRmContextAutosave" -ErrorAction "SilentlyContinue") { try { Write-Host "##[command]Disable-AzureRmContextAutosave -ErrorAction Stop" - $null = Disable-AzureRmContextAutosave -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $null = Disable-AzContextAutosave -ErrorAction Stop + } + else + { + $null = Disable-AzureRmContextAutosave -ErrorAction Stop + } } catch { $message = $_.Exception.Message @@ -108,10 +125,24 @@ function Initialize-AzureSubscription { try { if (Get-Command -Name "Add-AzureRmAccount" -ErrorAction "SilentlyContinue") { Write-Host "##[command] Add-AzureRMAccount -Credential $psCredential" - $null = Add-AzureRMAccount -Credential $psCredential + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -Credential $psCredential + } + else + { + $null = Add-AzureRMAccount -Credential $psCredential + } } else { Write-Host "##[command] Connect-AzureRMAccount -Credential $psCredential" - $null = Connect-AzureRMAccount -Credential $psCredential + if ($featureFlags.retireAzureRM) + { + $null = Connect-AzAccount -Credential $psCredential + } + else + { + $null = Connect-AzureRMAccount -Credential $psCredential + } } } catch { # Provide an additional, custom, credentials-related error message. @@ -198,21 +229,49 @@ function Initialize-AzureSubscription { if ($Endpoint.Auth.Parameters.AuthenticationType -eq "SPNCertificate") { Write-Host "##[command]Add-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -CertificateThumbprint ****** -ApplicationId $($Endpoint.Auth.Parameters.ServicePrincipalId) -EnvironmentName $environmentName @processScope" - $null = Add-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -EnvironmentName $environmentName @processScope + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + } + else + { + $null = Add-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -EnvironmentName $environmentName @processScope + } } else { Write-Host "##[command]Add-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -Credential $psCredential -EnvironmentName $environmentName @processScope" - $null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -EnvironmentName $environmentName @processScope + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + } + else + { + $null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -EnvironmentName $environmentName @processScope + } } } else { if ($Endpoint.Auth.Parameters.AuthenticationType -eq "SPNCertificate") { Write-Host "##[command]Add-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -CertificateThumbprint ****** -ApplicationId $($Endpoint.Auth.Parameters.ServicePrincipalId) -Environment $environmentName @processScope" - $null = Add-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + } + else + { + $null = Add-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + } } else { Write-Host "##[command]Add-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -Credential $psCredential -Environment $environmentName @processScope" - $null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + } + else + { + $null = Add-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + } } } } @@ -228,11 +287,25 @@ function Initialize-AzureSubscription { if ($Endpoint.Auth.Parameters.AuthenticationType -eq "SPNCertificate") { Write-Host "##[command]Connect-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -CertificateThumbprint ****** -ApplicationId $($Endpoint.Auth.Parameters.ServicePrincipalId) -Environment $environmentName @processScope" - $null = Connect-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + if ($featureFlags.retireAzureRM) + { + $null = Connect-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + } + else + { + $null = Connect-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + } } else { Write-Host "##[command]Connect-AzureRMAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -Credential $psCredential -Environment $environmentName @processScope" - $null = Connect-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + if ($featureFlags.retireAzureRM) + { + $null = Connect-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + } + else + { + $null = Connect-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + } } } } @@ -294,11 +367,25 @@ function Initialize-AzureSubscription { if ($Endpoint.Auth.Parameters.AuthenticationType -eq "SPNCertificate") { Write-Host "##[command]Connect-AzAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -CertificateThumbprint ****** -ApplicationId $($Endpoint.Auth.Parameters.ServicePrincipalId) -Environment $environmentName @processScope" - $null = Connect-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + if ($featureFlags.retireAzureRM) + { + $null = Connect-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + } + else + { + $null = Connect-AzureRmAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -CertificateThumbprint $servicePrincipalCertificate.Thumbprint -ApplicationId $Endpoint.Auth.Parameters.ServicePrincipalId -Environment $environmentName @processScope + } } else { Write-Host "##[command]Connect-AzAccount -ServicePrincipal -Tenant $($Endpoint.Auth.Parameters.TenantId) -Credential $psCredential -Environment $environmentName @processScope" - $null = Connect-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + if ($featureFlags.retireAzureRM) + { + $null = Connect-AzAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + } + else + { + $null = Connect-AzureRMAccount -ServicePrincipal -Tenant $Endpoint.Auth.Parameters.TenantId -Credential $psCredential -Environment $environmentName @processScope + } } } } @@ -324,7 +411,14 @@ function Initialize-AzureSubscription { $access_token = Get-MsiAccessToken $Endpoint try { Write-Host "##[command]Add-AzureRmAccount -AccessToken ****** -AccountId $accountId " - $null = Add-AzureRmAccount -AccessToken $access_token -AccountId $accountId + if ($featureFlags.retireAzureRM) + { + $null = Add-AzAccount -AccessToken $access_token -AccountId $accountId + } + else + { + $null = Add-AzureRmAccount -AccessToken $access_token -AccountId $accountId + } } catch { # Provide an additional, custom, credentials-related error message. Write-VstsTaskError -Message $_.Exception.Message @@ -369,10 +463,25 @@ function Set-CurrentAzureRMSubscription { if (Get-Command -Name "Select-AzureRmSubscription" -ErrorAction "SilentlyContinue") { Write-Host "##[command] Select-AzureRMSubscription -SubscriptionId $SubscriptionId $(Format-Splat $additional)" - $null = Select-AzureRMSubscription -SubscriptionId $SubscriptionId @additional + if ($featureFlags.retireAzureRM) + { + $null = Select-AzSubscription -Subscription $SubscriptionId @additional + } + else + { + $null = Select-AzureRMSubscription -SubscriptionId $SubscriptionId @additional + } } else { Write-Host "##[command] Set-AzureRmContext -SubscriptionId $SubscriptionId $(Format-Splat $additional)" - $null = Set-AzureRmContext -SubscriptionId $SubscriptionId @additional + if ($featureFlags.retireAzureRM) + { + $null = Set-AzContext -Subscription $SubscriptionId @additional + } + else + { + $null = Set-AzureRmContext -SubscriptionId $SubscriptionId @additional + } } } + diff --git a/Tasks/Common/VstsAzureHelpers_/Utility.ps1 b/Tasks/Common/VstsAzureHelpers_/Utility.ps1 index 3b49b5c2c923..546fee8562d1 100644 --- a/Tasks/Common/VstsAzureHelpers_/Utility.ps1 +++ b/Tasks/Common/VstsAzureHelpers_/Utility.ps1 @@ -1,4 +1,8 @@ -function Add-Certificate { +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + +function Add-Certificate { [CmdletBinding()] param( [Parameter(Mandatory=$true)] $Endpoint, @@ -577,29 +581,69 @@ function Add-AzureStackAzureRmEnvironment { $galleryEndpoint = $Endpoint.data.galleryUrl } - $azureEnvironmentParams = @{ - Name = $Name - ActiveDirectoryEndpoint = $activeDirectoryEndpoint - ActiveDirectoryServiceEndpointResourceId = $activeDirectoryServiceEndpointResourceId - ResourceManagerEndpoint = $ResourceManagerEndpoint - GalleryEndpoint = $galleryEndpoint - GraphEndpoint = $graphEndpoint - GraphAudience = $graphAudience - StorageEndpointSuffix = $StorageEndpointSuffix - AzureKeyVaultDnsSuffix = $AzureKeyVaultDnsSuffix - AzureKeyVaultServiceEndpointResourceId = $AzureKeyVaultServiceEndpointResourceId - EnableAdfsAuthentication = $aadAuthorityEndpoint.TrimEnd("/").EndsWith("/adfs", [System.StringComparison]::OrdinalIgnoreCase) + if ($featureFlags.retireAzureRM) + { + $azureEnvironmentParams = @{ + Name = $Name + ActiveDirectoryEndpoint = $activeDirectoryEndpoint + ActiveDirectoryServiceEndpointResourceId = $activeDirectoryServiceEndpointResourceId + ResourceManagerEndpoint = $ResourceManagerEndpoint + GalleryEndpoint = $galleryEndpoint + GraphEndpoint = $graphEndpoint + GraphAudience = $graphAudience + StorageEndpoint = $StorageEndpointSuffix + AzureKeyVaultDnsSuffix = $AzureKeyVaultDnsSuffix + AzureKeyVaultServiceEndpointResourceId = $AzureKeyVaultServiceEndpointResourceId + EnableAdfsAuthentication = $aadAuthorityEndpoint.TrimEnd("/").EndsWith("/adfs", [System.StringComparison]::OrdinalIgnoreCase) + } + } + else + { + $azureEnvironmentParams = @{ + Name = $Name + ActiveDirectoryEndpoint = $activeDirectoryEndpoint + ActiveDirectoryServiceEndpointResourceId = $activeDirectoryServiceEndpointResourceId + ResourceManagerEndpoint = $ResourceManagerEndpoint + GalleryEndpoint = $galleryEndpoint + GraphEndpoint = $graphEndpoint + GraphAudience = $graphAudience + StorageEndpointSuffix = $StorageEndpointSuffix + AzureKeyVaultDnsSuffix = $AzureKeyVaultDnsSuffix + AzureKeyVaultServiceEndpointResourceId = $AzureKeyVaultServiceEndpointResourceId + EnableAdfsAuthentication = $aadAuthorityEndpoint.TrimEnd("/").EndsWith("/adfs", [System.StringComparison]::OrdinalIgnoreCase) + } } - $armEnv = Get-AzureRmEnvironment -Name $name + if ($featureFlags.retireAzureRM) + { + $armEnv = Get-AzEnvironment -Name $name + } + else + { + $armEnv = Get-AzureRmEnvironment -Name $name + } if($armEnv -ne $null) { Write-Verbose "Updating AzureRm environment $name" -Verbose if (CmdletHasMember -cmdlet Remove-AzureRmEnvironment -memberName Force) { - Remove-AzureRmEnvironment -Name $name -Force | Out-Null + if ($featureFlags.retireAzureRM) + { + Remove-AzEnvironment -Name $name -Force | Out-Null + } + else + { + Remove-AzureRmEnvironment -Name $name -Force | Out-Null + } } else { - Remove-AzureRmEnvironment -Name $name | Out-Null + if ($featureFlags.retireAzureRM) + { + Remove-AzEnvironment -Name $name | Out-Null + } + else + { + Remove-AzureRmEnvironment -Name $name | Out-Null + } } } else { @@ -607,7 +651,14 @@ function Add-AzureStackAzureRmEnvironment { } try { - return Add-AzureRmEnvironment @azureEnvironmentParams + if ($featureFlags.retireAzureRM) + { + return Add-AzEnvironment @azureEnvironmentParams + } + else + { + return Add-AzureRmEnvironment @azureEnvironmentParams + } } catch { Assert-TlsError -exception $_.Exception @@ -667,19 +718,48 @@ function Disconnect-UsingARMModule { if ((Get-Command -Name "Disconnect-AzureRmAccount" -ErrorAction "SilentlyContinue") -and (CmdletHasMember -cmdlet Disconnect-AzureRmAccount -memberName Scope)) { Write-Host "##[command]Disconnect-AzureRmAccount -Scope Process -ErrorAction Stop" - $null = Disconnect-AzureRmAccount -Scope Process -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $null = Disconnect-AzAccount -Scope Process -ErrorAction Stop + } + else + { + $null = Disconnect-AzureRmAccount -Scope Process -ErrorAction Stop + } } elseif ((Get-Command -Name "Remove-AzureRmAccount" -ErrorAction "SilentlyContinue") -and (CmdletHasMember -cmdlet Remove-AzureRmAccount -memberName Scope)) { Write-Host "##[command]Remove-AzureRmAccount -Scope Process -ErrorAction Stop" - $null = Remove-AzureRmAccount -Scope Process -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $null = Remove-AzAccount -Scope Process -ErrorAction Stop + } + else + { + $null = Remove-AzureRmAccount -Scope Process -ErrorAction Stop + } } elseif ((Get-Command -Name "Logout-AzureRmAccount" -ErrorAction "SilentlyContinue") -and (CmdletHasMember -cmdlet Logout-AzureRmAccount -memberName Scope)) { Write-Host "##[command]Logout-AzureRmAccount -Scope Process -ErrorAction Stop" - $null = Logout-AzureRmAccount -Scope Process -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $null = Disconnect-AzAccount -Scope Process -ErrorAction Stop + } + else + { + $null = Logout-AzureRmAccount -Scope Process -ErrorAction Stop + } } if (Get-Command -Name "Clear-AzureRmContext" -ErrorAction "SilentlyContinue") { Write-Host "##[command]Clear-AzureRmContext -Scope Process -ErrorAction Stop" - $null = Clear-AzureRmContext -Scope Process -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $null = Clear-AzContext -Scope Process -ErrorAction Stop + } + else + { + $null = Clear-AzureRmContext -Scope Process -ErrorAction Stop + } } -} \ No newline at end of file +} + diff --git a/Tasks/CondaEnvironmentV1/Strings/resources.resjson/en-US/resources.resjson b/Tasks/CondaEnvironmentV1/Strings/resources.resjson/en-US/resources.resjson index 2352ea09a954..74ac7b229902 100644 --- a/Tasks/CondaEnvironmentV1/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/CondaEnvironmentV1/Strings/resources.resjson/en-US/resources.resjson @@ -24,5 +24,6 @@ "loc.messages.ReactivateExistingEnvironment": "Found existing environment %s and the task's \"Clean environment\" parameter is not set. Reactivating ...", "loc.messages.ParameterRequired": "The `%s` parameter is required", "loc.messages.PlatformNotRecognized": "Platform not recognized", - "loc.messages.PrependPath": "Prepending PATH environment variable with directory: %s" + "loc.messages.PrependPath": "Prepending PATH environment variable with directory: %s", + "loc.messages.DeprecatedTask": "The CondaEnvironment@1 (Conda environment) task has been deprecated since February 13, 2019 and will soon be retired. Use the Conda CLI ('conda') directly from a bash/pwsh/script task." } \ No newline at end of file diff --git a/Tasks/CondaEnvironmentV1/main.ts b/Tasks/CondaEnvironmentV1/main.ts index f7cfd3d0a31c..2d084e0af3ee 100644 --- a/Tasks/CondaEnvironmentV1/main.ts +++ b/Tasks/CondaEnvironmentV1/main.ts @@ -19,6 +19,11 @@ import { condaEnvironment } from './conda'; cleanEnvironment: task.getBoolInput('cleanEnvironment') }, getPlatform()); + let shouldFail = task.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + + if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(task.loc("DeprecatedTask")); + } task.setResult(task.TaskResult.Succeeded, ""); } catch (e) { #if NODE20 diff --git a/Tasks/CondaEnvironmentV1/task.json b/Tasks/CondaEnvironmentV1/task.json index 3f4ee52e5887..256fb105599c 100644 --- a/Tasks/CondaEnvironmentV1/task.json +++ b/Tasks/CondaEnvironmentV1/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, @@ -101,6 +101,7 @@ "ReactivateExistingEnvironment": "Found existing environment %s and the task's \"Clean environment\" parameter is not set. Reactivating ...", "ParameterRequired": "The `%s` parameter is required", "PlatformNotRecognized": "Platform not recognized", - "PrependPath": "Prepending PATH environment variable with directory: %s" + "PrependPath": "Prepending PATH environment variable with directory: %s", + "DeprecatedTask": "The CondaEnvironment@1 (Conda environment) task has been deprecated since February 13, 2019 and will soon be retired. Use the Conda CLI ('conda') directly from a bash/pwsh/script task." } } \ No newline at end of file diff --git a/Tasks/CondaEnvironmentV1/task.loc.json b/Tasks/CondaEnvironmentV1/task.loc.json index 17f8a593c7ee..dde84a5aa260 100644 --- a/Tasks/CondaEnvironmentV1/task.loc.json +++ b/Tasks/CondaEnvironmentV1/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, @@ -101,6 +101,11 @@ "ReactivateExistingEnvironment": "ms-resource:loc.messages.ReactivateExistingEnvironment", "ParameterRequired": "ms-resource:loc.messages.ParameterRequired", "PlatformNotRecognized": "ms-resource:loc.messages.PlatformNotRecognized", - "PrependPath": "ms-resource:loc.messages.PrependPath" + "PrependPath": "ms-resource:loc.messages.PrependPath", + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" + }, + "_buildConfigMapping": { + "Default": "1.234.2", + "Node20-225": "1.234.3" } } \ No newline at end of file diff --git a/Tasks/DotNetCoreInstallerV1/Strings/resources.resjson/en-US/resources.resjson b/Tasks/DotNetCoreInstallerV1/Strings/resources.resjson/en-US/resources.resjson index 706457fda6d3..25a049565f25 100644 --- a/Tasks/DotNetCoreInstallerV1/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/DotNetCoreInstallerV1/Strings/resources.resjson/en-US/resources.resjson @@ -78,5 +78,6 @@ "loc.messages.FilesDataIsIncorrectInVersion": "In release %s for version %s, File data is incorrect (might have missing required fields, such as name, rid and url): %s", "loc.messages.VersionFilesDataIncorrect": "Version's files data is missing or has missing required fields.", "loc.messages.VersionInformationNotComplete": "Version: %s required information is not complete in releases.json file. Error: %s", - "loc.messages.FailedWhileExtractingPacakge": "Failed while extracting downloaded package with error: %s" + "loc.messages.FailedWhileExtractingPacakge": "Failed while extracting downloaded package with error: %s", + "loc.messages.DeprecatedTask": "The DotNetCoreInstaller@1 (.NET Core SDK/runtime installer) task has been deprecated since August 22, 2019 and will soon be retired. Use the UseDotNet@2 task instead." } \ No newline at end of file diff --git a/Tasks/DotNetCoreInstallerV1/dotnetcoreinstaller.ts b/Tasks/DotNetCoreInstallerV1/dotnetcoreinstaller.ts index b3989d54e119..8bee770098ed 100644 --- a/Tasks/DotNetCoreInstallerV1/dotnetcoreinstaller.ts +++ b/Tasks/DotNetCoreInstallerV1/dotnetcoreinstaller.ts @@ -41,6 +41,12 @@ async function run() { // Set DOTNET_ROOT for dotnet core Apphost to find runtime since it is installed to a non well-known location. tl.setVariable('DOTNET_ROOT', installationPath); + + let shouldFail = tl.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + + if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(tl.loc("DeprecatedTask")); + } } function addDotNetCoreToolPath() { diff --git a/Tasks/DotNetCoreInstallerV1/task.json b/Tasks/DotNetCoreInstallerV1/task.json index 8b32fe34fbd0..4d8f543063a3 100644 --- a/Tasks/DotNetCoreInstallerV1/task.json +++ b/Tasks/DotNetCoreInstallerV1/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, @@ -153,6 +153,7 @@ "FilesDataIsIncorrectInVersion": "In release %s for version %s, File data is incorrect (might have missing required fields, such as name, rid and url): %s", "VersionFilesDataIncorrect": "Version's files data is missing or has missing required fields.", "VersionInformationNotComplete": "Version: %s required information is not complete in releases.json file. Error: %s", - "FailedWhileExtractingPacakge": "Failed while extracting downloaded package with error: %s" + "FailedWhileExtractingPacakge": "Failed while extracting downloaded package with error: %s", + "DeprecatedTask": "The DotNetCoreInstaller@1 (.NET Core SDK/runtime installer) task has been deprecated since August 22, 2019 and will soon be retired. Use the UseDotNet@2 task instead." } } \ No newline at end of file diff --git a/Tasks/DotNetCoreInstallerV1/task.loc.json b/Tasks/DotNetCoreInstallerV1/task.loc.json index 0099e3f4d228..14e7a158132b 100644 --- a/Tasks/DotNetCoreInstallerV1/task.loc.json +++ b/Tasks/DotNetCoreInstallerV1/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, @@ -153,6 +153,7 @@ "FilesDataIsIncorrectInVersion": "ms-resource:loc.messages.FilesDataIsIncorrectInVersion", "VersionFilesDataIncorrect": "ms-resource:loc.messages.VersionFilesDataIncorrect", "VersionInformationNotComplete": "ms-resource:loc.messages.VersionInformationNotComplete", - "FailedWhileExtractingPacakge": "ms-resource:loc.messages.FailedWhileExtractingPacakge" + "FailedWhileExtractingPacakge": "ms-resource:loc.messages.FailedWhileExtractingPacakge", + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" } } \ No newline at end of file diff --git a/Tasks/DownloadPackageV0/download.ts b/Tasks/DownloadPackageV0/download.ts index 755566049a44..c047160d8b9b 100644 --- a/Tasks/DownloadPackageV0/download.ts +++ b/Tasks/DownloadPackageV0/download.ts @@ -238,5 +238,5 @@ export async function unzip(zipLocation: string, unzipLocation: string): Promise } main() - .then(() => tl.setResult(tl.TaskResult.Succeeded, "")) + .then(() => tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("DeprecatedTask"))) .catch((error) => tl.setResult(tl.TaskResult.Failed, error)); diff --git a/Tasks/DownloadPackageV0/task.json b/Tasks/DownloadPackageV0/task.json index 60e3887589a7..5655fa83715b 100644 --- a/Tasks/DownloadPackageV0/task.json +++ b/Tasks/DownloadPackageV0/task.json @@ -9,7 +9,7 @@ "author": "ms-vscs-rm", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 0 }, "demands": [], diff --git a/Tasks/DownloadPackageV0/task.loc.json b/Tasks/DownloadPackageV0/task.loc.json index a4d0d4885f7d..a2a2b06f06fa 100644 --- a/Tasks/DownloadPackageV0/task.loc.json +++ b/Tasks/DownloadPackageV0/task.loc.json @@ -9,7 +9,7 @@ "author": "ms-vscs-rm", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 0 }, "demands": [], diff --git a/Tasks/IISWebAppDeployment/DeployIISWebApp.ps1 b/Tasks/IISWebAppDeployment/DeployIISWebApp.ps1 index 71e788c73b5a..65308a35e479 100644 --- a/Tasks/IISWebAppDeployment/DeployIISWebApp.ps1 +++ b/Tasks/IISWebAppDeployment/DeployIISWebApp.ps1 @@ -154,4 +154,12 @@ if(-not [string]::IsNullOrEmpty($errorMessage)) throw "$errorMessage $helpMessage" } +$featureFlags = @{ + failDeprecatedBuildTask = [System.Convert]::ToBoolean($env:FAIL_DEPRECATED_BUILD_TASK) +} +if ($featureFlags.failDeprecatedBuildTask) +{ + throw "The IISWebAppDeployment@1 (IIS Web App deployment) task has been deprecated since October 5, 2018 and will soon be retired. Use the 'IIS Web App Deployment Using WinRM' extension instead: https://marketplace.visualstudio.com/items?itemName=ms-vscs-rm.iiswebapp." +} + Write-Output ( Get-LocalizedString -Key "Successfully deployed IIS Web Deploy Package : {0}" -ArgumentList $webDeployPackage) \ No newline at end of file diff --git a/Tasks/IISWebAppDeployment/task.json b/Tasks/IISWebAppDeployment/task.json index 843cd67c9781..d9a154906021 100644 --- a/Tasks/IISWebAppDeployment/task.json +++ b/Tasks/IISWebAppDeployment/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "demands": [], diff --git a/Tasks/IISWebAppDeployment/task.loc.json b/Tasks/IISWebAppDeployment/task.loc.json index 7abcbe8c609d..a425c699e336 100644 --- a/Tasks/IISWebAppDeployment/task.loc.json +++ b/Tasks/IISWebAppDeployment/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "demands": [], diff --git a/Tasks/NuGetInstallerV0/nugetinstaller.ts b/Tasks/NuGetInstallerV0/nugetinstaller.ts index 962fdb205b97..48e0d8898831 100644 --- a/Tasks/NuGetInstallerV0/nugetinstaller.ts +++ b/Tasks/NuGetInstallerV0/nugetinstaller.ts @@ -194,7 +194,7 @@ async function main(): Promise { throw new Error(tl.loc("DeprecatedTask")); } - tl.setResult(tl.TaskResult.Succeeded, tl.loc("PackagesInstalledSuccessfully")); + tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("DeprecatedTask")); } catch (err) { tl.error(err); diff --git a/Tasks/NuGetInstallerV0/task.json b/Tasks/NuGetInstallerV0/task.json index 3fa19e796ceb..3a612338db13 100644 --- a/Tasks/NuGetInstallerV0/task.json +++ b/Tasks/NuGetInstallerV0/task.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 0 }, "runsOn": [ diff --git a/Tasks/NuGetInstallerV0/task.loc.json b/Tasks/NuGetInstallerV0/task.loc.json index 3c821e336abe..1d8e05ed48dd 100644 --- a/Tasks/NuGetInstallerV0/task.loc.json +++ b/Tasks/NuGetInstallerV0/task.loc.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 0 }, "runsOn": [ diff --git a/Tasks/NuGetRestoreV1/nugetinstaller.ts b/Tasks/NuGetRestoreV1/nugetinstaller.ts index 11d345e6159f..0526cddcd298 100644 --- a/Tasks/NuGetRestoreV1/nugetinstaller.ts +++ b/Tasks/NuGetRestoreV1/nugetinstaller.ts @@ -240,7 +240,7 @@ async function main(): Promise { isNugetOrgBehaviorWarn ? tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("Warning_IncludeNuGetOrgEnabled")) - : tl.setResult(tl.TaskResult.Succeeded, tl.loc("PackagesInstalledSuccessfully")); + : tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("DeprecatedTask")); } catch (err) { diff --git a/Tasks/NuGetRestoreV1/task.json b/Tasks/NuGetRestoreV1/task.json index 7a5bb6087e3e..3a572a19934c 100644 --- a/Tasks/NuGetRestoreV1/task.json +++ b/Tasks/NuGetRestoreV1/task.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "runsOn": [ diff --git a/Tasks/NuGetRestoreV1/task.loc.json b/Tasks/NuGetRestoreV1/task.loc.json index 12042987bd7d..7501d6e5b95b 100644 --- a/Tasks/NuGetRestoreV1/task.loc.json +++ b/Tasks/NuGetRestoreV1/task.loc.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "runsOn": [ diff --git a/Tasks/QuickPerfTestV1/Invoke-QuickPerfTest.ps1 b/Tasks/QuickPerfTestV1/Invoke-QuickPerfTest.ps1 index ae6ef2dbd808..d34fcdcc30cf 100644 --- a/Tasks/QuickPerfTestV1/Invoke-QuickPerfTest.ps1 +++ b/Tasks/QuickPerfTestV1/Invoke-QuickPerfTest.ps1 @@ -187,6 +187,13 @@ else Write-Error ("Failed to connect to the endpoint '{0}' for VSO account '{1}'" -f $EndpointName, $VSOAccountUrl) } +$featureFlags = @{ + failDeprecatedBuildTask = [System.Convert]::ToBoolean($env:FAIL_DEPRECATED_BUILD_TASK) +} +if ($featureFlags.failDeprecatedBuildTask) +{ + throw "The QuickPerfTest@1 (Cloud-based web performance test) task has been deprecated since June 4, 2019 and will soon be retired. Use the AzureLoadTest@1 task instead." +} Write-Output "Quick Perf Test Script execution completed" diff --git a/Tasks/QuickPerfTestV1/task.json b/Tasks/QuickPerfTestV1/task.json index 6b3087f156f7..f47eeaa8aa78 100644 --- a/Tasks/QuickPerfTestV1/task.json +++ b/Tasks/QuickPerfTestV1/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/QuickPerfTestV1/task.loc.json b/Tasks/QuickPerfTestV1/task.loc.json index 8115c227b940..30b46298fe64 100644 --- a/Tasks/QuickPerfTestV1/task.loc.json +++ b/Tasks/QuickPerfTestV1/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/RunJMeterLoadTestV1/Start-ApacheJMeterTest.ps1 b/Tasks/RunJMeterLoadTestV1/Start-ApacheJMeterTest.ps1 index b1ef702ec3fa..3a7c05111cf9 100644 --- a/Tasks/RunJMeterLoadTestV1/Start-ApacheJMeterTest.ps1 +++ b/Tasks/RunJMeterLoadTestV1/Start-ApacheJMeterTest.ps1 @@ -184,5 +184,12 @@ else ("Connection '{0}' failed for service '{1}'" -f $connectedServiceName, $connectedServiceDetails.Url.AbsoluteUri) >> $summaryFile } +$featureFlags = @{ + failDeprecatedBuildTask = [System.Convert]::ToBoolean($env:FAIL_DEPRECATED_BUILD_TASK) +} +if ($featureFlags.failDeprecatedBuildTask) +{ + throw "The ApacheJMeterLoadTest@1 (Cloud-based Apache JMeter load test) task haas been deprecated since June 4, 2019 and will soon be retired. For cloud-based load testing, use the AzureLoadTest@1 task." +} WriteTaskMessages "JMeter Test Script execution completed" diff --git a/Tasks/RunJMeterLoadTestV1/task.json b/Tasks/RunJMeterLoadTestV1/task.json index 17b992ed1a24..d0b7231c17c5 100644 --- a/Tasks/RunJMeterLoadTestV1/task.json +++ b/Tasks/RunJMeterLoadTestV1/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/RunJMeterLoadTestV1/task.loc.json b/Tasks/RunJMeterLoadTestV1/task.loc.json index 644c4e291bac..e124a0259b03 100644 --- a/Tasks/RunJMeterLoadTestV1/task.loc.json +++ b/Tasks/RunJMeterLoadTestV1/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/RunLoadTestV1/Start-CloudLoadTest.ps1 b/Tasks/RunLoadTestV1/Start-CloudLoadTest.ps1 index 3dcb7cfc06c9..2f22ff319746 100644 --- a/Tasks/RunLoadTestV1/Start-CloudLoadTest.ps1 +++ b/Tasks/RunLoadTestV1/Start-CloudLoadTest.ps1 @@ -233,5 +233,13 @@ else Write-Error ("Connection '{0}' failed for service '{1}'" -f $connectedServiceName, $connectedServiceDetails.Url.AbsoluteUri) } +$featureFlags = @{ + failDeprecatedBuildTask = [System.Convert]::ToBoolean($env:FAIL_DEPRECATED_BUILD_TASK) +} +if ($featureFlags.failDeprecatedBuildTask) +{ + throw "The CloudLoadTest@1 (Cloud-based load test) has been deprecated since June 4, 2019 and will soon be retired. Use the AzureLoadTest@1 task instead." +} + WriteTaskMessages "Load Test Script execution completed" diff --git a/Tasks/RunLoadTestV1/task.json b/Tasks/RunLoadTestV1/task.json index cba9a19d9cee..b3ba80661b51 100644 --- a/Tasks/RunLoadTestV1/task.json +++ b/Tasks/RunLoadTestV1/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/RunLoadTestV1/task.loc.json b/Tasks/RunLoadTestV1/task.loc.json index 50f8076a709f..3008abe45d56 100644 --- a/Tasks/RunLoadTestV1/task.loc.json +++ b/Tasks/RunLoadTestV1/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, diff --git a/Tasks/SqlAzureDacpacDeploymentV1/task.json b/Tasks/SqlAzureDacpacDeploymentV1/task.json index 33b166c2ab27..053cdb1e16f7 100644 --- a/Tasks/SqlAzureDacpacDeploymentV1/task.json +++ b/Tasks/SqlAzureDacpacDeploymentV1/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/SqlAzureDacpacDeploymentV1/task.loc.json b/Tasks/SqlAzureDacpacDeploymentV1/task.loc.json index 7a449e0c9529..c6e26f1c7cdb 100644 --- a/Tasks/SqlAzureDacpacDeploymentV1/task.loc.json +++ b/Tasks/SqlAzureDacpacDeploymentV1/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/SqlServerDacpacDeployment/DeployToSqlServer.ps1 b/Tasks/SqlServerDacpacDeployment/DeployToSqlServer.ps1 index 2b330f9619f3..eadb79dea226 100644 --- a/Tasks/SqlServerDacpacDeployment/DeployToSqlServer.ps1 +++ b/Tasks/SqlServerDacpacDeployment/DeployToSqlServer.ps1 @@ -81,4 +81,12 @@ if(-not [string]::IsNullOrEmpty($errorMessage)) throw "$errorMessage $helpMessage" } +$featureFlags = @{ + failDeprecatedBuildTask = [System.Convert]::ToBoolean($env:FAIL_DEPRECATED_BUILD_TASK) +} +if ($featureFlags.failDeprecatedBuildTask) +{ + throw "The SqlServerDacpacDeployment@1 (SQL Server database deploy) task has been deprecated since October 5, 2018 and will soon be retired. Use the 'IIS Web App Deployment Using WinRM' extension instead: https://marketplace.visualstudio.com/items?itemName=ms-vscs-rm.iiswebapp. For Azure SQL Database use the SqlAzureDacpacDeployment@1 task." +} + Write-Output ( Get-LocalizedString -Key "Successfully deployed Sql Dacpac File : {0}" -ArgumentList $dacpacFile) \ No newline at end of file diff --git a/Tasks/SqlServerDacpacDeployment/task.json b/Tasks/SqlServerDacpacDeployment/task.json index 44725c2654f8..cc1e81a4c374 100644 --- a/Tasks/SqlServerDacpacDeployment/task.json +++ b/Tasks/SqlServerDacpacDeployment/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "demands": [], diff --git a/Tasks/SqlServerDacpacDeployment/task.loc.json b/Tasks/SqlServerDacpacDeployment/task.loc.json index 93942b9b64e1..55c090fc3e35 100644 --- a/Tasks/SqlServerDacpacDeployment/task.loc.json +++ b/Tasks/SqlServerDacpacDeployment/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "demands": [], diff --git a/Tasks/UseDotNetV2/externals/get-os-distro.sh b/Tasks/UseDotNetV2/externals/get-os-distro.sh index 689da6d682cb..73000e7b5f10 100644 --- a/Tasks/UseDotNetV2/externals/get-os-distro.sh +++ b/Tasks/UseDotNetV2/externals/get-os-distro.sh @@ -159,6 +159,7 @@ get_legacy_os_name() { get_machine_architecture() { if command -v uname > /dev/null; then + local osn=$(get_current_os_name || echo "") CPUName=$(uname -m) case $CPUName in armv7l) @@ -169,6 +170,20 @@ get_machine_architecture() { echo "arm64" return 0 ;; + arm64) + echo "arm64" + return 0 + ;; + x86_64) + if [ "$osn" = "osx" ]; then + if [ "$(sysctl -in sysctl.proc_translated)" = "1" ]; then + echo "arm64" + else + echo "x64" + fi + return 0 + fi + ;; esac fi diff --git a/Tasks/UseDotNetV2/task.json b/Tasks/UseDotNetV2/task.json index 5e565c704714..e6cc28a12594 100644 --- a/Tasks/UseDotNetV2/task.json +++ b/Tasks/UseDotNetV2/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "satisfies": [ @@ -194,4 +194,4 @@ "SupportPhaseNotPresentInChannel": "support-phase is not present in the channel with channel-version %s.", "DepricatedVersionNetCore": "NET Core version you specfied %s is out of support and will be removed from hosted agents soon. Please refer to https://aka.ms/dotnet-core-support for more information about the .NET support policy." } -} \ No newline at end of file +} diff --git a/Tasks/UseDotNetV2/task.loc.json b/Tasks/UseDotNetV2/task.loc.json index d2b79376aae0..f932e612f880 100644 --- a/Tasks/UseDotNetV2/task.loc.json +++ b/Tasks/UseDotNetV2/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "satisfies": [ @@ -194,4 +194,4 @@ "SupportPhaseNotPresentInChannel": "ms-resource:loc.messages.SupportPhaseNotPresentInChannel", "DepricatedVersionNetCore": "ms-resource:loc.messages.DepricatedVersionNetCore" } -} \ No newline at end of file +} diff --git a/Tasks/VsTestV2/make.json b/Tasks/VsTestV2/make.json index 3ec008712366..24fda5eb1455 100644 --- a/Tasks/VsTestV2/make.json +++ b/Tasks/VsTestV2/make.json @@ -6,7 +6,7 @@ "dest": "./" }, { - "url": "https://testexecution.blob.core.windows.net/testexecution/22799172/TestAgent.zip", + "url": "https://testexecution.blob.core.windows.net/testexecution/25847670/TestAgent.zip", "dest": "./Modules" }, { diff --git a/Tasks/VsTestV2/task.json b/Tasks/VsTestV2/task.json index 2b74a321d98f..4baaa50a9ca0 100644 --- a/Tasks/VsTestV2/task.json +++ b/Tasks/VsTestV2/task.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 229, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/VsTestV2/task.loc.json b/Tasks/VsTestV2/task.loc.json index 402f74674fd0..fb66e7e3e228 100644 --- a/Tasks/VsTestV2/task.loc.json +++ b/Tasks/VsTestV2/task.loc.json @@ -17,7 +17,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 229, + "Minor": 234, "Patch": 0 }, "demands": [ diff --git a/Tasks/XamarinTestCloudV1/Strings/resources.resjson/en-US/resources.resjson b/Tasks/XamarinTestCloudV1/Strings/resources.resjson/en-US/resources.resjson index 560a389003c3..bae4406560f9 100644 --- a/Tasks/XamarinTestCloudV1/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/XamarinTestCloudV1/Strings/resources.resjson/en-US/resources.resjson @@ -28,5 +28,6 @@ "loc.input.label.optionalArgs": "Optional arguments", "loc.input.help.optionalArgs": "Additional arguments passed to test-cloud.exe.", "loc.input.label.publishNUnitResults": "Publish results to Azure Pipelines", - "loc.input.help.publishNUnitResults": "When selected, --nunit-xml option will be passed to test-cloud.exe. Results from the NUnit xml file will be published to Azure Pipelines." + "loc.input.help.publishNUnitResults": "When selected, --nunit-xml option will be passed to test-cloud.exe. Results from the NUnit xml file will be published to Azure Pipelines.", + "loc.messages.DeprecatedTask": "The XamarinTestCloud@1 (Xamarin Test Cloud) task has been deprecated since January 11, 2018 and will soon be retired. Use the AppCenterDistribute@3 task instead." } \ No newline at end of file diff --git a/Tasks/XamarinTestCloudV1/XamarinTestCloud.ps1 b/Tasks/XamarinTestCloudV1/XamarinTestCloud.ps1 index 9e100e213e02..80e6b6170378 100644 --- a/Tasks/XamarinTestCloudV1/XamarinTestCloud.ps1 +++ b/Tasks/XamarinTestCloudV1/XamarinTestCloud.ps1 @@ -193,4 +193,11 @@ if($testCloudResults) Write-Host "##vso[task.addattachment type=Distributedtask.Core.Summary;name=Xamarin Test Cloud Results;]$mdReportFile" } +$featureFlags = @{ + failDeprecatedBuildTask = [System.Convert]::ToBoolean($env:FAIL_DEPRECATED_BUILD_TASK) +} +if ($featureFlags.failDeprecatedBuildTask) +{ + throw "The XamarinTestCloud@1 (Xamarin Test Cloud) task has been deprecated since January 11, 2018 and will soon be retired. Use the AppCenterDistribute@3 task instead." +} Write-Verbose "Leaving script XamarinTestCloud.ps1" \ No newline at end of file diff --git a/Tasks/XamarinTestCloudV1/task.json b/Tasks/XamarinTestCloudV1/task.json index 0d6309db01cc..2d7f9ebbb51a 100644 --- a/Tasks/XamarinTestCloudV1/task.json +++ b/Tasks/XamarinTestCloudV1/task.json @@ -1,200 +1,203 @@ { - "id": "049918CB-1488-48EB-85E8-C318ECCAAA74", - "name": "XamarinTestCloud", - "friendlyName": "Xamarin Test Cloud", - "description": "[Deprecated] Test mobile apps with Xamarin Test Cloud using Xamarin.UITest. Instead, use the 'App Center test' task.", - "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/test/xamarin-test-cloud", - "helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613744)", - "category": "Test", - "visibility": [ - "Build", - "Release" - ], - "author": "Microsoft Corporation", - "version": { - "Major": 1, - "Minor": 234, - "Patch": 2 + "id": "049918CB-1488-48EB-85E8-C318ECCAAA74", + "name": "XamarinTestCloud", + "friendlyName": "Xamarin Test Cloud", + "description": "[Deprecated] Test mobile apps with Xamarin Test Cloud using Xamarin.UITest. Instead, use the 'App Center test' task.", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/test/xamarin-test-cloud", + "helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613744)", + "category": "Test", + "visibility": [ + "Build", + "Release" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 1, + "Minor": 235, + "Patch": 0 + }, + "demands": [], + "minimumAgentVersion": "1.83.0", + "groups": [ + { + "name": "advanced", + "displayName": "Advanced", + "isExpanded": true + } + ], + "deprecated": true, + "removalDate": "2024-01-31", + "deprecationMessage": "The XamarinTestCloud@1 (Xamarin Test Cloud) task has been deprecated since January 11, 2018 and will soon be retired. Use the AppCenterDistribute@3 task instead.", + "inputs": [ + { + "name": "app", + "aliases": [ + "appFile" + ], + "type": "filePath", + "label": "App file", + "defaultValue": "", + "required": true, + "helpMarkDown": "Relative path from repo root of the app(s) to test. Wildcards can be used ([more information](https://go.microsoft.com/fwlink/?linkid=856077)). For example, `**/*.apk` for all APK files in all subfolders." + }, + { + "name": "dsym", + "aliases": [ + "dsymFile" + ], + "type": "string", + "label": "dSYM file (iOS only)", + "required": false, + "defaultValue": "", + "helpMarkDown": "To make crash logs easier to read, you can upload a dSYM file that is associated with your app. This field only applies to iOS apps. Provide path relative to the .ipa file. Wildcards can be used ([more information](https://go.microsoft.com/fwlink/?linkid=856077)). For example: *.dSYM" + }, + { + "name": "teamApiKey", + "type": "string", + "label": "Team API key", + "defaultValue": "", + "required": true, + "helpMarkDown": "Your Xamarin Test Cloud Team API key can be found under \"Teams & Apps\" at https://testcloud.xamarin.com/account." + }, + { + "name": "user", + "aliases": [ + "email" + ], + "type": "string", + "label": "User email", + "defaultValue": "", + "required": true, + "helpMarkDown": "User name this test will run under." + }, + { + "name": "devices", + "type": "string", + "label": "Devices", + "defaultValue": "", + "required": true, + "helpMarkDown": "The devices string is generated by Xamarin Test Cloud. It can be found as the value of the --devices command line argument of a Test Cloud test run." + }, + { + "name": "series", + "type": "string", + "label": "Series", + "defaultValue": "master", + "required": true, + "helpMarkDown": "The series name for organizing test runs (e.g. master, production, beta)." + }, + { + "name": "testDir", + "aliases": [ + "testAssemblyDirectory" + ], + "type": "filePath", + "label": "Test assembly directory", + "defaultValue": "", + "required": true, + "helpMarkDown": "Relative path to the folder containing the test assemblies, such as: SolutionName/TestsProjectName/bin/Release" + }, + { + "name": "parallelization", + "aliases": [ + "parallelizationOption" + ], + "type": "pickList", + "label": "Parallelization", + "required": true, + "defaultValue": "none", + "groupName": "advanced", + "options": { + "none": "None", + "--fixture-chunk": "By test fixture", + "--test-chunk": "By test method" + } + }, + { + "name": "locale", + "aliases": [ + "localeOption" + ], + "type": "pickList", + "label": "System language", + "defaultValue": "en_US", + "required": true, + "groupName": "advanced", + "options": { + "da_DK": "Danish (Denmark)", + "nl_NL": "Dutch (Netherlands)", + "en_GB": "English (United Kingdom)", + "en_US": "English (United States)", + "fr_FR": "French (France)", + "de_DE": "German (Germany)", + "ja_JP": "Japanese (Japan)", + "ru_RU": "Russian (Russia)", + "es_MX": "Spanish (Mexico)", + "es_ES": "Spanish (Spain)", + "user": "Other" + }, + "helpMarkDown": "If your language isn't displayed, select 'Other' and enter its locale below, such as en_US." + }, + { + "name": "userDefinedLocale", + "type": "string", + "label": "Other locale", + "groupName": "advanced", + "defaultValue": "", + "required": false, + "visibleRule": "locale = user", + "helpMarkDown": "Enter any two-letter ISO-639 language code along with any two-letter ISO 3166 country code in the format [language]_[country], such as en_US." + }, + { + "name": "testCloudLocation", + "aliases": [ + "testCloudFile" + ], + "type": "filePath", + "label": "test-cloud.exe location", + "groupName": "advanced", + "defaultValue": "**/packages/**/tools/test-cloud.exe", + "required": true, + "helpMarkDown": "The path to test-cloud.exe. Wildcards can be used, in which case the first occurrence of test-cloud.exe is used ([more information](https://go.microsoft.com/fwlink/?linkid=856077))." + }, + { + "name": "optionalArgs", + "type": "string", + "label": "Optional arguments", + "required": false, + "defaultValue": "", + "groupName": "advanced", + "helpMarkDown": "Additional arguments passed to test-cloud.exe." + }, + { + "name": "publishNUnitResults", + "type": "boolean", + "label": "Publish results to Azure Pipelines", + "groupName": "advanced", + "defaultValue": "true", + "helpMarkDown": "When selected, --nunit-xml option will be passed to test-cloud.exe. Results from the NUnit xml file will be published to Azure Pipelines." + } + ], + "instanceNameFormat": "Test $(app) with Xamarin.UITest in Xamarin Test Cloud", + "execution": { + "Node10": { + "target": "xamarintestcloud.js", + "argumentFormat": "" + }, + "Node16": { + "target": "xamarintestcloud.js", + "argumentFormat": "" }, - "demands": [], - "minimumAgentVersion": "1.83.0", - "groups": [ - { - "name": "advanced", - "displayName": "Advanced", - "isExpanded": true - } - ], - "deprecated": true, - "removalDate": "2024-01-31", - "deprecationMessage": "The XamarinTestCloud@1 (Xamarin Test Cloud) task has been deprecated since January 11, 2018 and will soon be retired. Use the AppCenterDistribute@3 task instead.", - "inputs": [ - { - "name": "app", - "aliases": [ - "appFile" - ], - "type": "filePath", - "label": "App file", - "defaultValue": "", - "required": true, - "helpMarkDown": "Relative path from repo root of the app(s) to test. Wildcards can be used ([more information](https://go.microsoft.com/fwlink/?linkid=856077)). For example, `**/*.apk` for all APK files in all subfolders." - }, - { - "name": "dsym", - "aliases": [ - "dsymFile" - ], - "type": "string", - "label": "dSYM file (iOS only)", - "required": false, - "defaultValue": "", - "helpMarkDown": "To make crash logs easier to read, you can upload a dSYM file that is associated with your app. This field only applies to iOS apps. Provide path relative to the .ipa file. Wildcards can be used ([more information](https://go.microsoft.com/fwlink/?linkid=856077)). For example: *.dSYM" - }, - { - "name": "teamApiKey", - "type": "string", - "label": "Team API key", - "defaultValue": "", - "required": true, - "helpMarkDown": "Your Xamarin Test Cloud Team API key can be found under \"Teams & Apps\" at https://testcloud.xamarin.com/account." - }, - { - "name": "user", - "aliases": [ - "email" - ], - "type": "string", - "label": "User email", - "defaultValue": "", - "required": true, - "helpMarkDown": "User name this test will run under." - }, - { - "name": "devices", - "type": "string", - "label": "Devices", - "defaultValue": "", - "required": true, - "helpMarkDown": "The devices string is generated by Xamarin Test Cloud. It can be found as the value of the --devices command line argument of a Test Cloud test run." - }, - { - "name": "series", - "type": "string", - "label": "Series", - "defaultValue": "master", - "required": true, - "helpMarkDown": "The series name for organizing test runs (e.g. master, production, beta)." - }, - { - "name": "testDir", - "aliases": [ - "testAssemblyDirectory" - ], - "type": "filePath", - "label": "Test assembly directory", - "defaultValue": "", - "required": true, - "helpMarkDown": "Relative path to the folder containing the test assemblies, such as: SolutionName/TestsProjectName/bin/Release" - }, - { - "name": "parallelization", - "aliases": [ - "parallelizationOption" - ], - "type": "pickList", - "label": "Parallelization", - "required": true, - "defaultValue": "none", - "groupName": "advanced", - "options": { - "none": "None", - "--fixture-chunk": "By test fixture", - "--test-chunk": "By test method" - } - }, - { - "name": "locale", - "aliases": [ - "localeOption" - ], - "type": "pickList", - "label": "System language", - "defaultValue": "en_US", - "required": true, - "groupName": "advanced", - "options": { - "da_DK": "Danish (Denmark)", - "nl_NL": "Dutch (Netherlands)", - "en_GB": "English (United Kingdom)", - "en_US": "English (United States)", - "fr_FR": "French (France)", - "de_DE": "German (Germany)", - "ja_JP": "Japanese (Japan)", - "ru_RU": "Russian (Russia)", - "es_MX": "Spanish (Mexico)", - "es_ES": "Spanish (Spain)", - "user": "Other" - }, - "helpMarkDown": "If your language isn't displayed, select 'Other' and enter its locale below, such as en_US." - }, - { - "name": "userDefinedLocale", - "type": "string", - "label": "Other locale", - "groupName": "advanced", - "defaultValue": "", - "required": false, - "visibleRule": "locale = user", - "helpMarkDown": "Enter any two-letter ISO-639 language code along with any two-letter ISO 3166 country code in the format [language]_[country], such as en_US." - }, - { - "name": "testCloudLocation", - "aliases": [ - "testCloudFile" - ], - "type": "filePath", - "label": "test-cloud.exe location", - "groupName": "advanced", - "defaultValue": "**/packages/**/tools/test-cloud.exe", - "required": true, - "helpMarkDown": "The path to test-cloud.exe. Wildcards can be used, in which case the first occurrence of test-cloud.exe is used ([more information](https://go.microsoft.com/fwlink/?linkid=856077))." - }, - { - "name": "optionalArgs", - "type": "string", - "label": "Optional arguments", - "required": false, - "defaultValue": "", - "groupName": "advanced", - "helpMarkDown": "Additional arguments passed to test-cloud.exe." - }, - { - "name": "publishNUnitResults", - "type": "boolean", - "label": "Publish results to Azure Pipelines", - "groupName": "advanced", - "defaultValue": "true", - "helpMarkDown": "When selected, --nunit-xml option will be passed to test-cloud.exe. Results from the NUnit xml file will be published to Azure Pipelines." - } - ], - "instanceNameFormat": "Test $(app) with Xamarin.UITest in Xamarin Test Cloud", - "execution": { - "Node10": { - "target": "xamarintestcloud.js", - "argumentFormat": "" - }, - "Node16": { - "target": "xamarintestcloud.js", - "argumentFormat": "" - }, - "PowerShell": { - "target": "$(currentDirectory)\\XamarinTestCloud.ps1", - "argumentFormat": "", - "workingDirectory": "$(currentDirectory)", - "platforms": [ - "windows" - ] - } + "PowerShell": { + "target": "$(currentDirectory)\\XamarinTestCloud.ps1", + "argumentFormat": "", + "workingDirectory": "$(currentDirectory)", + "platforms": [ + "windows" + ] } + }, + "messages": { + "DeprecatedTask": "The XamarinTestCloud@1 (Xamarin Test Cloud) task has been deprecated since January 11, 2018 and will soon be retired. Use the AppCenterDistribute@3 task instead." + } } \ No newline at end of file diff --git a/Tasks/XamarinTestCloudV1/task.loc.json b/Tasks/XamarinTestCloudV1/task.loc.json index 49cfe627a910..3d5c25ad59ae 100644 --- a/Tasks/XamarinTestCloudV1/task.loc.json +++ b/Tasks/XamarinTestCloudV1/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, - "Patch": 2 + "Minor": 235, + "Patch": 0 }, "demands": [], "minimumAgentVersion": "1.83.0", @@ -196,5 +196,8 @@ "windows" ] } + }, + "messages": { + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" } } \ No newline at end of file diff --git a/Tasks/XamarinTestCloudV1/xamarintestcloud.ts b/Tasks/XamarinTestCloudV1/xamarintestcloud.ts index 1b0d73d3b87f..41c0d4f7af0d 100644 --- a/Tasks/XamarinTestCloudV1/xamarintestcloud.ts +++ b/Tasks/XamarinTestCloudV1/xamarintestcloud.ts @@ -268,3 +268,9 @@ var submitToTestCloud = function (index) { } submitToTestCloud(appFileIndex); + +let shouldFail = tl.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + +if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(tl.loc("DeprecatedTask")); +} \ No newline at end of file diff --git a/_generated/AppCenterDistributeV1.versionmap.txt b/_generated/AppCenterDistributeV1.versionmap.txt index 03c75e2e696e..bf340ca139ef 100644 --- a/_generated/AppCenterDistributeV1.versionmap.txt +++ b/_generated/AppCenterDistributeV1.versionmap.txt @@ -1,2 +1,2 @@ -Default|1.234.0 -Node20_229_7|1.234.1 +Default|1.235.0 +Node20_229_7|1.235.1 diff --git a/_generated/AppCenterDistributeV1_Node20/Strings/resources.resjson/en-US/resources.resjson b/_generated/AppCenterDistributeV1_Node20/Strings/resources.resjson/en-US/resources.resjson index b06ecc2d0491..c946550ca471 100644 --- a/_generated/AppCenterDistributeV1_Node20/Strings/resources.resjson/en-US/resources.resjson +++ b/_generated/AppCenterDistributeV1_Node20/Strings/resources.resjson/en-US/resources.resjson @@ -38,5 +38,6 @@ "loc.messages.CannotFindAnyFile": "Cannot find any file based on %s.", "loc.messages.FoundMultipleFiles": "Found multiple files matching %s.", "loc.messages.FailedToCreateFile": "Failed to create %s with error: %s.", - "loc.messages.FailedToFindFile": "Failed to find %s at %s." + "loc.messages.FailedToFindFile": "Failed to find %s at %s.", + "loc.messages.DeprecatedTask": "The AppCenterDistribute@1 (App Center distribute) task has been deprecated since November 14, 2022 and will soon be retired. Use the AppCenterDistribute@3 task instead." } \ No newline at end of file diff --git a/_generated/AppCenterDistributeV1_Node20/appcenterdistribute.ts b/_generated/AppCenterDistributeV1_Node20/appcenterdistribute.ts index d587a73552f2..6742d8e9a352 100644 --- a/_generated/AppCenterDistributeV1_Node20/appcenterdistribute.ts +++ b/_generated/AppCenterDistributeV1_Node20/appcenterdistribute.ts @@ -558,6 +558,12 @@ async function run() { await commitSymbols(effectiveApiServer, effectiveApiVersion, appSlug, symbolsUploadInfo.symbol_upload_id, apiToken, userAgent); } + let shouldFail = tl.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + + if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(tl.loc("DeprecatedTask")); + } + tl.setResult(tl.TaskResult.Succeeded, tl.loc("Succeeded")); } catch (err) { tl.setResult(tl.TaskResult.Failed, `${err}`); diff --git a/_generated/AppCenterDistributeV1_Node20/task.json b/_generated/AppCenterDistributeV1_Node20/task.json index 1bb5e4e33174..228767bdfa8d 100644 --- a/_generated/AppCenterDistributeV1_Node20/task.json +++ b/_generated/AppCenterDistributeV1_Node20/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 1 }, "minimumAgentVersion": "2.144.0", @@ -205,10 +205,11 @@ "CannotFindAnyFile": "Cannot find any file based on %s.", "FoundMultipleFiles": "Found multiple files matching %s.", "FailedToCreateFile": "Failed to create %s with error: %s.", - "FailedToFindFile": "Failed to find %s at %s." + "FailedToFindFile": "Failed to find %s at %s.", + "DeprecatedTask": "The AppCenterDistribute@1 (App Center distribute) task has been deprecated since November 14, 2022 and will soon be retired. Use the AppCenterDistribute@3 task instead." }, "_buildConfigMapping": { - "Default": "1.234.0", - "Node20_229_7": "1.234.1" + "Default": "1.235.0", + "Node20_229_7": "1.235.1" } } \ No newline at end of file diff --git a/_generated/AppCenterDistributeV1_Node20/task.loc.json b/_generated/AppCenterDistributeV1_Node20/task.loc.json index 94a9a1315fb0..4b88e72ba053 100644 --- a/_generated/AppCenterDistributeV1_Node20/task.loc.json +++ b/_generated/AppCenterDistributeV1_Node20/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 1 }, "minimumAgentVersion": "2.144.0", @@ -205,10 +205,11 @@ "CannotFindAnyFile": "ms-resource:loc.messages.CannotFindAnyFile", "FoundMultipleFiles": "ms-resource:loc.messages.FoundMultipleFiles", "FailedToCreateFile": "ms-resource:loc.messages.FailedToCreateFile", - "FailedToFindFile": "ms-resource:loc.messages.FailedToFindFile" + "FailedToFindFile": "ms-resource:loc.messages.FailedToFindFile", + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" }, "_buildConfigMapping": { - "Default": "1.234.0", - "Node20_229_7": "1.234.1" + "Default": "1.235.0", + "Node20_229_7": "1.235.1" } } \ No newline at end of file diff --git a/_generated/AppCenterDistributeV2.versionmap.txt b/_generated/AppCenterDistributeV2.versionmap.txt index cdfd3eac38e5..5bb6442d61ff 100644 --- a/_generated/AppCenterDistributeV2.versionmap.txt +++ b/_generated/AppCenterDistributeV2.versionmap.txt @@ -1,2 +1,2 @@ -Default|2.234.0 -Node20_229_7|2.234.1 +Default|2.235.0 +Node20_229_7|2.235.1 diff --git a/_generated/AppCenterDistributeV2_Node20/Strings/resources.resjson/en-US/resources.resjson b/_generated/AppCenterDistributeV2_Node20/Strings/resources.resjson/en-US/resources.resjson index 9c3ec1f83437..0d154f652428 100644 --- a/_generated/AppCenterDistributeV2_Node20/Strings/resources.resjson/en-US/resources.resjson +++ b/_generated/AppCenterDistributeV2_Node20/Strings/resources.resjson/en-US/resources.resjson @@ -39,5 +39,6 @@ "loc.messages.CannotFindAnyFile": "Cannot find any file based on %s.", "loc.messages.FoundMultipleFiles": "Found multiple files matching %s.", "loc.messages.FailedToCreateFile": "Failed to create %s with error: %s.", - "loc.messages.FailedToFindFile": "Failed to find %s at %s." + "loc.messages.FailedToFindFile": "Failed to find %s at %s.", + "loc.messages.DeprecatedTask": "The AppCenterDistribute@2 (App Center distribute) task has been deprecated since November 14, 2022 and will soon be retired. Use the AppCenterDistribute@3 task instead." } \ No newline at end of file diff --git a/_generated/AppCenterDistributeV2_Node20/appcenterdistribute.ts b/_generated/AppCenterDistributeV2_Node20/appcenterdistribute.ts index 66415fd7328d..1857f439e3df 100644 --- a/_generated/AppCenterDistributeV2_Node20/appcenterdistribute.ts +++ b/_generated/AppCenterDistributeV2_Node20/appcenterdistribute.ts @@ -547,6 +547,12 @@ async function run() { await commitSymbols(effectiveApiServer, effectiveApiVersion, appSlug, symbolsUploadInfo.symbol_upload_id, apiToken, userAgent); } + let shouldFail = tl.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + + if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(tl.loc("DeprecatedTask")); + } + tl.setResult(tl.TaskResult.Succeeded, tl.loc("Succeeded")); } catch (err) { tl.setResult(tl.TaskResult.Failed, `${err}`); diff --git a/_generated/AppCenterDistributeV2_Node20/task.json b/_generated/AppCenterDistributeV2_Node20/task.json index 3d07a8f0e5c5..3848df20dfe5 100644 --- a/_generated/AppCenterDistributeV2_Node20/task.json +++ b/_generated/AppCenterDistributeV2_Node20/task.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 234, + "Minor": 235, "Patch": 1 }, "minimumAgentVersion": "2.144.0", @@ -207,10 +207,11 @@ "CannotFindAnyFile": "Cannot find any file based on %s.", "FoundMultipleFiles": "Found multiple files matching %s.", "FailedToCreateFile": "Failed to create %s with error: %s.", - "FailedToFindFile": "Failed to find %s at %s." + "FailedToFindFile": "Failed to find %s at %s.", + "DeprecatedTask": "The AppCenterDistribute@2 (App Center distribute) task has been deprecated since November 14, 2022 and will soon be retired. Use the AppCenterDistribute@3 task instead." }, "_buildConfigMapping": { - "Default": "2.234.0", - "Node20_229_7": "2.234.1" + "Default": "2.235.0", + "Node20_229_7": "2.235.1" } } \ No newline at end of file diff --git a/_generated/AppCenterDistributeV2_Node20/task.loc.json b/_generated/AppCenterDistributeV2_Node20/task.loc.json index d4f8bfdfdfcc..72de3386fd19 100644 --- a/_generated/AppCenterDistributeV2_Node20/task.loc.json +++ b/_generated/AppCenterDistributeV2_Node20/task.loc.json @@ -16,7 +16,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 234, + "Minor": 235, "Patch": 1 }, "minimumAgentVersion": "2.144.0", @@ -207,10 +207,11 @@ "CannotFindAnyFile": "ms-resource:loc.messages.CannotFindAnyFile", "FoundMultipleFiles": "ms-resource:loc.messages.FoundMultipleFiles", "FailedToCreateFile": "ms-resource:loc.messages.FailedToCreateFile", - "FailedToFindFile": "ms-resource:loc.messages.FailedToFindFile" + "FailedToFindFile": "ms-resource:loc.messages.FailedToFindFile", + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" }, "_buildConfigMapping": { - "Default": "2.234.0", - "Node20_229_7": "2.234.1" + "Default": "2.235.0", + "Node20_229_7": "2.235.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV2.versionmap.txt b/_generated/AzureFileCopyV2.versionmap.txt index 541cb7e3177c..dfad9fdc1c32 100644 --- a/_generated/AzureFileCopyV2.versionmap.txt +++ b/_generated/AzureFileCopyV2.versionmap.txt @@ -1,2 +1,2 @@ -Default|2.231.2 -Node20_229_2|2.231.4 +Default|2.234.0 +Node20_229_2|2.234.1 diff --git a/_generated/AzureFileCopyV2/AzureFileCopy.ps1 b/_generated/AzureFileCopyV2/AzureFileCopy.ps1 index 6b64ce4a6c72..b69f23805337 100644 --- a/_generated/AzureFileCopyV2/AzureFileCopy.ps1 +++ b/_generated/AzureFileCopyV2/AzureFileCopy.ps1 @@ -3,6 +3,10 @@ param() Trace-VstsEnteringInvocation $MyInvocation +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + # Get inputs for the task $connectedServiceNameSelector = Get-VstsInput -Name ConnectedServiceNameSelector -Require $sourcePath = Get-VstsInput -Name SourcePath -Require @@ -211,7 +215,14 @@ try { } if(-not [string]::IsNullOrEmpty($outputStorageContainerSASToken)) { - $storageContainerSaSToken = New-AzureStorageContainerSASToken -Container $containerName -Context $storageContext -Permission rl -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + if ($featureFlags.retireAzureRM) + { + $storageContainerSaSToken = New-AzStorageContainerSASToken -Name $containerName -Context $storageContext -Permission rl -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + } + else + { + $storageContainerSaSToken = New-AzureStorageContainerSASToken -Container $containerName -Context $storageContext -Permission rl -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + } Write-Host "##vso[task.setvariable variable=$outputStorageContainerSASToken;]$storageContainerSasToken" } @@ -280,4 +291,4 @@ try { } finally { Disconnect-AzureAndClearContext -authScheme $connectionType -ErrorAction SilentlyContinue -} \ No newline at end of file +} diff --git a/_generated/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 b/_generated/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 index 3b9642fcf36c..67408989a140 100644 --- a/_generated/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 +++ b/_generated/AzureFileCopyV2/AzureUtilityGTE1.0.ps1 @@ -1,5 +1,9 @@ # This file implements IAzureUtility for Azure PowerShell version >= 1.0.0 +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageKeyFromRDFE { param([string]$storageAccountName, @@ -24,7 +28,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -50,7 +61,14 @@ function Get-AzureStorageKeyFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage key for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageKeyDetails = Get-AzureRMStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageKeyDetails = Get-AzStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageKeyDetails = Get-AzureRMStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageKey = $storageKeyDetails.Key1 Write-Verbose "[Azure Call]Retrieved storage key successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -66,7 +84,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -102,7 +127,14 @@ function Get-AzureBlobStorageEndpointFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account endpoint for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageAccountInfo = Get-AzStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageAccountEnpoint = $storageAccountInfo.PrimaryEndpoints[0].blob Write-Verbose "[Azure Call]Retrieved storage account endpoint successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -139,7 +171,14 @@ function Get-AzureStorageAccountTypeFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account type for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageAccountInfo = Get-AzStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageAccountType = $storageAccountInfo.AccountType Write-Verbose "[Azure Call]Retrieved storage account type successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -160,9 +199,23 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -178,7 +231,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -265,7 +325,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -348,17 +415,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -367,15 +455,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -401,7 +510,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInHours hours" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -416,7 +532,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -435,7 +558,14 @@ function Get-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $customScriptExtension = Get-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + } + else + { + $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -455,7 +585,14 @@ function Set-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -474,7 +611,14 @@ function Remove-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + if ($featureFlags.retireAzureRM) + { + $response = Remove-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + } + else + { + $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -491,7 +635,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -513,7 +664,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -551,7 +709,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -568,11 +733,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -583,7 +762,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -612,7 +798,15 @@ function Remove-NetworkSecurityRuleConfig foreach($securityGroup in $securityGroups) { Write-Verbose "[Azure Call]Removing the Rule $ruleName" - $result = Remove-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzureRmNetworkSecurityGroup + if ($featureFlags.retireAzureRM) + { + $result = Remove-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzNetworkSecurityGroup + } + else + { + $result = Remove-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzureRmNetworkSecurityGroup + } Write-Verbose "[Azure Call]Removed the Rule $ruleName" } } + diff --git a/_generated/AzureFileCopyV2/AzureUtilityGTE1.1.0.ps1 b/_generated/AzureFileCopyV2/AzureUtilityGTE1.1.0.ps1 index acf2f971551e..b00250086d92 100644 --- a/_generated/AzureFileCopyV2/AzureUtilityGTE1.1.0.ps1 +++ b/_generated/AzureFileCopyV2/AzureUtilityGTE1.1.0.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityGTE1.0.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureRMVMsInResourceGroup { param([string]$resourceGroupName) @@ -11,7 +15,13 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -41,7 +51,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -55,3 +72,4 @@ function Set-AzureMachineCustomScriptExtension return $result } + diff --git a/_generated/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 b/_generated/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 index dcdd33a0c368..a8f7f9e869a7 100644 --- a/_generated/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 +++ b/_generated/AzureFileCopyV2/AzureUtilityLTE9.8.ps1 @@ -1,5 +1,9 @@ # This file implements IAzureUtility for Azure PowerShell version <= 0.9.8 +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageKeyFromRDFE { param([string]$storageAccountName, @@ -80,7 +84,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -182,11 +193,25 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -202,7 +227,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -378,7 +410,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInHours hours" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -600,3 +639,4 @@ function Remove-NetworkSecurityRuleConfig Write-Verbose "[Azure Call]Removed the Rule $ruleName" } } + diff --git a/_generated/AzureFileCopyV2/task.json b/_generated/AzureFileCopyV2/task.json index 9a7e83d281b2..70af0eb3d644 100644 --- a/_generated/AzureFileCopyV2/task.json +++ b/_generated/AzureFileCopyV2/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" @@ -374,7 +374,7 @@ "ExpiredServicePrincipal": "Could not fetch access token for Azure. Verify if the Service Principal used is valid and not expired." }, "_buildConfigMapping": { - "Default": "2.231.2", - "Node20_229_2": "2.231.4" + "Default": "2.234.0", + "Node20_229_2": "2.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV2/task.loc.json b/_generated/AzureFileCopyV2/task.loc.json index 522bd397e303..a3c854191873 100644 --- a/_generated/AzureFileCopyV2/task.loc.json +++ b/_generated/AzureFileCopyV2/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" @@ -374,7 +374,7 @@ "ExpiredServicePrincipal": "ms-resource:loc.messages.ExpiredServicePrincipal" }, "_buildConfigMapping": { - "Default": "2.231.2", - "Node20_229_2": "2.231.4" + "Default": "2.234.0", + "Node20_229_2": "2.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV2_Node20/AzureFileCopy.ps1 b/_generated/AzureFileCopyV2_Node20/AzureFileCopy.ps1 index 6b64ce4a6c72..b69f23805337 100644 --- a/_generated/AzureFileCopyV2_Node20/AzureFileCopy.ps1 +++ b/_generated/AzureFileCopyV2_Node20/AzureFileCopy.ps1 @@ -3,6 +3,10 @@ param() Trace-VstsEnteringInvocation $MyInvocation +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + # Get inputs for the task $connectedServiceNameSelector = Get-VstsInput -Name ConnectedServiceNameSelector -Require $sourcePath = Get-VstsInput -Name SourcePath -Require @@ -211,7 +215,14 @@ try { } if(-not [string]::IsNullOrEmpty($outputStorageContainerSASToken)) { - $storageContainerSaSToken = New-AzureStorageContainerSASToken -Container $containerName -Context $storageContext -Permission rl -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + if ($featureFlags.retireAzureRM) + { + $storageContainerSaSToken = New-AzStorageContainerSASToken -Name $containerName -Context $storageContext -Permission rl -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + } + else + { + $storageContainerSaSToken = New-AzureStorageContainerSASToken -Container $containerName -Context $storageContext -Permission rl -ExpiryTime (Get-Date).AddHours($defaultSasTokenTimeOutInHours) + } Write-Host "##vso[task.setvariable variable=$outputStorageContainerSASToken;]$storageContainerSasToken" } @@ -280,4 +291,4 @@ try { } finally { Disconnect-AzureAndClearContext -authScheme $connectionType -ErrorAction SilentlyContinue -} \ No newline at end of file +} diff --git a/_generated/AzureFileCopyV2_Node20/AzureUtilityGTE1.0.ps1 b/_generated/AzureFileCopyV2_Node20/AzureUtilityGTE1.0.ps1 index 3b9642fcf36c..67408989a140 100644 --- a/_generated/AzureFileCopyV2_Node20/AzureUtilityGTE1.0.ps1 +++ b/_generated/AzureFileCopyV2_Node20/AzureUtilityGTE1.0.ps1 @@ -1,5 +1,9 @@ # This file implements IAzureUtility for Azure PowerShell version >= 1.0.0 +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageKeyFromRDFE { param([string]$storageAccountName, @@ -24,7 +28,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -50,7 +61,14 @@ function Get-AzureStorageKeyFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage key for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageKeyDetails = Get-AzureRMStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageKeyDetails = Get-AzStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageKeyDetails = Get-AzureRMStorageAccountKey -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageKey = $storageKeyDetails.Key1 Write-Verbose "[Azure Call]Retrieved storage key successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -66,7 +84,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -102,7 +127,14 @@ function Get-AzureBlobStorageEndpointFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account endpoint for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageAccountInfo = Get-AzStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageAccountEnpoint = $storageAccountInfo.PrimaryEndpoints[0].blob Write-Verbose "[Azure Call]Retrieved storage account endpoint successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -139,7 +171,14 @@ function Get-AzureStorageAccountTypeFromARM $azureResourceGroupName = Get-AzureStorageAccountResourceGroupName -storageAccountName $storageAccountName Write-Verbose "[Azure Call]Retrieving storage account type for the storage account: $storageAccount in resource group: $azureResourceGroupName" - $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageAccountInfo = Get-AzStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } + else + { + $storageAccountInfo = Get-AzureRMStorageAccount -ResourceGroupName $azureResourceGroupName -Name $storageAccountName -ErrorAction Stop + } $storageAccountType = $storageAccountInfo.AccountType Write-Verbose "[Azure Call]Retrieved storage account type successfully for the storage account: $storageAccount in resource group: $azureResourceGroupName" @@ -160,9 +199,23 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -178,7 +231,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -265,7 +325,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -348,17 +415,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -367,15 +455,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -401,7 +510,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInHours hours" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -416,7 +532,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -435,7 +558,14 @@ function Get-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName)) { Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtension" -ArgumentList $name, $vmName) - $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $customScriptExtension = Get-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + } + else + { + $customScriptExtension = Get-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -455,7 +585,14 @@ function Set-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -474,7 +611,14 @@ function Remove-AzureMachineCustomScriptExtension if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtension" -ArgumentList $name, $vmName) - $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + if ($featureFlags.retireAzureRM) + { + $response = Remove-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + } + else + { + $response = Remove-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -Force -ErrorAction SilentlyContinue -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_RemoveCustomScriptExtensionComplete" -ArgumentList $name, $vmName) } @@ -491,7 +635,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -513,7 +664,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -551,7 +709,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -568,11 +733,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -583,7 +762,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -612,7 +798,15 @@ function Remove-NetworkSecurityRuleConfig foreach($securityGroup in $securityGroups) { Write-Verbose "[Azure Call]Removing the Rule $ruleName" - $result = Remove-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzureRmNetworkSecurityGroup + if ($featureFlags.retireAzureRM) + { + $result = Remove-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzNetworkSecurityGroup + } + else + { + $result = Remove-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName | Set-AzureRmNetworkSecurityGroup + } Write-Verbose "[Azure Call]Removed the Rule $ruleName" } } + diff --git a/_generated/AzureFileCopyV2_Node20/AzureUtilityGTE1.1.0.ps1 b/_generated/AzureFileCopyV2_Node20/AzureUtilityGTE1.1.0.ps1 index acf2f971551e..b00250086d92 100644 --- a/_generated/AzureFileCopyV2_Node20/AzureUtilityGTE1.1.0.ps1 +++ b/_generated/AzureFileCopyV2_Node20/AzureUtilityGTE1.1.0.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityGTE1.0.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureRMVMsInResourceGroup { param([string]$resourceGroupName) @@ -11,7 +15,13 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -41,7 +51,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -55,3 +72,4 @@ function Set-AzureMachineCustomScriptExtension return $result } + diff --git a/_generated/AzureFileCopyV2_Node20/AzureUtilityLTE9.8.ps1 b/_generated/AzureFileCopyV2_Node20/AzureUtilityLTE9.8.ps1 index dcdd33a0c368..a8f7f9e869a7 100644 --- a/_generated/AzureFileCopyV2_Node20/AzureUtilityLTE9.8.ps1 +++ b/_generated/AzureFileCopyV2_Node20/AzureUtilityLTE9.8.ps1 @@ -1,5 +1,9 @@ # This file implements IAzureUtility for Azure PowerShell version <= 0.9.8 +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageKeyFromRDFE { param([string]$storageAccountName, @@ -80,7 +84,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -182,11 +193,25 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -202,7 +227,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -378,7 +410,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInHours hours" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddHours($tokenTimeOutInHours) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -600,3 +639,4 @@ function Remove-NetworkSecurityRuleConfig Write-Verbose "[Azure Call]Removed the Rule $ruleName" } } + diff --git a/_generated/AzureFileCopyV2_Node20/task.json b/_generated/AzureFileCopyV2_Node20/task.json index 5d82b3a5f230..b3eb48c2ce06 100644 --- a/_generated/AzureFileCopyV2_Node20/task.json +++ b/_generated/AzureFileCopyV2_Node20/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 231, - "Patch": 4 + "Minor": 234, + "Patch": 1 }, "demands": [ "azureps" @@ -378,7 +378,7 @@ "ExpiredServicePrincipal": "Could not fetch access token for Azure. Verify if the Service Principal used is valid and not expired." }, "_buildConfigMapping": { - "Default": "2.231.2", - "Node20_229_2": "2.231.4" + "Default": "2.234.0", + "Node20_229_2": "2.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV2_Node20/task.loc.json b/_generated/AzureFileCopyV2_Node20/task.loc.json index 98f70a0e293c..07d168311946 100644 --- a/_generated/AzureFileCopyV2_Node20/task.loc.json +++ b/_generated/AzureFileCopyV2_Node20/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 231, - "Patch": 4 + "Minor": 234, + "Patch": 1 }, "demands": [ "azureps" @@ -378,7 +378,7 @@ "ExpiredServicePrincipal": "ms-resource:loc.messages.ExpiredServicePrincipal" }, "_buildConfigMapping": { - "Default": "2.231.2", - "Node20_229_2": "2.231.4" + "Default": "2.234.0", + "Node20_229_2": "2.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV3.versionmap.txt b/_generated/AzureFileCopyV3.versionmap.txt index 9c8d63647e05..997601b91b81 100644 --- a/_generated/AzureFileCopyV3.versionmap.txt +++ b/_generated/AzureFileCopyV3.versionmap.txt @@ -1,2 +1,2 @@ -Default|3.231.2 -Node20_229_2|3.231.4 +Default|3.234.0 +Node20_229_2|3.234.1 diff --git a/_generated/AzureFileCopyV3/AzureUtilityARM.ps1 b/_generated/AzureFileCopyV3/AzureUtilityARM.ps1 index 9ed07921a74d..f89fefb0776d 100644 --- a/_generated/AzureFileCopyV3/AzureUtilityARM.ps1 +++ b/_generated/AzureFileCopyV3/AzureUtilityARM.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityRest.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageAccountResourceGroupName { param([string]$storageAccountName) @@ -10,7 +14,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -33,7 +44,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -53,9 +71,25 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop - } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + } + else + { + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -71,7 +105,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -85,7 +126,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -112,17 +160,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -131,15 +200,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -165,7 +255,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInMinutes minutes" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -180,7 +277,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -201,7 +305,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -224,7 +335,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -246,7 +364,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -284,7 +409,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -301,11 +433,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -316,7 +462,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -335,3 +488,4 @@ function Add-NetworkSecurityRuleConfig } } } + diff --git a/_generated/AzureFileCopyV3/task.json b/_generated/AzureFileCopyV3/task.json index 922d33fe6e13..03cb728ce759 100644 --- a/_generated/AzureFileCopyV3/task.json +++ b/_generated/AzureFileCopyV3/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" @@ -313,7 +313,7 @@ "ExpiredServicePrincipal": "Could not fetch access token for Azure. Verify if the Service Principal used is valid and not expired." }, "_buildConfigMapping": { - "Default": "3.231.2", - "Node20_229_2": "3.231.4" + "Default": "3.234.0", + "Node20_229_2": "3.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV3/task.loc.json b/_generated/AzureFileCopyV3/task.loc.json index b2bf7fdf4771..0b4956a45e41 100644 --- a/_generated/AzureFileCopyV3/task.loc.json +++ b/_generated/AzureFileCopyV3/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" @@ -313,7 +313,7 @@ "ExpiredServicePrincipal": "ms-resource:loc.messages.ExpiredServicePrincipal" }, "_buildConfigMapping": { - "Default": "3.231.2", - "Node20_229_2": "3.231.4" + "Default": "3.234.0", + "Node20_229_2": "3.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV3_Node20/AzureUtilityARM.ps1 b/_generated/AzureFileCopyV3_Node20/AzureUtilityARM.ps1 index 9ed07921a74d..f89fefb0776d 100644 --- a/_generated/AzureFileCopyV3_Node20/AzureUtilityARM.ps1 +++ b/_generated/AzureFileCopyV3_Node20/AzureUtilityARM.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityRest.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageAccountResourceGroupName { param([string]$storageAccountName) @@ -10,7 +14,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmResource -ErrorAction Stop | Where-Object { ($_.ResourceType -eq $ARMStorageAccountResourceType) -and ($_.Name -eq $storageAccountName)} + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -33,7 +44,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -53,9 +71,25 @@ function Create-AzureContainer Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" if ($isPremiumStorage) { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop - } else { - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + } + else + { + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Container -ErrorAction Stop + } } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } @@ -71,7 +105,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -85,7 +126,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -112,17 +160,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -131,15 +200,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -165,7 +255,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInMinutes minutes" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -180,7 +277,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -201,7 +305,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -224,7 +335,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -246,7 +364,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -284,7 +409,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -301,11 +433,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -316,7 +462,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -335,3 +488,4 @@ function Add-NetworkSecurityRuleConfig } } } + diff --git a/_generated/AzureFileCopyV3_Node20/task.json b/_generated/AzureFileCopyV3_Node20/task.json index 1e5c76f794c3..e4e5944944a5 100644 --- a/_generated/AzureFileCopyV3_Node20/task.json +++ b/_generated/AzureFileCopyV3_Node20/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 231, - "Patch": 4 + "Minor": 234, + "Patch": 1 }, "demands": [ "azureps" @@ -317,7 +317,7 @@ "ExpiredServicePrincipal": "Could not fetch access token for Azure. Verify if the Service Principal used is valid and not expired." }, "_buildConfigMapping": { - "Default": "3.231.2", - "Node20_229_2": "3.231.4" + "Default": "3.234.0", + "Node20_229_2": "3.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV3_Node20/task.loc.json b/_generated/AzureFileCopyV3_Node20/task.loc.json index 23a22d208bda..36ea580d2c7c 100644 --- a/_generated/AzureFileCopyV3_Node20/task.loc.json +++ b/_generated/AzureFileCopyV3_Node20/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 3, - "Minor": 231, - "Patch": 4 + "Minor": 234, + "Patch": 1 }, "demands": [ "azureps" @@ -317,7 +317,7 @@ "ExpiredServicePrincipal": "ms-resource:loc.messages.ExpiredServicePrincipal" }, "_buildConfigMapping": { - "Default": "3.231.2", - "Node20_229_2": "3.231.4" + "Default": "3.234.0", + "Node20_229_2": "3.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV4.versionmap.txt b/_generated/AzureFileCopyV4.versionmap.txt index de56ed7e38ca..362f1b910d7e 100644 --- a/_generated/AzureFileCopyV4.versionmap.txt +++ b/_generated/AzureFileCopyV4.versionmap.txt @@ -1,2 +1,2 @@ -Default|4.231.2 -Node20_229_2|4.231.4 +Default|4.234.0 +Node20_229_2|4.234.1 diff --git a/_generated/AzureFileCopyV4/AzureUtilityARM.ps1 b/_generated/AzureFileCopyV4/AzureUtilityARM.ps1 index e31f5c2bfd6d..4313603a7bbf 100644 --- a/_generated/AzureFileCopyV4/AzureUtilityARM.ps1 +++ b/_generated/AzureFileCopyV4/AzureUtilityARM.ps1 @@ -10,7 +10,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -33,7 +40,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -50,7 +64,14 @@ function Create-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } } @@ -69,7 +90,14 @@ function Get-AzureContainer Write-Verbose "[Azure Call]Getting container: $containerName in storage account: $storageAccountName" try { - $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = Get-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } catch { @@ -90,7 +118,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -104,7 +139,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -131,17 +173,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -150,15 +213,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -184,7 +268,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInMinutes minutes" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -199,7 +290,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -220,7 +318,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -243,7 +348,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -265,7 +377,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -303,7 +422,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -320,11 +446,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -335,7 +475,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -354,3 +501,4 @@ function Add-NetworkSecurityRuleConfig } } } + diff --git a/_generated/AzureFileCopyV4/task.json b/_generated/AzureFileCopyV4/task.json index 842cd4ba305b..701be10f27d7 100644 --- a/_generated/AzureFileCopyV4/task.json +++ b/_generated/AzureFileCopyV4/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" @@ -301,7 +301,7 @@ "ServicePrincipalError": "There was an error with the service principal used for the deployment." }, "_buildConfigMapping": { - "Default": "4.231.2", - "Node20_229_2": "4.231.4" + "Default": "4.234.0", + "Node20_229_2": "4.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV4/task.loc.json b/_generated/AzureFileCopyV4/task.loc.json index 6c0b0432c6d2..9a2519d52649 100644 --- a/_generated/AzureFileCopyV4/task.loc.json +++ b/_generated/AzureFileCopyV4/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" @@ -301,7 +301,7 @@ "ServicePrincipalError": "ms-resource:loc.messages.ServicePrincipalError" }, "_buildConfigMapping": { - "Default": "4.231.2", - "Node20_229_2": "4.231.4" + "Default": "4.234.0", + "Node20_229_2": "4.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV4_Node20/AzureUtilityARM.ps1 b/_generated/AzureFileCopyV4_Node20/AzureUtilityARM.ps1 index e31f5c2bfd6d..4313603a7bbf 100644 --- a/_generated/AzureFileCopyV4_Node20/AzureUtilityARM.ps1 +++ b/_generated/AzureFileCopyV4_Node20/AzureUtilityARM.ps1 @@ -10,7 +10,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -33,7 +40,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -50,7 +64,14 @@ function Create-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } } @@ -69,7 +90,14 @@ function Get-AzureContainer Write-Verbose "[Azure Call]Getting container: $containerName in storage account: $storageAccountName" try { - $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = Get-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } catch { @@ -90,7 +118,14 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -104,7 +139,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -131,17 +173,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -150,15 +213,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -184,7 +268,14 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInMinutes minutes" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -199,7 +290,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -220,7 +318,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -243,7 +348,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -265,7 +377,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -303,7 +422,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -320,11 +446,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -335,7 +475,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -354,3 +501,4 @@ function Add-NetworkSecurityRuleConfig } } } + diff --git a/_generated/AzureFileCopyV4_Node20/task.json b/_generated/AzureFileCopyV4_Node20/task.json index e121bdf00adf..9970abf53e84 100644 --- a/_generated/AzureFileCopyV4_Node20/task.json +++ b/_generated/AzureFileCopyV4_Node20/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, - "Patch": 4 + "Minor": 234, + "Patch": 1 }, "demands": [ "azureps" @@ -305,7 +305,7 @@ "ServicePrincipalError": "There was an error with the service principal used for the deployment." }, "_buildConfigMapping": { - "Default": "4.231.2", - "Node20_229_2": "4.231.4" + "Default": "4.234.0", + "Node20_229_2": "4.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV4_Node20/task.loc.json b/_generated/AzureFileCopyV4_Node20/task.loc.json index 734c3af92ea7..656130296853 100644 --- a/_generated/AzureFileCopyV4_Node20/task.loc.json +++ b/_generated/AzureFileCopyV4_Node20/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, - "Patch": 4 + "Minor": 234, + "Patch": 1 }, "demands": [ "azureps" @@ -305,7 +305,7 @@ "ServicePrincipalError": "ms-resource:loc.messages.ServicePrincipalError" }, "_buildConfigMapping": { - "Default": "4.231.2", - "Node20_229_2": "4.231.4" + "Default": "4.234.0", + "Node20_229_2": "4.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV5.versionmap.txt b/_generated/AzureFileCopyV5.versionmap.txt index 512e00f0a058..093b5dc77f7a 100644 --- a/_generated/AzureFileCopyV5.versionmap.txt +++ b/_generated/AzureFileCopyV5.versionmap.txt @@ -1,2 +1,2 @@ -Default|5.231.2 -Node20_229_2|5.231.4 +Default|5.234.0 +Node20_229_2|5.234.1 diff --git a/_generated/AzureFileCopyV5/AzureUtilityARM.ps1 b/_generated/AzureFileCopyV5/AzureUtilityARM.ps1 index e31f5c2bfd6d..bc0b524ddd79 100644 --- a/_generated/AzureFileCopyV5/AzureUtilityARM.ps1 +++ b/_generated/AzureFileCopyV5/AzureUtilityARM.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityRest.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageAccountResourceGroupName { param([string]$storageAccountName) @@ -10,7 +14,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -33,7 +44,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -50,7 +68,14 @@ function Create-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } } @@ -69,7 +94,14 @@ function Get-AzureContainer Write-Verbose "[Azure Call]Getting container: $containerName in storage account: $storageAccountName" try { - $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = Get-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } catch { @@ -90,7 +122,15 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -104,7 +144,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -131,17 +178,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -150,15 +218,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -184,7 +273,15 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInMinutes minutes" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -199,7 +296,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -220,7 +324,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -243,7 +354,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -265,7 +383,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -303,7 +428,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -320,11 +452,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -335,7 +481,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -354,3 +507,4 @@ function Add-NetworkSecurityRuleConfig } } } + diff --git a/_generated/AzureFileCopyV5/task.json b/_generated/AzureFileCopyV5/task.json index 558990b9e3b5..b0936d5efced 100644 --- a/_generated/AzureFileCopyV5/task.json +++ b/_generated/AzureFileCopyV5/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" @@ -301,7 +301,7 @@ "AzModuleNotFound": "Could not find the modules: 'Az.Accounts'. If the module was recently installed, retry after restarting the Azure Pipelines task agent." }, "_buildConfigMapping": { - "Default": "5.231.2", - "Node20_229_2": "5.231.4" + "Default": "5.234.0", + "Node20_229_2": "5.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV5/task.loc.json b/_generated/AzureFileCopyV5/task.loc.json index cbebf08b3294..8a0d2d93ffda 100644 --- a/_generated/AzureFileCopyV5/task.loc.json +++ b/_generated/AzureFileCopyV5/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 0 }, "demands": [ "azureps" @@ -301,7 +301,7 @@ "AzModuleNotFound": "ms-resource:loc.messages.AzModuleNotFound" }, "_buildConfigMapping": { - "Default": "5.231.2", - "Node20_229_2": "5.231.4" + "Default": "5.234.0", + "Node20_229_2": "5.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV5_Node20/AzureUtilityARM.ps1 b/_generated/AzureFileCopyV5_Node20/AzureUtilityARM.ps1 index e31f5c2bfd6d..bc0b524ddd79 100644 --- a/_generated/AzureFileCopyV5_Node20/AzureUtilityARM.ps1 +++ b/_generated/AzureFileCopyV5_Node20/AzureUtilityARM.ps1 @@ -2,6 +2,10 @@ . "$PSScriptRoot/AzureUtilityRest.ps1" +$featureFlags = @{ + retireAzureRM = [System.Convert]::ToBoolean($env:RETIRE_AZURERM_POWERSHELL_MODULE) +} + function Get-AzureStorageAccountResourceGroupName { param([string]$storageAccountName) @@ -10,7 +14,14 @@ function Get-AzureStorageAccountResourceGroupName if (-not [string]::IsNullOrEmpty($storageAccountName)) { Write-Verbose "[Azure Call]Getting resource details for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" - $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + if ($featureFlags.retireAzureRM) + { + $azureStorageAccountResourceDetails = Get-AzStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } + else + { + $azureStorageAccountResourceDetails = Get-AzureRmStorageAccount -ErrorAction Stop | Where-Object { $_.StorageAccountName -eq $storageAccountName } + } Write-Verbose "[Azure Call]Retrieved resource details successfully for azure storage account resource: $storageAccountName with resource type: $ARMStorageAccountResourceType" $azureResourceGroupName = $azureStorageAccountResourceDetails.ResourceGroupName @@ -33,7 +44,14 @@ function Create-AzureStorageContext if(-not [string]::IsNullOrEmpty($storageAccountName) -and -not [string]::IsNullOrEmpty($storageAccountKey)) { Write-Verbose "[Azure Call]Creating AzureStorageContext for storage account: $storageAccountName" - $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } + else + { + $storageContext = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey -ErrorAction Stop + } Write-Verbose "[Azure Call]Created AzureStorageContext for storage account: $storageAccountName" return $storageContext @@ -50,7 +68,14 @@ function Create-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Creating container: $containerName in storage account: $storageAccountName" - $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = New-AzStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } + else + { + $container = New-AzureStorageContainer -Name $containerName -Context $storageContext -Permission Off -ErrorAction Stop + } Write-Verbose "[Azure Call]Created container: $containerName successfully in storage account: $storageAccountName" } } @@ -69,7 +94,14 @@ function Get-AzureContainer Write-Verbose "[Azure Call]Getting container: $containerName in storage account: $storageAccountName" try { - $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + if ($featureFlags.retireAzureRM) + { + $container = Get-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } + else + { + $container = Get-AzureStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop + } } catch { @@ -90,7 +122,15 @@ function Remove-AzureContainer $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Deleting container: $containerName in storage account: $storageAccountName" - Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + if ($featureFlags.retireAzureRM) + { + Remove-AzStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + else + { + Remove-AzureStorageContainer -Name $containerName -Context $storageContext -Force -ErrorAction SilentlyContinue + } + Write-Verbose "[Azure Call]Deleted container: $containerName in storage account: $storageAccountName" } } @@ -104,7 +144,14 @@ function Get-AzureRMVMsInResourceGroup try { Write-Verbose "[Azure Call]Getting resource group:$resourceGroupName RM virtual machines type resources" - $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $azureRMVMResources = Get-AzVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $azureRMVMResources = Get-AzureRMVM -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Count of resource group:$resourceGroupName RM virtual machines type resource is $($azureRMVMResources.Count)" return $azureRMVMResources @@ -131,17 +178,38 @@ function Get-AzureRMResourceGroupResourcesDetails if(-not [string]::IsNullOrEmpty($resourceGroupName) -and $azureRMVMResources) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName" - $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $networkInterfaceResources = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $networkInterfaceResources = Get-AzureRMNetworkInterface -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" $azureRGResourcesDetails.Add("networkInterfaceResources", $networkInterfaceResources) Write-Verbose "[Azure Call]Getting public IP Addresses in resource group $resourceGroupName" - $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $publicIPAddressResources = Get-AzPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $publicIPAddressResources = Get-AzureRMPublicIpAddress -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got public IP Addresses in resource group $resourceGroupName" $azureRGResourcesDetails.Add("publicIPAddressResources", $publicIPAddressResources) Write-Verbose "[Azure Call]Getting load balancers in resource group $resourceGroupName" - $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $lbGroup = Get-AzLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $lbGroup = Get-AzureRMLoadBalancer -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancers in resource group $resourceGroupName" if($lbGroup) @@ -150,15 +218,36 @@ function Get-AzureRMResourceGroupResourcesDetails { $lbDetails = @{} Write-Verbose "[Azure Call]Getting load balancer in resource group $resourceGroupName" - $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $loadBalancer = Get-AzLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } + else + { + $loadBalancer = Get-AzureRMLoadBalancer -Name $lb.Name -ResourceGroupName $resourceGroupName -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got load balancer in resource group $resourceGroupName" Write-Verbose "[Azure Call]Getting LoadBalancer Frontend Ip Config" - $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $frontEndIPConfigs = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $frontEndIPConfigs = Get-AzureRMLoadBalancerFrontendIpConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got LoadBalancer Frontend Ip Config" Write-Verbose "[Azure Call]Getting Azure LoadBalancer Inbound NatRule Config" - $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $inboundRules = Get-AzLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } + else + { + $inboundRules = Get-AzureRMLoadBalancerInboundNatRuleConfig -LoadBalancer $loadBalancer -ErrorAction Stop -Verbose + } Write-Verbose "[Azure Call]Got Azure LoadBalancer Inbound NatRule Config" $lbDetails.Add("frontEndIPConfigs", $frontEndIPConfigs) @@ -184,7 +273,15 @@ function Generate-AzureStorageContainerSASToken $storageAccountName = $storageContext.StorageAccountName Write-Verbose "[Azure Call]Generating SasToken for container: $containerName in storage: $storageAccountName with expiry time: $tokenTimeOutInMinutes minutes" - $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + if ($featureFlags.retireAzureRM) + { + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + else + { + $containerSasToken = New-AzureStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl + } + $containerSasToken = New-AzStorageContainerSASToken -Name $containerName -ExpiryTime (Get-Date).AddMinutes($tokenTimeOutInMinutes) -Context $storageContext -Permission rwdl Write-Verbose "[Azure Call]Generated SasToken: $containerSasToken successfully for container: $containerName in storage: $storageAccountName" return $containerSasToken @@ -199,7 +296,14 @@ function Get-AzureMachineStatus if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($name)) { Write-Host (Get-VstsLocString -Key "AFC_GetVMStatus" -ArgumentList $name) - $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $status = Get-AzVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } + else + { + $status = Get-AzureRmVM -ResourceGroupName $resourceGroupName -Name $name -Status -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_GetVMStatusComplete" -ArgumentList $name) } @@ -220,7 +324,14 @@ function Set-AzureMachineCustomScriptExtension { Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtension" -ArgumentList $name, $vmName) Write-Verbose "Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose" - $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + if ($featureFlags.retireAzureRM) + { + $result = Set-AzVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } + else + { + $result = Set-AzureRmVMCustomScriptExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name $name -FileUri $fileUri -Run $run -Argument $argument -Location $location -ErrorAction Stop -Verbose + } Write-Host (Get-VstsLocString -Key "AFC_SetCustomScriptExtensionComplete" -ArgumentList $name, $vmName) if($result.IsSuccessStatusCode -eq $true) { @@ -243,7 +354,14 @@ function Get-NetworkSecurityGroups if(-not [string]::IsNullOrEmpty($resourceGroupName) -and -not [string]::IsNullOrEmpty($vmId)) { Write-Verbose "[Azure Call]Getting network interfaces in resource group $resourceGroupName for vm $vmId" - $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + if ($featureFlags.retireAzureRM) + { + $networkInterfaces = Get-AzNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } + else + { + $networkInterfaces = Get-AzureRmNetworkInterface -ResourceGroupName $resourceGroupName | Where-Object { $_.VirtualMachine.Id -eq $vmId } + } Write-Verbose "[Azure Call]Got network interfaces in resource group $resourceGroupName" if($networkInterfaces) @@ -265,7 +383,14 @@ function Get-NetworkSecurityGroups # Get the network security group object Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $sgResourceGroup" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $sgResourceGroup -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $sgResourceGroup" $securityGroups.Add($securityGroup) @@ -303,7 +428,14 @@ function Add-NetworkSecurityRuleConfig $winRMConfigRule = $null Write-Verbose "[Azure Call]Getting network security rule config $ruleName under security group $securityGroupName" - $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + if ($featureFlags.retireAzureRM) + { + $winRMConfigRule = Get-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } + else + { + $winRMConfigRule = Get-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -EA SilentlyContinue + } Write-Verbose "[Azure Call]Got network security rule config $ruleName under security group $securityGroupName" } catch @@ -320,11 +452,25 @@ function Add-NetworkSecurityRuleConfig try { Write-Verbose "[Azure Call]Adding inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" - $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + if ($featureFlags.retireAzureRM) + { + $securityGroup = Add-AzNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } + else + { + $securityGroup = Add-AzureRmNetworkSecurityRuleConfig -NetworkSecurityGroup $securityGroup -Name $ruleName -Direction Inbound -Access Allow -SourceAddressPrefix '*' -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange $winrmHttpsPort -Protocol * -Priority $rulePriotity + } Write-Verbose "[Azure Call]Added inbound network security rule config $ruleName with priority $rulePriotity for port $winrmHttpsPort under security group $securityGroupName" Write-Verbose "[Azure Call]Setting the azure network security group" - $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + if ($featureFlags.retireAzureRM) + { + $result = Set-AzNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } + else + { + $result = Set-AzureRmNetworkSecurityGroup -NetworkSecurityGroup $securityGroup + } Write-Verbose "[Azure Call]Set the azure network security group" } catch @@ -335,7 +481,14 @@ function Add-NetworkSecurityRuleConfig $rulePriotity = $newPort.ToString() Write-Verbose "[Azure Call]Getting network security group $securityGroupName in resource group $resourceGroupName" - $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + if ($featureFlags.retireAzureRM) + { + $securityGroup = Get-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } + else + { + $securityGroup = Get-AzureRmNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Name $securityGroupName + } Write-Verbose "[Azure Call]Got network security group $securityGroupName in resource group $resourceGroupName" @@ -354,3 +507,4 @@ function Add-NetworkSecurityRuleConfig } } } + diff --git a/_generated/AzureFileCopyV5_Node20/task.json b/_generated/AzureFileCopyV5_Node20/task.json index 2e8e6d5c22cc..a529951c904d 100644 --- a/_generated/AzureFileCopyV5_Node20/task.json +++ b/_generated/AzureFileCopyV5_Node20/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, - "Patch": 4 + "Minor": 234, + "Patch": 1 }, "demands": [ "azureps" @@ -305,7 +305,7 @@ "AzModuleNotFound": "Could not find the modules: 'Az.Accounts'. If the module was recently installed, retry after restarting the Azure Pipelines task agent." }, "_buildConfigMapping": { - "Default": "5.231.2", - "Node20_229_2": "5.231.4" + "Default": "5.234.0", + "Node20_229_2": "5.234.1" } } \ No newline at end of file diff --git a/_generated/AzureFileCopyV5_Node20/task.loc.json b/_generated/AzureFileCopyV5_Node20/task.loc.json index 49ca60f27f4f..a9abd9253ec4 100644 --- a/_generated/AzureFileCopyV5_Node20/task.loc.json +++ b/_generated/AzureFileCopyV5_Node20/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, - "Patch": 4 + "Minor": 234, + "Patch": 1 }, "demands": [ "azureps" @@ -305,7 +305,7 @@ "AzModuleNotFound": "ms-resource:loc.messages.AzModuleNotFound" }, "_buildConfigMapping": { - "Default": "5.231.2", - "Node20_229_2": "5.231.4" + "Default": "5.234.0", + "Node20_229_2": "5.234.1" } } \ No newline at end of file diff --git a/_generated/AzurePowerShellV4.versionmap.txt b/_generated/AzurePowerShellV4.versionmap.txt index cc4d9a107c52..362f1b910d7e 100644 --- a/_generated/AzurePowerShellV4.versionmap.txt +++ b/_generated/AzurePowerShellV4.versionmap.txt @@ -1,2 +1,2 @@ -Default|4.231.0 -Node20_229_2|4.231.2 +Default|4.234.0 +Node20_229_2|4.234.1 diff --git a/_generated/AzurePowerShellV4/AzurePowerShell.ps1 b/_generated/AzurePowerShellV4/AzurePowerShell.ps1 new file mode 100644 index 000000000000..1212b0efaa6e --- /dev/null +++ b/_generated/AzurePowerShellV4/AzurePowerShell.ps1 @@ -0,0 +1,298 @@ +Trace-VstsEnteringInvocation $MyInvocation +Import-VstsLocStrings "$PSScriptRoot\Task.json" + +# Get inputs. +$scriptType = Get-VstsInput -Name ScriptType -Require +$scriptPath = Get-VstsInput -Name ScriptPath +$scriptInline = Get-VstsInput -Name Inline +$scriptArguments = Get-VstsInput -Name ScriptArguments +$__vsts_input_errorActionPreference = Get-VstsInput -Name errorActionPreference +$__vsts_input_failOnStandardError = Get-VstsInput -Name FailOnStandardError -AsBool +$targetAzurePs = Get-VstsInput -Name TargetAzurePs +$customTargetAzurePs = Get-VstsInput -Name CustomTargetAzurePs +$input_pwsh = Get-VstsInput -Name pwsh -AsBool +$input_workingDirectory = Get-VstsInput -Name workingDirectory -Require +$restrictContext = Get-VstsInput -Name RestrictContextToCurrentTask -AsBool +$validateScriptSignature = Get-VstsInput -Name validateScriptSignature -AsBool + +Write-Host "## Validating Inputs" +# Validate the script path and args do not contains new-lines. Otherwise, it will +# break invoking the script via Invoke-Expression. +if ($scriptType -eq "FilePath") { + if ($scriptPath -match '[\r\n]' -or [string]::IsNullOrWhitespace($scriptPath)) { + throw (Get-VstsLocString -Key InvalidScriptPath0 -ArgumentList $scriptPath) + } +} + +if ($scriptArguments -match '[\r\n]') { + throw (Get-VstsLocString -Key InvalidScriptArguments0 -ArgumentList $scriptArguments) +} + +# string constants +$otherVersion = "OtherVersion" +$latestVersion = "LatestVersion" + +if ($targetAzurePs -eq $otherVersion) { + if ($customTargetAzurePs -eq $null) { + throw (Get-VstsLocString -Key InvalidAzurePsVersion $customTargetAzurePs) + } else { + $targetAzurePs = $customTargetAzurePs.Trim() + } +} + +$pattern = "^[0-9]+\.[0-9]+\.[0-9]+$" +$regex = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $pattern + +if ($targetAzurePs -eq $latestVersion) { + $targetAzurePs = "" +} elseif (-not($regex.IsMatch($targetAzurePs))) { + throw (Get-VstsLocString -Key InvalidAzurePsVersion -ArgumentList $targetAzurePs) +} +Write-Host "## Validating Inputs Complete" + +. $PSScriptRoot\TryMakingModuleAvailable.ps1 -targetVersion "$targetAzurePs" -platform Windows + +if ($validateScriptSignature) { + try { + if ($scriptType -ne "InlineScript") { + Write-Host "## Validating Script Signature" + + # Validate script is signed + $scriptSignature = Get-AuthenticodeSignature $scriptPath + if ($scriptSignature.Status -eq "NotSigned") { + throw "Object does not have a digital signature. Please ensure your script is signed and try again." + } + elseif ($scriptSignature.Status -ne "Valid") { + throw "Digital signature of the object did not verify. Please ensure your script is properly signed and try again." + } + + Write-Host "## Validating Script Signature Complete" + } + } + catch + { + $errorMsg = $_.Exception.Message + throw "Unable to validate script signature: $errorMsg" + } +} + +Write-Host "## Initializing Az module" +. "$PSScriptRoot\Utility.ps1" + +$serviceName = Get-VstsInput -Name ConnectedServiceNameARM -Require +$endpoint = Get-VstsEndpoint -Name $serviceName -Require +CleanUp-PSModulePathForHostedAgent +Update-PSModulePathForHostedAgent -targetAzurePs $targetAzurePs +$vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require +$vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + +# troubleshoot link +$troubleshoot = "https://aka.ms/azurepowershelltroubleshooting" +try +{ + # Initialize Azure. + Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_ + $encryptedToken = ConvertTo-SecureString $vstsAccessToken -AsPlainText -Force + Initialize-AzModule -Endpoint $endpoint -connectedServiceNameARM $serviceName ` + -azVersion $targetAzurePs -encryptedToken $encryptedToken -isPSCore $input_pwsh + Write-Host "## Az module initialization Complete" + $success = $true +} +finally { + if (!$success) { + Write-VstsTaskError "Initializing Az module failed: For troubleshooting, refer: $troubleshoot" + } +} + +Write-Host "## Beginning Script Execution" +try { + if ($input_pwsh) + { + # Generate the script contents. + Write-Host (Get-VstsLocString -Key 'GeneratingScript') + $UpdatePSModulePathArgument = $null; + if ($targetAzurePs) + { + $UpdatePSModulePathArgument = "-targetAzurePs $targetAzurePs" + } + + $contents = @() + $contents += "`$ErrorActionPreference = '$__vsts_input_errorActionPreference'" + if ($env:system_debug -eq "true") { + $contents += "`$VerbosePreference = 'continue'" + } + + $contents += ". '$PSScriptRoot\UpdatePSModulePath.ps1' $UpdatePSModulePathArgument" + if ($scriptType -eq "InlineScript") { + $contents += "$scriptInline".Replace("`r`n", "`n").Replace("`n", "`r`n") + } else { + $contents += ". '$("$scriptPath".Replace("'", "''"))' $scriptArguments".Trim() + } + + # Write the script to disk. + $__vstsAzPSScriptPath = [System.IO.Path]::Combine($env:Agent_TempDirectory, ([guid]::NewGuid().ToString() + ".ps1")); + $joinedContents = [System.String]::Join( + ([System.Environment]::NewLine), + $contents) + $null = [System.IO.File]::WriteAllText( + $__vstsAzPSScriptPath, + $joinedContents, + ([System.Text.Encoding]::UTF8)) + + # Prepare the external command values. + # + # Note, use "-Command" instead of "-File". On PowerShell v4 and V3 when using "-File", terminating + # errors do not cause a non-zero exit code. + if ($input_pwsh) { + $powershellPath = Get-Command -Name pwsh.exe -CommandType Application | Select-Object -First 1 -ExpandProperty Path + } else { + $powershellPath = Get-Command -Name powershell.exe -CommandType Application | Select-Object -First 1 -ExpandProperty Path + } + Assert-VstsPath -LiteralPath $powershellPath -PathType 'Leaf' + $arguments = "-NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command `". '$($__vstsAzPSScriptPath.Replace("'", "''"))'`"" + $splat = @{ + 'FileName' = $powershellPath + 'Arguments' = $arguments + 'WorkingDirectory' = $input_workingDirectory + } + + # Switch to "Continue". + $global:ErrorActionPreference = 'Continue' + $failed = $false + + # Run the script. + Write-Host '========================== Starting Command Output ===========================' + if (!$__vsts_input_failOnStandardError) { + Invoke-VstsTool @splat + } + else { + $inError = $false + $errorLines = New-Object System.Text.StringBuilder + Invoke-VstsTool @splat 2>&1 | + ForEach-Object { + if ($_ -is [System.Management.Automation.ErrorRecord]) { + # Buffer the error lines. + $failed = $true + $inError = $true + $null = $errorLines.AppendLine("$($_.Exception.Message)") + + # Write to verbose to mitigate if the process hangs. + Write-Verbose "STDERR: $($_.Exception.Message)" + } else { + # Flush the error buffer. + if ($inError) { + $inError = $false + $message = $errorLines.ToString().Trim() + $null = $errorLines.Clear() + if ($message) { + Write-VstsTaskError -Message $message + } + } + + Write-Host "$_" + } + } + + # Flush the error buffer one last time. + if ($inError) { + $inError = $false + $message = $errorLines.ToString().Trim() + $null = $errorLines.Clear() + if ($message) { + Write-VstsTaskError -Message $message + } + } + } + + # Fail if any errors. + if ($failed) { + Write-VstsSetResult -Result 'Failed' -Message "Error detected" -DoNotThrow + } + } + else + { + # Trace the expression as it will be invoked. + $__vstsAzPSInlineScriptPath = $null + If ($scriptType -eq "InlineScript") { + $scriptArguments = $null + $__vstsAzPSInlineScriptPath = [System.IO.Path]::Combine($env:Agent_TempDirectory, ([guid]::NewGuid().ToString() + ".ps1")); + ($scriptInline | Out-File $__vstsAzPSInlineScriptPath) + $scriptPath = $__vstsAzPSInlineScriptPath + } + + $scriptCommand = "& '$($scriptPath.Replace("'", "''"))' $scriptArguments" + Remove-Variable -Name scriptType + Remove-Variable -Name scriptPath + Remove-Variable -Name scriptInline + Remove-Variable -Name scriptArguments + + # Remove all commands imported from VstsTaskSdk, other than Out-Default. + # Remove all commands imported from VstsAzureHelpers_. + Get-ChildItem -LiteralPath function: | + Where-Object { + ($_.ModuleName -eq 'VstsTaskSdk' -and $_.Name -ne 'Out-Default') -or + ($_.Name -eq 'Invoke-VstsTaskScript') -or + ($_.ModuleName -eq 'VstsAzureHelpers_' ) + } | + Remove-Item + + # For compatibility with the legacy handler implementation, set the error action + # preference to continue. An implication of changing the preference to Continue, + # is that Invoke-VstsTaskScript will no longer handle setting the result to failed. + $global:ErrorActionPreference = 'Continue' + + # Undocumented VstsTaskSdk variable so Verbose/Debug isn't converted to ##vso[task.debug]. + # Otherwise any content the ad-hoc script writes to the verbose pipeline gets dropped by + # the agent when System.Debug is not set. + $global:__vstsNoOverrideVerbose = $true + + # Run the user's script. Redirect the error pipeline to the output pipeline to enable + # a couple goals due to compatibility with the legacy handler implementation: + # 1) STDERR from external commands needs to be converted into error records. Piping + # the redirected error output to an intermediate command before it is piped to + # Out-Default will implicitly perform the conversion. + # 2) The task result needs to be set to failed if an error record is encountered. + # As mentioned above, the requirement to handle this is an implication of changing + # the error action preference. + ([scriptblock]::Create($scriptCommand)) | + ForEach-Object { + Remove-Variable -Name scriptCommand + Write-Host "##[command]$_" + . $_ 2>&1 + } | + ForEach-Object { + if($_ -is [System.Management.Automation.ErrorRecord]) { + if($_.FullyQualifiedErrorId -eq "NativeCommandError" -or $_.FullyQualifiedErrorId -eq "NativeCommandErrorMessage") { + ,$_ + if($__vsts_input_failOnStandardError -eq $true) { + "##vso[task.complete result=Failed]" + } + } + else { + if($__vsts_input_errorActionPreference -eq "continue") { + ,$_ + if($__vsts_input_failOnStandardError -eq $true) { + "##vso[task.complete result=Failed]" + } + } + elseif($__vsts_input_errorActionPreference -eq "stop") { + throw $_ + } + } + } else { + ,$_ + } + } + } + +} +finally { + if ($__vstsAzPSInlineScriptPath -and (Test-Path -LiteralPath $__vstsAzPSInlineScriptPath) ) { + Remove-Item -LiteralPath $__vstsAzPSInlineScriptPath -ErrorAction 'SilentlyContinue' + } + + Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_ + Remove-EndpointSecrets + Disconnect-AzureAndClearContext -restrictContext $restrictContext -ErrorAction SilentlyContinue +} +Write-Host "## Script Execution Complete" \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/InitializeAz.ps1 b/_generated/AzurePowerShellV4/InitializeAz.ps1 new file mode 100644 index 000000000000..076d87fe029c --- /dev/null +++ b/_generated/AzurePowerShellV4/InitializeAz.ps1 @@ -0,0 +1,107 @@ +[CmdletBinding()] +param +( + [String] [Parameter(Mandatory = $true)] + $endpoint, + + [String] [Parameter(Mandatory = $false)] + $targetAzurePs +) + +$endpointObject = ConvertFrom-Json $endpoint +$moduleName = "Az.Accounts" +$environmentName = $endpointObject.environment + +. "$PSScriptRoot/Utility.ps1" +Update-PSModulePathForHostedAgentLinux -targetAzurePs $targetAzurePs + +if($targetAzurePs -eq ""){ + $module = Get-Module -Name $moduleName -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1 +} +else{ + $modules = Get-Module -Name $moduleName -ListAvailable + foreach ($moduleVal in $modules) { + # $moduleVal.Path will have value like /usr/local/share/powershell/Modules/Az.Accounts/1.2.1/Az.Accounts.psd1 + $azModulePath = Split-Path (Split-Path (Split-Path $moduleVal.Path -Parent) -Parent) -Parent + $azModulePath = $azModulePath + "/Az/*" + $azModuleVersion = split-path -path $azModulePath -Leaf -Resolve + if($azModuleVersion -eq $targetAzurePs) { + $module = $moduleVal + break + } + } +} + +if (!$module) { + # Will handle localization later + Write-Verbose "No module found with name: $moduleName" + throw ("Could not find the module Az.Accounts with given version. If the module was recently installed, retry after restarting the Azure Pipelines task agent.") +} + +# Import the module. +Write-Host "##[command]Import-Module -Name $($module.Path) -Global" +$module = Import-Module -Name $module.Path -Global -PassThru -Force + +# Clear context +Write-Host "##[command]Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue" +$null = Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue +Write-Host "##[command]Clear-AzContext -Scope Process" +$null = Clear-AzContext -Scope Process + +$scopeLevel = "Subscription" +if($endpointObject.scopeLevel) { + $scopeLevel = $endpointObject.scopeLevel +} +$processScope = @{ Scope = "Process" } + +function Format-Splat { + [CmdletBinding()] + param([Parameter(Mandatory = $true)][hashtable]$Hashtable) + + # Collect the parameters (names and values) in an array. + $parameters = foreach ($key in $Hashtable.Keys) { + $value = $Hashtable[$key] + # If the value is a bool, format the parameter as a switch (ending with ':'). + if ($value -is [bool]) { "-$($key):" } else { "-$key" } + $value + } + + "$parameters" # String join the array. +} + +if ($endpointObject.scheme -eq 'ServicePrincipal') { + try { + if ($endpointObject.authenticationType -ieq 'SPNKey') { + $psCredential = New-Object System.Management.Automation.PSCredential( + $endpointObject.servicePrincipalClientID, + (ConvertTo-SecureString $endpointObject.servicePrincipalKey -AsPlainText -Force)) + Write-Host "##[command]Connect-AzAccount -ServicePrincipal -Tenant $($endpointObject.tenantId) -Credential $psCredential -Environment $environmentName @processScope" + $null = Connect-AzAccount -ServicePrincipal -Tenant $endpointObject.tenantId ` + -Credential $psCredential ` + -Environment $environmentName @processScope -WarningAction SilentlyContinue + } + else { + # Provide an additional, custom, credentials-related error message. Will handle localization later + throw ("Only SPN credential auth scheme is supported for non windows agent.") + } + } + catch { + # Provide an additional, custom, credentials-related error message. Will handle localization later + Write-Host "Exception is : $($_.Exception.Message)" + throw (New-Object System.Exception("There was an error with the service principal used for the deployment.", $_.Exception)) + } + + if($scopeLevel -eq "Subscription") + { + $SubscriptionId = $endpointObject.subscriptionId + $TenantId = $endpointObject.tenantId + $additional = @{ TenantId = $TenantId } + + Write-Host "##[command] Set-AzContext -SubscriptionId $SubscriptionId $(Format-Splat $additional)" + $null = Set-AzContext -SubscriptionId $SubscriptionId @additional + } +} +else { + # Provide an additional, custom, credentials-related error message. Will handle localization later + throw ("Only SPN credential auth scheme is supported for non windows agent.") +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/de-DE/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/de-DE/resources.resjson new file mode 100644 index 000000000000..44d372e42cb4 --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/de-DE/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[Weitere Informationen zu dieser Aufgabe](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "PowerShell-Skript innerhalb einer Azure-Umgebung ausführen", + "loc.instanceNameFormat": "Azure PowerShell-Skript: $(ScriptType)", + "loc.releaseNotes": "Unterstützung für Az-Modul und plattformübergreifende Agents hinzugefügt.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell-Versionsoptionen", + "loc.group.displayName.advanced": "Erweitert", + "loc.input.label.ConnectedServiceNameARM": "Azure-Abonnement", + "loc.input.help.ConnectedServiceNameARM": "Azure Resource Manager-Abonnement, das vor dem Ausführen von PowerShell konfiguriert wird.", + "loc.input.label.ScriptType": "Skripttyp", + "loc.input.help.ScriptType": "Der Typ des Skripts: Dateipfad oder Inlineskript.", + "loc.input.label.ScriptPath": "Skriptpfad", + "loc.input.help.ScriptPath": "Der Pfad des Skripts. Es muss sich um den vollqualifizierten Pfad oder einen Pfad relativ zum Standardarbeitsverzeichnis handeln.", + "loc.input.label.Inline": "Inlineskript", + "loc.input.help.Inline": "Geben Sie das Skript ein, das ausgeführt werden soll.", + "loc.input.label.ScriptArguments": "Skriptargumente", + "loc.input.help.ScriptArguments": "Zusätzliche Argumente, die an PowerShell übergeben werden sollen. Entweder Ordnungszahl- oder benannte Parameter.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Wählen Sie den Wert der Variablen \"ErrorActionPreference\" für die Skriptausführung.", + "loc.input.label.FailOnStandardError": "Fehler bei Standardfehler.", + "loc.input.help.FailOnStandardError": "Wenn dieser Wert TRUE ist, tritt ein Aufgabenfehler auf, wenn Fehler in die Fehlerpipeline oder Daten in den Standard-Fehlerdatenstrom geschrieben werden.", + "loc.input.label.RestrictContextToCurrentTask": "Kontextbereich auf aktuelle Aufgabe beschränken", + "loc.input.help.RestrictContextToCurrentTask": "Wenn diese Option auf TRUE festgelegt ist, beschränkt diese Aufgabe den Kontextbereich nur auf die aktuelle Aufgabe, und der Kontext steht bei Verwendung des privaten Agents für andere Aufgaben in der Pipeline nicht zur Verfügung.", + "loc.input.label.TargetAzurePs": "Azure PowerShell-Version", + "loc.input.help.TargetAzurePs": "Im Falle gehosteter Agents werden die folgenden Azure PowerShell-Versionen unterstützt: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (gehostete VS2017-Warteschlange).\nWenn Sie die neueste für den Agent verfügbare Version auswählen möchten, wählen Sie \"Neueste installierte Version\" aus.\n\nFür private Agents können Sie mithilfe von \"Version angeben\" die bevorzugte Version von Azure PowerShell festlegen.", + "loc.input.label.CustomTargetAzurePs": "Bevorzugte Azure PowerShell-Version", + "loc.input.help.CustomTargetAzurePs": "Die bevorzugte Azure PowerShell-Version muss einem ordnungsgemäßen semantischen Versionsmuster folgen, z. B. \"1.2.3\". Reguläre Ausdrücke wie 2.\\*,2.3.\\* werden nicht unterstützt. Der gehostete VS2017-Pool unterstützt aktuell die folgenden Az-Modulversionen: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "PowerShell Core verwenden", + "loc.input.help.pwsh": "Sofern TRUE, verwendet die Aufgabe unter Windows anstelle von \"powershell.exe\" die in PATH festgelegte \"pwsh.exe\".", + "loc.input.label.validateScriptSignature": "Skriptsignatur überprüfen", + "loc.input.help.validateScriptSignature": "Wenn dies der Fall ist, überprüft die Aufgabe zunächst, ob das angegebene Skript signiert und gültig ist, bevor es ausgeführt wird.", + "loc.input.label.workingDirectory": "Arbeitsverzeichnis", + "loc.input.help.workingDirectory": "Arbeitsverzeichnis zum Ausführen des Skripts.", + "loc.messages.GeneratingScript": "Skript wird erstellt.", + "loc.messages.JS_FormattedCommand": "Formatierter Befehl: %s", + "loc.messages.InvalidScriptArguments0": "Ungültige Skriptargumente \"{0}\". Zeilenumbrüche sind unzulässig.", + "loc.messages.InvalidScriptPath0": "Ungültiger Skriptpfad \"{0}\". Es wurden ungültige Pfadzeichen angegeben.", + "loc.messages.InvalidAzurePsVersion": "Die angegebene Azure PowerShell-Version \"{0}\" weist nicht das richtige Format auf. Überprüfen Sie das Format. Ein Beispiel für das richtige Format ist etwa 1.0.1.", + "loc.messages.JS_ExitCode": "PowerShell wurde beendet mit dem Code \"%s\".", + "loc.messages.JS_Stderr": "PowerShell hat mindestens eine Zeile in den Standardfehlerstream geschrieben.", + "loc.messages.ExpiredServicePrincipal": "Das Zugriffstoken für Azure konnte nicht abgerufen werden. Stellen Sie sicher, dass der verwendete Dienstprinzipal gültig und nicht abgelaufen ist." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/en-US/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..5357601c22f5 --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Run a PowerShell script within an Azure environment", + "loc.instanceNameFormat": "Azure PowerShell script: $(ScriptType)", + "loc.releaseNotes": "Added support for Az Module and cross platform agents.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell version options", + "loc.group.displayName.advanced": "Advanced", + "loc.input.label.ConnectedServiceNameARM": "Azure Subscription", + "loc.input.help.ConnectedServiceNameARM": "Azure Resource Manager subscription to configure before running PowerShell", + "loc.input.label.ScriptType": "Script Type", + "loc.input.help.ScriptType": "Type of the script: File Path or Inline Script", + "loc.input.label.ScriptPath": "Script Path", + "loc.input.help.ScriptPath": "Path of the script. Should be fully qualified path or relative to the default working directory.", + "loc.input.label.Inline": "Inline Script", + "loc.input.help.Inline": "Enter the script to execute.", + "loc.input.label.ScriptArguments": "Script Arguments", + "loc.input.help.ScriptArguments": "Additional parameters to pass to PowerShell. Can be either ordinal or named parameters.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Select the value of the ErrorActionPreference variable for executing the script.", + "loc.input.label.FailOnStandardError": "Fail on Standard Error", + "loc.input.help.FailOnStandardError": "If this is true, this task will fail if any errors are written to the error pipeline, or if any data is written to the Standard Error stream.", + "loc.input.label.RestrictContextToCurrentTask": "Restrict scope of context to current task", + "loc.input.help.RestrictContextToCurrentTask": "If this is true, this task will restrict the scope of context to current task only and the context will not be available to other tasks in the pipeline when using private agent.", + "loc.input.label.TargetAzurePs": "Azure PowerShell Version", + "loc.input.help.TargetAzurePs": "In case of hosted agents, the supported Azure PowerShell Version is: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (Hosted VS2017 Queue).\nTo pick the latest version available on the agent, select \"Latest installed version\".\n\nFor private agents you can specify preferred version of Azure PowerShell using \"Specify version\"", + "loc.input.label.CustomTargetAzurePs": "Preferred Azure PowerShell Version", + "loc.input.help.CustomTargetAzurePs": "Preferred Azure PowerShell Version needs to be a proper semantic version eg. 1.2.3. Regex like 2.\\*,2.3.\\* is not supported. The Hosted VS2017 Pool currently supports Az module version: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "Use PowerShell Core", + "loc.input.help.pwsh": "If this is true, then on Windows the task will use pwsh.exe from your PATH instead of powershell.exe.", + "loc.input.label.validateScriptSignature": "Validate script signature", + "loc.input.help.validateScriptSignature": "If this is true, then the task will first check to make sure specified script is signed and valid before executing it.", + "loc.input.label.workingDirectory": "Working Directory", + "loc.input.help.workingDirectory": "Working directory where the script is run.", + "loc.messages.GeneratingScript": "Generating script.", + "loc.messages.JS_FormattedCommand": "Formatted command: %s", + "loc.messages.InvalidScriptArguments0": "Invalid script arguments '{0}'. Line breaks are not allowed.", + "loc.messages.InvalidScriptPath0": "Invalid script path '{0}'. Invalid path characters specified.", + "loc.messages.InvalidAzurePsVersion": "The Azure PowerShell version '{0}' specified is not in the correct format. Please check the format. An example of correct format is 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell exited with code '%s'.", + "loc.messages.JS_Stderr": "PowerShell wrote one or more lines to the standard error stream.", + "loc.messages.ExpiredServicePrincipal": "Could not fetch access token for Azure. Verify if the Service Principal used is valid and not expired." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/es-ES/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/es-ES/resources.resjson new file mode 100644 index 000000000000..9f596d3fdf27 --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/es-ES/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[Obtener más información acerca de esta tarea](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Ejecutar un script de PowerShell en un entorno de Azure", + "loc.instanceNameFormat": "Script de Azure PowerShell: $(ScriptType)", + "loc.releaseNotes": "Se ha agregado compatibilidad con el módulo Az y los agentes multiplataforma.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Opciones de versión de Azure PowerShell", + "loc.group.displayName.advanced": "Avanzado", + "loc.input.label.ConnectedServiceNameARM": "Suscripción a Azure", + "loc.input.help.ConnectedServiceNameARM": "Suscripción de Azure Resource Manager para configurar antes de ejecutar PowerShell", + "loc.input.label.ScriptType": "Tipo de script", + "loc.input.help.ScriptType": "Tipo del script: ruta de acceso del archivo o script en línea", + "loc.input.label.ScriptPath": "Ruta de acceso del script", + "loc.input.help.ScriptPath": "Ruta de acceso del script. Debe ser una ruta de acceso completa o relativa al directorio de trabajo predeterminado.", + "loc.input.label.Inline": "Script alineado", + "loc.input.help.Inline": "Escriba el script que se va a ejecutar.", + "loc.input.label.ScriptArguments": "Argumentos de script", + "loc.input.help.ScriptArguments": "Parámetros adicionales que pasar a PowerShell. Pueden ser parámetros ordinales o con nombre.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Seleccione el valor de la variable ErrorActionPreference para ejecutar el script.", + "loc.input.label.FailOnStandardError": "Error si se produce un error estándar", + "loc.input.help.FailOnStandardError": "Si es true, se producirá un error en la tarea si se escriben errores en la canalización de errores o si se escriben datos en el flujo de error estándar.", + "loc.input.label.RestrictContextToCurrentTask": "Restringir el ámbito de contexto a la tarea actual", + "loc.input.help.RestrictContextToCurrentTask": "Si es true, esta tarea restringirá el ámbito de contexto solo a la tarea actual y el contexto no estará disponible para otras tareas de la canalización cuando se use el agente privado.", + "loc.input.label.TargetAzurePs": "Versión de Azure PowerShell", + "loc.input.help.TargetAzurePs": "En el caso de los agentes hospedados, las versiones de Azure PowerShell admitidas son 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (Hosted VS2017 Queue).\nPara seleccionar la última versión disponible en el agente, seleccione \"Latest installed version\".\n\nPara los agentes privados, puede especificar la versión de Azure PowerShell que prefiera con la opción \"Specify version\"", + "loc.input.label.CustomTargetAzurePs": "Versión de Azure PowerShell preferida", + "loc.input.help.CustomTargetAzurePs": "La versión preferida de Azure PowerShell debe ser una versión de semántica adecuada, por ejemplo, 1.2.3. No se admite una notación regex como 2.\\*,2.3.\\*. El grupo Hosted VS2017 Pool es compatible con las versiones del módulo Az 1.0.0, 1.6.0, 2.3.2, 2.6.0 y 3.1.0", + "loc.input.label.pwsh": "Usar PowerShell Core", + "loc.input.help.pwsh": "Si es true, la tarea usará pwsh.exe desde PATH en lugar de powershell.exe en Windows.", + "loc.input.label.validateScriptSignature": "Validación de la firma del script", + "loc.input.help.validateScriptSignature": "Si es true, la tarea comprobará primero para asegurarse de que el script especificado está firmado y es válido antes de ejecutarlo.", + "loc.input.label.workingDirectory": "Directorio de trabajo", + "loc.input.help.workingDirectory": "Directorio de trabajo donde se ejecuta el script.", + "loc.messages.GeneratingScript": "Generando script.", + "loc.messages.JS_FormattedCommand": "Comando con formato: %s", + "loc.messages.InvalidScriptArguments0": "Argumentos de script '{0}' no válidos. No se permiten los saltos de línea.", + "loc.messages.InvalidScriptPath0": "Ruta del script '{0}' no válida. Los caracteres de ruta de acceso especificados no son válidos.", + "loc.messages.InvalidAzurePsVersion": "La versión de Azure PowerShell \"{0}\" especificada no tiene el formato correcto. Compruebe el formato. Ejemplo de formato correcto: 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell se cerró con el código \"%s\".", + "loc.messages.JS_Stderr": "PowerShell escribió una o varias líneas en la secuencia de error estándar.", + "loc.messages.ExpiredServicePrincipal": "No se pudo capturar el token de acceso de Azure. Compruebe que la entidad de servicio usada es válida y no ha expirado." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/fr-FR/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/fr-FR/resources.resjson new file mode 100644 index 000000000000..85ffdca03de8 --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/fr-FR/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[En savoir plus sur cette tâche](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Exécuter un script PowerShell dans un environnement Azure", + "loc.instanceNameFormat": "Script Azure PowerShell : $(ScriptType)", + "loc.releaseNotes": "Ajout de la prise en charge du module Azure et des agents multiplateformes.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Options de version Azure PowerShell", + "loc.group.displayName.advanced": "Avancé", + "loc.input.label.ConnectedServiceNameARM": "Abonnement Azure", + "loc.input.help.ConnectedServiceNameARM": "Abonnement Azure Resource Manager à configurer avant d'exécuter PowerShell", + "loc.input.label.ScriptType": "Type de script", + "loc.input.help.ScriptType": "Type du script : chemin de fichier ou script inline", + "loc.input.label.ScriptPath": "Chemin d'accès du script", + "loc.input.help.ScriptPath": "Chemin d'accès du script. Doit être un chemin d'accès complet ou relatif au répertoire de travail par défaut.", + "loc.input.label.Inline": "Script inline", + "loc.input.help.Inline": "Entrez le script à exécuter.", + "loc.input.label.ScriptArguments": "Arguments de script", + "loc.input.help.ScriptArguments": "Paramètres supplémentaires à passer à PowerShell. Peuvent être des paramètres ordinaux ou nommés.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Sélectionnez la valeur de la variable ErrorActionPreference pour l'exécution du script.", + "loc.input.label.FailOnStandardError": "Échec sur une erreur standard", + "loc.input.help.FailOnStandardError": "Si la valeur est true, et si des erreurs sont écrites dans le pipeline d'erreurs ou si des données sont écrites dans le flux d'erreurs standard, cette tâche se solde par un échec.", + "loc.input.label.RestrictContextToCurrentTask": "Limiter l'étendue du contexte à la tâche active", + "loc.input.help.RestrictContextToCurrentTask": "Si cette condition est vérifiée, la tâche limite l'étendue du contexte à la tâche active uniquement. Le contexte n'est pas accessible aux autres tâches du pipeline quand l'agent privé est utilisé.", + "loc.input.label.TargetAzurePs": "Version d'Azure PowerShell", + "loc.input.help.TargetAzurePs": "Dans le cas d'agents hébergés, les versions d'Azure PowerShell prises en charge sont les suivantes : 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (file d'attente VS2017 hébergée).\nPour choisir la dernière version disponible sur l'agent, sélectionnez \"Dernière version installée\".\n\nPour les agents privés, vous pouvez spécifier la version par défaut d'Azure PowerShell via \"Spécifier la version\"", + "loc.input.label.CustomTargetAzurePs": "Version préférée d'Azure PowerShell", + "loc.input.help.CustomTargetAzurePs": "La version par défaut d'Azure PowerShell doit être une version sémantique appropriée, par exemple 1.2.3. La notation regex telle que 2.\\*,2.3.\\* n'est pas prise en charge. Le pool VS2017 hébergé prend en charge les versions de module Az suivantes : 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "Utilisez PowerShell Core", + "loc.input.help.pwsh": "Si la valeur est true, dans Windows, la tâche utilise pwsh.exe à partir de votre variable PATH au lieu de powershell.exe.", + "loc.input.label.validateScriptSignature": "Valider la signature du script", + "loc.input.help.validateScriptSignature": "Si la valeur est true, la tâche vérifie d’abord que le script spécifié est signé et valide avant de l’exécuter.", + "loc.input.label.workingDirectory": "Répertoire de travail", + "loc.input.help.workingDirectory": "Répertoire de travail où le script est exécuté.", + "loc.messages.GeneratingScript": "Génération du script.", + "loc.messages.JS_FormattedCommand": "Commande mise en forme : %s", + "loc.messages.InvalidScriptArguments0": "Arguments de script '{0}' non valides. Les sauts de ligne ne sont pas autorisés.", + "loc.messages.InvalidScriptPath0": "Chemin de script '{0}' non valide. Caractères non valides spécifiés dans le chemin.", + "loc.messages.InvalidAzurePsVersion": "La version '{0}' spécifiée pour Azure PowerShell n'est pas au format approprié. Vérifiez le format. Exemple de format correct : 1.0.1", + "loc.messages.JS_ExitCode": "Arrêt de PowerShell. Code de sortie : '%s'.", + "loc.messages.JS_Stderr": "PowerShell a écrit une ou plusieurs lignes dans le flux d'erreurs standard.", + "loc.messages.ExpiredServicePrincipal": "Impossible de récupérer (fetch) le jeton d'accès pour Azure. Vérifiez si le principal de service utilisé est valide et s'il n'a pas expiré." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/it-IT/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/it-IT/resources.resjson new file mode 100644 index 000000000000..de03075839b5 --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/it-IT/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[Altre informazioni su questa attività](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Consente di eseguire uno script PowerShell in un ambiente Azure", + "loc.instanceNameFormat": "Script Azure PowerShell: $(ScriptType)", + "loc.releaseNotes": "È stato aggiunto il supporto per il modulo AZ e gli agenti multipiattaforma.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Opzioni della versione di Azure PowerShell", + "loc.group.displayName.advanced": "Avanzate", + "loc.input.label.ConnectedServiceNameARM": "Sottoscrizione di Azure", + "loc.input.help.ConnectedServiceNameARM": "Sottoscrizione di Azure Resource Manager da configurare prima di eseguire PowerShell", + "loc.input.label.ScriptType": "Tipo di script", + "loc.input.help.ScriptType": "Tipo dello script: Percorso file o Script inline", + "loc.input.label.ScriptPath": "Percorso script", + "loc.input.help.ScriptPath": "Percorso dello script. Deve essere un percorso completo o relativo rispetto alla directory di lavoro predefinita.", + "loc.input.label.Inline": "Script inline", + "loc.input.help.Inline": "Consente di immettere lo script da eseguire.", + "loc.input.label.ScriptArguments": "Argomenti script", + "loc.input.help.ScriptArguments": "Parametri aggiuntivi da passare a PowerShell. Possono essere ordinali o denominati.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Consente di selezionare il valore della variabile ErrorActionPreference per l'esecuzione dello script.", + "loc.input.label.FailOnStandardError": "Interrompi in caso di errore standard", + "loc.input.help.FailOnStandardError": "Se il valore è true, questa attività non riuscirà nel caso in cui vengano scritti errori nella pipeline degli errori oppure se vengono scritti dati nel flusso STDERR.", + "loc.input.label.RestrictContextToCurrentTask": "Limita l'ambito del contesto all'attività corrente", + "loc.input.help.RestrictContextToCurrentTask": "Se è true, questa attività limiterà l'ambito del contesto solo all'attività corrente e il contesto non sarà disponibile per altre attività nella pipeline quando si usa l'agente privato.", + "loc.input.label.TargetAzurePs": "Versione di Azure PowerShell", + "loc.input.help.TargetAzurePs": "In caso di agenti ospitati la versione supportata di Azure PowerShell è: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (Hosted VS2017 Queue).\nPer selezionare l'ultima versione disponibile per l'agente ospitato, selezionare \"Ultima versione installata\".\n\nPer gli agenti privati è possibile selezionare \"Specifica versione\" per specificare la versione preferita di Azure PowerShell", + "loc.input.label.CustomTargetAzurePs": "Versione preferita di Azure PowerShell", + "loc.input.help.CustomTargetAzurePs": "La versione preferita di Azure PowerShell deve essere una versione semantica valida, ad esempio 1.2.3. Espressioni regolari come 2.\\*,2.3.\\* non sono supportate. La versione Hosted VS2017 Pool supporta attualmente le versioni seguenti del modulo Az: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "Usa PowerShell Core", + "loc.input.help.pwsh": "Se è impostata su true, in Windows l'attività userà pwsh.exe da PATH invece di powershell.exe.", + "loc.input.label.validateScriptSignature": "Convalida firma script", + "loc.input.help.validateScriptSignature": "Se è True, l'attività verificherà innanzitutto che lo script specificato sia firmato e valido prima di eseguirlo.", + "loc.input.label.workingDirectory": "Directory di lavoro", + "loc.input.help.workingDirectory": "Directory di lavoro in cui viene eseguito lo script.", + "loc.messages.GeneratingScript": "Generazione dello script.", + "loc.messages.JS_FormattedCommand": "Comando formattato: %s", + "loc.messages.InvalidScriptArguments0": "Gli argomenti '{0}' dello script non sono validi. Le interruzioni di riga non sono consentite.", + "loc.messages.InvalidScriptPath0": "Il percorso '{0}' dello script non è valido. Sono stati specificati caratteri non validi.", + "loc.messages.InvalidAzurePsVersion": "Il formato della versione di Azure PowerShell '{0}' specificata non è corretto. Controllare il formato. Un esempio di formato corretto è 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell terminato con codice '%s'.", + "loc.messages.JS_Stderr": "PowerShell ha scritto una o più righe nel flusso di errore standard.", + "loc.messages.ExpiredServicePrincipal": "Non è stato possibile recuperare il token di accesso per Azure. Verificare che l'entità servizio usata sia valida e non sia scaduta." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/ja-JP/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/ja-JP/resources.resjson new file mode 100644 index 000000000000..5f60ce4b7a81 --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/ja-JP/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[このタスクの詳細を表示](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Azure 環境内で PowerShell スクリプトを実行します", + "loc.instanceNameFormat": "Azure PowerShell スクリプト: $(ScriptType)", + "loc.releaseNotes": "Az モジュールとクロス プラットフォームのエージェントのサポートが追加されました。", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell バージョンのオプション", + "loc.group.displayName.advanced": "詳細設定", + "loc.input.label.ConnectedServiceNameARM": "Azure サブスクリプション", + "loc.input.help.ConnectedServiceNameARM": "PowerShell を実行する前に構成する Azure Resource Manager サブスクリプション", + "loc.input.label.ScriptType": "スクリプトの種類", + "loc.input.help.ScriptType": "スクリプトの種類: ファイル パスまたはインライン スクリプト", + "loc.input.label.ScriptPath": "スクリプト パス", + "loc.input.help.ScriptPath": "スクリプトのパス。完全修飾パスか、既定の作業ディレクトリを基準とした相対パスのいずれかです。", + "loc.input.label.Inline": "インライン スクリプト", + "loc.input.help.Inline": "実行するスクリプトを入力します。", + "loc.input.label.ScriptArguments": "スクリプトの引数", + "loc.input.help.ScriptArguments": "PowerShell に渡す追加のパラメーター。順序によるパラメーターまたは名前指定されたパラメーターのいずれかです。", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "スクリプトを実行するための ErrorActionPreference 変数の値を選択します。", + "loc.input.label.FailOnStandardError": "標準エラーで失敗", + "loc.input.help.FailOnStandardError": "これが true の場合、何らかのエラーがエラー パイプラインに書き込まれるか、何らかのデータが標準エラー ストリームに書き込まれる場合、このタスクは失敗します。", + "loc.input.label.RestrictContextToCurrentTask": "コンテキストのスコープを現在のタスクに制限する", + "loc.input.help.RestrictContextToCurrentTask": "これが true の場合、このタスクによってコンテキストのスコープが現在のタスクのみに制限されます。また、プライベート エージェントを使用している場合、このコンテキストをパイプライン内の他のタスクで使用することはできなくなります。", + "loc.input.label.TargetAzurePs": "Azure PowerShell バージョン", + "loc.input.help.TargetAzurePs": "ホステッド エージェントの場合、サポートされている Azure PowerShell のバージョンは、1.0.0、1.6.0、2.3.2、2.6.0、3.1.0 (ホステッド VS2017 キュー) です。\nエージェントで利用可能な最新バージョンを選ぶには、[Latest installed version](インストールされている最新バージョン) を選択します。\n\nプライベート エージェントの場合は、[Specify version](バージョンを指定する) を使用して優先されるバージョンの Azure PowerShell を指定できます。", + "loc.input.label.CustomTargetAzurePs": "優先される Azure PowerShell バージョン", + "loc.input.help.CustomTargetAzurePs": "優先される Azure PowerShell バージョンは、1.2.3 などの適切なセマンティック バージョンである必要があります。2.\\*、2.3.\\* などの正規表現はサポートされていません。ホステッド VS2017 プールは、現在次の Az モジュール バージョンをサポートしています: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0", + "loc.input.label.pwsh": "PowerShell Core を使用する", + "loc.input.help.pwsh": "これが true の場合、Windows 上のタスクは powershell.exe ではなく PATH からの pwsh.exe を使用します。", + "loc.input.label.validateScriptSignature": "スクリプトの署名を検証する", + "loc.input.help.validateScriptSignature": "これが true の場合、タスクはまず、指定されたスクリプトが署名され、有効であることを確認してからこれを実行します。", + "loc.input.label.workingDirectory": "作業ディレクトリ", + "loc.input.help.workingDirectory": "スクリプトが実行される作業ディレクトリ。", + "loc.messages.GeneratingScript": "スクリプトを生成しています。", + "loc.messages.JS_FormattedCommand": "フォーマット後のコマンド: %s", + "loc.messages.InvalidScriptArguments0": "スクリプトの引数 '{0}' が無効です。改行は使用できません。", + "loc.messages.InvalidScriptPath0": "スクリプト パス '{0}' が無効です。無効なパス文字が指定されました。", + "loc.messages.InvalidAzurePsVersion": "指定した Azure PowerShell バージョン '{0}' は、形式が正しくありません。形式をご確認ください。正しい形式の例は、1.0.1 です", + "loc.messages.JS_ExitCode": "PowerShell がコード '%s' で終了しました。", + "loc.messages.JS_Stderr": "PowerShell が標準エラー ストリームに 1 行以上を書き込みました。", + "loc.messages.ExpiredServicePrincipal": "Azure のアクセス トークンをフェッチできませんでした。使用されているサービス プリンシパルが有効であり、有効期限が切れていないことを確認してください。" +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/ko-KR/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/ko-KR/resources.resjson new file mode 100644 index 000000000000..b00a1a1619c4 --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/ko-KR/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[이 작업에 대한 자세한 정보](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Azure 환경에서 PowerShell 스크립트 실행", + "loc.instanceNameFormat": "Azure PowerShell 스크립트: $(ScriptType)", + "loc.releaseNotes": "Az 모듈 및 플랫폼 간 에이전트에 대한 지원이 추가되었습니다.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell 버전 옵션", + "loc.group.displayName.advanced": "고급", + "loc.input.label.ConnectedServiceNameARM": "Azure 구독", + "loc.input.help.ConnectedServiceNameARM": "PowerShell을 실행하기 전에 구성할 Azure Resource Manager 구독", + "loc.input.label.ScriptType": "스크립트 유형", + "loc.input.help.ScriptType": "스크립트 유형: 파일 경로 또는 인라인 스크립트", + "loc.input.label.ScriptPath": "스크립트 경로", + "loc.input.help.ScriptPath": "스크립트의 경로입니다. 정규화된 경로이거나 기본 작업 디렉터리에 대한 상대 경로여야 합니다.", + "loc.input.label.Inline": "인라인 스크립트", + "loc.input.help.Inline": "실행할 스크립트를 입력합니다.", + "loc.input.label.ScriptArguments": "스크립트 인수", + "loc.input.help.ScriptArguments": "PowerShell에 전달할 추가 인수입니다. 서수 매개 변수나 명명된 매개 변수 중 하나일 수 있습니다.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "스크립트 실행에 대한 ErrorActionPreference 변수의 값을 선택합니다.", + "loc.input.label.FailOnStandardError": "표준 오류 시 실패", + "loc.input.help.FailOnStandardError": "이 값이 true이면 오류 파이프라인에 오류가 작성되거나 표준 오류 스트림에 데이터가 작성될 경우 이 작업은 실패하게 됩니다.", + "loc.input.label.RestrictContextToCurrentTask": "컨텍스트 범위를 현재 작업으로 제한", + "loc.input.help.RestrictContextToCurrentTask": "true이면 이 작업이 컨텍스트 범위를 현재 작업으로만 제한하고 프라이빗 에이전트를 사용할 때 파이프라인의 다른 작업에 대해 컨텍스트를 사용할 수 없게 됩니다.", + "loc.input.label.TargetAzurePs": "Azure PowerShell 버전", + "loc.input.help.TargetAzurePs": "호스트된 에이전트의 경우 지원되는 Azure PowerShell 버전은 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0(Hosted VS2017 Queue)입니다.\n에이전트에서 사용 가능한 최신 버전을 선택하려면 \"설치된 최신 버전\"을 선택합니다.\n\n사용자 에이전트의 경우 \"버전 지정\"을 사용하여 기본 Azure PowerShell 버전을 지정할 수 있습니다.", + "loc.input.label.CustomTargetAzurePs": "기본 Azure PowerShell 버전", + "loc.input.help.CustomTargetAzurePs": "기본 Azure PowerShell 버전은 올바른 의미 체계 버전(예: 1.2.3)이어야 합니다. 2.\\*,2.3.\\*와 같은 Regex는 지원되지 않습니다. Hosted VS2017 풀은 현재 Az 모듈 버전 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0을 지원합니다.", + "loc.input.label.pwsh": "PowerShell Core 사용", + "loc.input.help.pwsh": "true이면, Windows에서 작업이 powershell.exe 대신 PATH의 pwsh.exe를 사용합니다.", + "loc.input.label.validateScriptSignature": "스크립트 서명 유효성 검사", + "loc.input.help.validateScriptSignature": "true이면 작업을 실행하기 전에 먼저 지정한 스크립트가 서명되어 있고 유효한지 확인합니다.", + "loc.input.label.workingDirectory": "작업 디렉터리", + "loc.input.help.workingDirectory": "스크립트가 실행되는 작업 디렉터리입니다.", + "loc.messages.GeneratingScript": "스크립트를 생성 중입니다.", + "loc.messages.JS_FormattedCommand": "형식이 지정된 명령: %s", + "loc.messages.InvalidScriptArguments0": "스크립트 인수 '{0}'이(가) 잘못되었습니다. 줄 바꿈은 허용되지 않습니다.", + "loc.messages.InvalidScriptPath0": "스크립트 경로 '{0}'이(가) 잘못되었습니다. 잘못된 경로 문자를 지정했습니다.", + "loc.messages.InvalidAzurePsVersion": "지정한 Azure PowerShell 버전 '{0}'의 형식이 잘못되었습니다. 형식을 확인하세요. 올바른 형식의 예는 1.0.1입니다.", + "loc.messages.JS_ExitCode": "PowerShell이 코드 '%s'(으)로 종료되었습니다.", + "loc.messages.JS_Stderr": "PowerShell이 표준 오류 스트림에 하나 이상의 줄을 썼습니다.", + "loc.messages.ExpiredServicePrincipal": "Azure의 액세스 토큰을 페치할 수 없습니다. 사용한 서비스 주체가 유효하고 만료되지 않았는지 확인하세요." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/ru-RU/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/ru-RU/resources.resjson new file mode 100644 index 000000000000..c20a9b0fce5f --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/ru-RU/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[См. дополнительные сведения об этой задаче](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Выполнение скрипта PowerShell в среде Azure", + "loc.instanceNameFormat": "Сценарий Azure PowerShell: $(ScriptType)", + "loc.releaseNotes": "Добавлена поддержка модуля Az и кроссплатформенных агентов.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Параметры версии Azure PowerShell", + "loc.group.displayName.advanced": "Дополнительно", + "loc.input.label.ConnectedServiceNameARM": "Подписка Azure", + "loc.input.help.ConnectedServiceNameARM": "Подписка на Azure Resource Manager для настройки перед запуском PowerShell", + "loc.input.label.ScriptType": "Тип сценария", + "loc.input.help.ScriptType": "Тип сценария: путь к файлу или встроенный сценарий", + "loc.input.label.ScriptPath": "Путь к скрипту", + "loc.input.help.ScriptPath": "Путь к сценарию. Это должен быть полный путь или путь относительно рабочего каталога по умолчанию.", + "loc.input.label.Inline": "Встроенный сценарий", + "loc.input.help.Inline": "Введите сценарий для выполнения.", + "loc.input.label.ScriptArguments": "Аргументы скрипта", + "loc.input.help.ScriptArguments": "Дополнительные параметры для передачи в PowerShell. Могут быть как порядковыми, так и именованными.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Выберите значение переменной ErrorActionPreference для выполнения скрипта.", + "loc.input.label.FailOnStandardError": "Сбой со стандартной ошибкой", + "loc.input.help.FailOnStandardError": "Если задано значение True, задача будет завершаться сбоем при записи любых ошибок в конвейер ошибок или записи любых данных в стандартный поток ошибок.", + "loc.input.label.RestrictContextToCurrentTask": "Ограничить область контекста текущей задачей", + "loc.input.help.RestrictContextToCurrentTask": "Если задано значение true, задача ограничивает область контекста только текущей задачей и при использовании частного агента контекст будет недоступен для других задач в конвейере.", + "loc.input.label.TargetAzurePs": "Версия Azure PowerShell", + "loc.input.help.TargetAzurePs": "Для размещенных агентов поддерживаются следующие версии Azure PowerShell: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (размещенная очередь Visual Studio 2017).\nЧтобы выбрать последнюю версию, доступную в агенте, выберите пункт \"Последняя установленная версия\".\n\nДля частных агентов можно указать предпочтительную версию Azure PowerShell с помощью элемента \"Указать версию\"", + "loc.input.label.CustomTargetAzurePs": "Предпочтительная версия Azure PowerShell", + "loc.input.help.CustomTargetAzurePs": "Предпочтительная версия Azure PowerShell должна быть надлежащей семантической версией, например 1.2.3. Регулярные выражения, например 2.\\*,2.3.\\*, не поддерживаются. Размещенный пул Visual Studio 2017 сейчас поддерживает следующие версии модуля Az: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "Использовать PowerShell Core", + "loc.input.help.pwsh": "Если задано значение True, в Windows задача будет использовать программу pwsh.exe, указанную в переменной PATH, вместо powershell.exe.", + "loc.input.label.validateScriptSignature": "Проверка подписи сценария", + "loc.input.help.validateScriptSignature": "Если задано значение true, задача сначала проверит, что указанный сценарий подписан и действителен, прежде чем выполнить его.", + "loc.input.label.workingDirectory": "Рабочий каталог", + "loc.input.help.workingDirectory": "Рабочий каталог, в котором выполняется скрипт.", + "loc.messages.GeneratingScript": "Формируется скрипт.", + "loc.messages.JS_FormattedCommand": "Отформатирована команда: %s", + "loc.messages.InvalidScriptArguments0": "Недопустимые аргументы скрипта \"{0}\". Разрывы строк запрещены.", + "loc.messages.InvalidScriptPath0": "Недопустимый путь к скрипту \"{0}\". Указаны символы, недопустимые в пути.", + "loc.messages.InvalidAzurePsVersion": "Указанная версия Azure PowerShell \"{0}\" имеет неправильный формат. Проверьте формат. Пример правильного формата: 1.0.1", + "loc.messages.JS_ExitCode": "Завершение работы PowerShell с кодом \"%s\".", + "loc.messages.JS_Stderr": "Оболочка PowerShell записала одну или несколько строк в стандартный поток ошибок.", + "loc.messages.ExpiredServicePrincipal": "Не удалось получить маркер доступа для Azure. Убедитесь, что используемый субъект-служба является допустимым, а срок его действия не истек." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/zh-CN/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/zh-CN/resources.resjson new file mode 100644 index 000000000000..fe4a5eb3b960 --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/zh-CN/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[详细了解此任务](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "在 Azure 环境中运行 PowerShell 脚本", + "loc.instanceNameFormat": "Azure PowerShell 脚本: $(ScriptType)", + "loc.releaseNotes": "添加了对 Azure 模块和跨平台代理的支持。", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell 版本选项", + "loc.group.displayName.advanced": "高级", + "loc.input.label.ConnectedServiceNameARM": "Azure 订阅", + "loc.input.help.ConnectedServiceNameARM": "在运行 PowerShell 之前配置的 Azure 资源管理器订阅", + "loc.input.label.ScriptType": "脚本类型", + "loc.input.help.ScriptType": "脚本类型: 文件路径或内联脚本", + "loc.input.label.ScriptPath": "脚本路径", + "loc.input.help.ScriptPath": "脚本的路径。应是完全限定的路径或相对于默认工作目录。", + "loc.input.label.Inline": "内联脚本", + "loc.input.help.Inline": "输入要执行的脚本。", + "loc.input.label.ScriptArguments": "脚本参数", + "loc.input.help.ScriptArguments": "要传递给 PowerShell 的其他参数。可以是序号或命名参数。", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "选择执行脚本的 ErrorActionPreference 变量的值。", + "loc.input.label.FailOnStandardError": "因标准错误失败", + "loc.input.help.FailOnStandardError": "如果为 true,当有错误被写入错误管道或有数据被写入标准错误流时,此任务将失败。", + "loc.input.label.RestrictContextToCurrentTask": "将上下文的范围限于当前任务", + "loc.input.help.RestrictContextToCurrentTask": "如果为 true,此任务会将上下文的范围仅限于当前任务,并且在使用专用代理时,管道中的其他任务将无法使用该上下文。", + "loc.input.label.TargetAzurePs": "Azure PowerShell 版本", + "loc.input.help.TargetAzurePs": "对于托管代理,受支持的 Azure PowerShell 版本为: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0 (托管的 VS2017 队列)。\n若要选择代理上的最新可用版本,请选择“已安装的最新版本”。\n\n对于专用代理,可以使用“指定版本”指定 Azure PowerShell 的首选版本", + "loc.input.label.CustomTargetAzurePs": "首选 Azure PowerShell 版本", + "loc.input.help.CustomTargetAzurePs": "首选 Azure PowerShell 版本需为正确的语义版本,例如 1.2.3。不支持 2.\\*、2.3.\\* 等正则表达式。托管 VS2017 池当前支持 Azure 模块版本: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0", + "loc.input.label.pwsh": "使用 PowerShell Core", + "loc.input.help.pwsh": "如果为 true,则在 Windows 上,任务将使用来自 PATH 的 pwsh.exe,而不是 powershell.exe。", + "loc.input.label.validateScriptSignature": "验证脚本签名", + "loc.input.help.validateScriptSignature": "如果为 true,则任务将首先检查以确保指定的脚本已签名并且在执行前有效。", + "loc.input.label.workingDirectory": "工作目录", + "loc.input.help.workingDirectory": "在其中运行脚本的工作目录。", + "loc.messages.GeneratingScript": "正在生成脚本。", + "loc.messages.JS_FormattedCommand": "已设置格式的命令: %s", + "loc.messages.InvalidScriptArguments0": "脚本参数“{0}”无效。不允许换行。", + "loc.messages.InvalidScriptPath0": "脚本路径“{0}”无效。指定的路径字符无效。", + "loc.messages.InvalidAzurePsVersion": "指定的 Azure PowerShell 版本“{0}”格式不正确。请检查格式。正确格式的示例为 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell 已退出,代码为“%s”。", + "loc.messages.JS_Stderr": "PowerShell 向标准错误流写入一个或多个行。", + "loc.messages.ExpiredServicePrincipal": "无法提取 Azure 的访问令牌。请确保使用的服务主体有效且未过期。" +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Strings/resources.resjson/zh-TW/resources.resjson b/_generated/AzurePowerShellV4/Strings/resources.resjson/zh-TW/resources.resjson new file mode 100644 index 000000000000..5b87db2dbbac --- /dev/null +++ b/_generated/AzurePowerShellV4/Strings/resources.resjson/zh-TW/resources.resjson @@ -0,0 +1,43 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[深入了解此工作](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "在 Azure 環境中執行 PowerShell 指令碼", + "loc.instanceNameFormat": "Azure PowerShell 指令碼: $(ScriptType)", + "loc.releaseNotes": "新增了 Az 模組和跨平台代理程式的支援。", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell 版本選項", + "loc.group.displayName.advanced": "進階", + "loc.input.label.ConnectedServiceNameARM": "Azure 訂用帳戶", + "loc.input.help.ConnectedServiceNameARM": "執行 PowerShell 之前要設定的 Azure Resource Manager 訂用帳戶", + "loc.input.label.ScriptType": "指令碼類型", + "loc.input.help.ScriptType": "指令碼類型: 檔案路徑或內嵌指令碼", + "loc.input.label.ScriptPath": "指令碼路徑", + "loc.input.help.ScriptPath": "指令碼的路徑。必須是完整路徑名稱或預設工作目錄的相對路徑。", + "loc.input.label.Inline": "內嵌指令碼", + "loc.input.help.Inline": "請輸入要執行的指令碼。", + "loc.input.label.ScriptArguments": "指令碼引數", + "loc.input.help.ScriptArguments": "傳遞至 PowerShell 的額外引數。可以是序數或具名參數。", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "請選取用於執行指令碼的 ErrorActionPreference 變數值。", + "loc.input.label.FailOnStandardError": "發生標準錯誤的失敗", + "loc.input.help.FailOnStandardError": "若此項為 true,如果在錯誤管線中寫入任何錯誤,或在標準錯誤資料流中寫入任何資料,此工作就會失敗。", + "loc.input.label.RestrictContextToCurrentTask": "將內容範圍限制在目前的工作", + "loc.input.help.RestrictContextToCurrentTask": "若為 true,則此工作只會將內容範圍限制在目前的工作,而在使用私人代理程式時,管線中的其他工作將無法使用內容。", + "loc.input.label.TargetAzurePs": "Azure PowerShell 版本", + "loc.input.help.TargetAzurePs": "若為裝載的代理程式,則支援的 Azure PowerShell 版本為: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0 (裝載的 VS2017 佇列)。\n若要挑選代理程式上可用的最新版本,請選取 [最新安裝的版本]。\n\n若為私人代理程式,您可以使用 [指定版本] 指定慣用的 Azure PowerShell 版本", + "loc.input.label.CustomTargetAzurePs": "慣用的 Azure PowerShell 版本", + "loc.input.help.CustomTargetAzurePs": "慣用的 Azure PowerShell 版本必須是正確的語意版本,例如 1.2.3。不支援像 2.\\*,2.3.\\* 這樣的 Regex。裝載的 VS2017 集區目前支援 Az 模組版本: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0", + "loc.input.label.pwsh": "使用 PowerShell Core", + "loc.input.help.pwsh": "若此為 true,那麼在 Windows 上,工作就會使用 PATH 中的 pwsh.exe 而非 powershell.exe。", + "loc.input.label.validateScriptSignature": "驗證指令碼簽章", + "loc.input.help.validateScriptSignature": "如果此為 true,則工作會先進行檢查,確定指定的指令碼已簽署且有效,然後再執行。", + "loc.input.label.workingDirectory": "工作目錄", + "loc.input.help.workingDirectory": "指令碼執行所在的工作目錄。", + "loc.messages.GeneratingScript": "正在產生指令碼。", + "loc.messages.JS_FormattedCommand": "經過格式化的命令: %s", + "loc.messages.InvalidScriptArguments0": "指令碼引數 '{0}' 無效。不允許分行符號。", + "loc.messages.InvalidScriptPath0": "指令碼路徑 '{0}' 無效。指定的路徑字元無效。", + "loc.messages.InvalidAzurePsVersion": "指定的 Azure PowerShell 版本 '{0}' 格式不正確。請檢查格式。正確格式的範例為 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell 已結束,代碼為 '%s'。", + "loc.messages.JS_Stderr": "PowerShell 已將一或多行寫入標準錯誤資料流。", + "loc.messages.ExpiredServicePrincipal": "無法擷取 Azure 的存取權杖。請驗證使用的服務主體是否有效且未過期。" +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Tests/ChecksForPowerShell.ps1 b/_generated/AzurePowerShellV4/Tests/ChecksForPowerShell.ps1 new file mode 100644 index 000000000000..c88aa1ffb54d --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/ChecksForPowerShell.ps1 @@ -0,0 +1,30 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +$targetAzurePs = "4.1.0" +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "$PSScriptRoot/PerformsBasicFlow_TargetScript.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { 'arg1 arg2' } -- -Name ScriptArguments +Register-Mock Get-VstsInput { "continue" } -- -Name errorActionPreference +Register-Mock Get-VstsInput { $true } -- -Name FailOnStandardError +Register-Mock Get-VstsInput { $false } -- -Name pwsh -AsBool +Register-Mock Update-PSModulePathForHostedAgent +Register-Mock Get-Module +Register-Mock Initialize-AzModule +Register-Mock Get-VstsEndpoint { @{auth = @{ scheme = "ServicePrincipal" }} } +Register-Mock Remove-EndpointSecrets +Register-Mock Disconnect-AzureAndClearContext +Register-Mock Assert-VstsPath +Register-Mock Invoke-VstsTool { } +Register-Mock Expand-ModuleZip +Register-Mock Invoke-RestMethod +Register-Mock Save-Module + +# Act. +$actual = & $PSScriptRoot\..\AzurePowerShell.ps1 + +Assert-WasCalled Invoke-VstsTool -Times 1 +Assert-WasCalled Invoke-VstsTool -ArgumentsEvaluator {($args | ConvertTo-Json) -like '*powershell.exe*'} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Tests/ChecksForPowerShellCore.ps1 b/_generated/AzurePowerShellV4/Tests/ChecksForPowerShellCore.ps1 new file mode 100644 index 000000000000..60caed9e28fe --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/ChecksForPowerShellCore.ps1 @@ -0,0 +1,31 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +$targetAzurePs = "4.1.0" +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "$PSScriptRoot/PerformsBasicFlow_TargetScript.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { 'arg1 arg2' } -- -Name ScriptArguments +Register-Mock Get-VstsInput { "continue" } -- -Name errorActionPreference +Register-Mock Get-VstsInput { $true } -- -Name FailOnStandardError +Register-Mock Get-VstsInput { $true } -- -Name pwsh -AsBool +Register-Mock Update-PSModulePathForHostedAgent +Register-Mock Get-Module +Register-Mock Initialize-AzModule +Register-Mock Get-VstsEndpoint { @{auth = @{ scheme = "ServicePrincipal" }} } +Register-Mock Remove-EndpointSecrets +Register-Mock Disconnect-AzureAndClearContext +Register-Mock Assert-VstsPath +Register-Mock Invoke-VstsTool { } +Register-Mock Expand-ModuleZip +Register-Mock Invoke-RestMethod +Register-Mock Save-Module +Register-Mock ConvertTo-SecureString + +# Act. +$actual = & $PSScriptRoot\..\AzurePowerShell.ps1 + +Assert-WasCalled Invoke-VstsTool -Times 1 +Assert-WasCalled Invoke-VstsTool -ArgumentsEvaluator {($args | ConvertTo-Json) -like '*pwsh.exe*'} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Tests/ChecksForWorkingDirectory.ps1 b/_generated/AzurePowerShellV4/Tests/ChecksForWorkingDirectory.ps1 new file mode 100644 index 000000000000..4f824ae5b8c2 --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/ChecksForWorkingDirectory.ps1 @@ -0,0 +1,33 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +$targetAzurePs = "4.1.0" +$input_workingDirectory = "C:\Users" +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "$PSScriptRoot/PerformsBasicFlow_TargetScript.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { 'arg1 arg2' } -- -Name ScriptArguments +Register-Mock Get-VstsInput { "continue" } -- -Name errorActionPreference +Register-Mock Get-VstsInput { $true } -- -Name FailOnStandardError +Register-Mock Get-VstsInput { $true } -- -Name pwsh -AsBool +Register-Mock Get-VstsInput { $input_workingDirectory } -- -Name workingDirectory -Require +Register-Mock Update-PSModulePathForHostedAgent +Register-Mock Get-Module +Register-Mock Initialize-AzModule +Register-Mock Get-VstsEndpoint { @{auth = @{ scheme = "ServicePrincipal" }} } +Register-Mock Remove-EndpointSecrets +Register-Mock Disconnect-AzureAndClearContext +Register-Mock Assert-VstsPath +Register-Mock Invoke-VstsTool { } +Register-Mock Expand-ModuleZip +Register-Mock Invoke-RestMethod +Register-Mock Save-Module +Register-Mock ConvertTo-SecureString + +# Act. +$actual = & $PSScriptRoot\..\AzurePowerShell.ps1 + +Assert-WasCalled Invoke-VstsTool -Times 1 +Assert-WasCalled Invoke-VstsTool -ArgumentsEvaluator {($args | ConvertTo-Json) -like '*C:\\Users*'} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Tests/L0.ts b/_generated/AzurePowerShellV4/Tests/L0.ts new file mode 100644 index 000000000000..23000ff892d3 --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/L0.ts @@ -0,0 +1,58 @@ +/// +/// +/// + +import Q = require('q'); +import assert = require('assert'); +import path = require('path'); +var psm = require('../../../Tests/lib/psRunner'); +var psr = null; + +describe('AzurePowerShell Suite', function () { + this.timeout(parseInt(process.env.TASK_TEST_TIMEOUT) || 20000); + + before((done) => { + if (psm.testSupported()) { + psr = new psm.PSRunner(); + psr.start(); + } + + done(); + }); + + after(function () { + if (psr) { + psr.kill(); + } + }); + + if (psm.testSupported()) { + it('checks for powershell core', (done) => { + psr.run(path.join(__dirname, 'ChecksForPowerShellCore.ps1'), done); + }) + /*it('checks for powershell', (done) => { + psr.run(path.join(__dirname, 'ChecksForPowerShell.ps1'), done); + })*/ + it('checks for working directory', (done) => { + psr.run(path.join(__dirname, 'ChecksForWorkingDirectory.ps1'), done); + }) + it('performs basic flow', (done) => { + psr.run(path.join(__dirname, 'PerformsBasicFlow.ps1'), done); + }) + it('throws when otherversion is specified in a wrong format', (done) => { + psr.run(path.join(__dirname, 'ThrowsForInvalidVersion.ps1'), done); + }) + it('throws when invalid script arguments', (done) => { + psr.run(path.join(__dirname, 'ThrowsWhenInvalidScriptArguments.ps1'), done); + }) + it('throws when invalid script path', (done) => { + psr.run(path.join(__dirname, 'ThrowsWhenInvalidScriptPath.ps1'), done); + }) + it('Get-LatestModule returns the latest available module', (done) => { + psr.run(path.join(__dirname, 'Utility.Get-LatestModule.ps1'), done); + }) + it('Update-PSModulePathForHostedAgent updated psmodulepath correctly', (done) => { + psr.run(path.join(__dirname, 'Utility.UpdatePSModulePathForHostedAgentWorksCorrectly.ps1'), done); + }) + } +}); \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Tests/PerformsBasicFlow.ps1 b/_generated/AzurePowerShellV4/Tests/PerformsBasicFlow.ps1 new file mode 100644 index 000000000000..6a2b2e74708d --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/PerformsBasicFlow.ps1 @@ -0,0 +1,35 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +$targetAzurePs = "4.1.0" +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "$PSScriptRoot/PerformsBasicFlow_TargetScript.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { 'arg1 arg2' } -- -Name ScriptArguments +Register-Mock Get-VstsInput { "continue" } -- -Name errorActionPreference +Register-Mock Get-VstsInput { $true } -- -Name FailOnStandardError +Register-Mock Update-PSModulePathForHostedAgent +Register-Mock Get-Module +Register-Mock Initialize-AzModule +Register-Mock Get-VstsEndpoint { @{auth = @{ scheme = "ServicePrincipal" }} } +Register-Mock Remove-EndpointSecrets +Register-Mock Disconnect-AzureAndClearContext +Register-Mock Assert-VstsPath +Register-Mock Invoke-VstsTool { } +Register-Mock Expand-ModuleZip +Register-Mock Invoke-RestMethod +Register-Mock Save-Module +Register-Mock ConvertTo-SecureString + +# Act. +$actual = & $PSScriptRoot\..\AzurePowerShell.ps1 + +# Assert the error action preference was set to Continue. +Assert-AreEqual "Continue" $global:ErrorActionPreference +$global:ErrorActionPreference = 'Stop' # Reset to stop. + +# Assert the Azure helpers module was imported and invoked. +Assert-WasCalled Import-Module -- ([System.IO.Path]::GetFullPath("$PSScriptRoot\..\ps_modules\VstsAzureHelpers_")) +Assert-WasCalled Initialize-AzModule diff --git a/_generated/AzurePowerShellV4/Tests/PerformsBasicFlow_TargetScript.ps1 b/_generated/AzurePowerShellV4/Tests/PerformsBasicFlow_TargetScript.ps1 new file mode 100644 index 000000000000..53aafdebcdd8 --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/PerformsBasicFlow_TargetScript.ps1 @@ -0,0 +1,4 @@ +# Return key information. +New-Object psobject -Property @{ + Args = $args +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Tests/ThrowsForInvalidVersion.ps1 b/_generated/AzurePowerShellV4/Tests/ThrowsForInvalidVersion.ps1 new file mode 100644 index 000000000000..5afc27858f1e --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/ThrowsForInvalidVersion.ps1 @@ -0,0 +1,15 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 + +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "foobar.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { "OtherVersion" } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { "x.y.z" } -- -Name CustomTargetAzurePs + +# Act/Assert. +Assert-Throws { + & $PSScriptRoot\..\AzurePowerShell.ps1 +} -MessagePattern "InvalidAzurePsVersion*x.y.z" diff --git a/_generated/AzurePowerShellV4/Tests/ThrowsWhenInvalidScriptArguments.ps1 b/_generated/AzurePowerShellV4/Tests/ThrowsWhenInvalidScriptArguments.ps1 new file mode 100644 index 000000000000..af93358163bc --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/ThrowsWhenInvalidScriptArguments.ps1 @@ -0,0 +1,14 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +foreach ($arguments in @( "script`rarguments", "script`narguments" )) { + Unregister-Mock Get-VstsInput + Register-Mock Get-VstsInput { $arguments } -- -Name ScriptArguments + + # Act/Assert. + Assert-Throws { + & $PSScriptRoot\..\AzurePowerShell.ps1 + } -MessagePattern "InvalidScriptArguments0*$arguments" +} diff --git a/_generated/AzurePowerShellV4/Tests/ThrowsWhenInvalidScriptPath.ps1 b/_generated/AzurePowerShellV4/Tests/ThrowsWhenInvalidScriptPath.ps1 new file mode 100644 index 000000000000..a1334790ccba --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/ThrowsWhenInvalidScriptPath.ps1 @@ -0,0 +1,16 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +foreach ($path in @( "script`rpath", "script`npath" )) { + Unregister-Mock Get-VstsInput + Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require + Register-Mock Get-VstsInput { $path } -- -Name ScriptPath + Register-Mock Get-VstsInput { "4.1.0" } -- -Name TargetAzurePs + + # Act/Assert. + Assert-Throws { + & $PSScriptRoot\..\AzurePowerShell.ps1 + } -MessagePattern "InvalidScriptPath0*$path" +} diff --git a/_generated/AzurePowerShellV4/Tests/Utility.Get-LatestModule.ps1 b/_generated/AzurePowerShellV4/Tests/Utility.Get-LatestModule.ps1 new file mode 100644 index 000000000000..71609db6ede0 --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/Utility.Get-LatestModule.ps1 @@ -0,0 +1,30 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +. $PSScriptRoot\..\Utility.ps1 + +$azModulePath = "c:\modules\az_4.1.0" + +$azModulePattern = "^az_[0-9]+\.[0-9]+\.[0-9]+$" +$versionPattern = "[0-9]+\.[0-9]+\.[0-9]+$" + +$mockDirectoryStructure = @( + @{ + Name = "az_4.1.0" + FullName = "C:\Modules\az_4.1.0" + } + @{ + Name = "az_3.6.0" + FullName = "C:\Modules\az_3.6.0" + } +) + +Register-Mock Get-ChildItem { $mockDirectoryStructure } -- -Directory -Path "C:\Modules" +Register-Mock Test-Path { $true } + +# Act +$result = Get-LatestModule -patternToMatch $azModulePattern -patternToExtract $versionPattern +# Assert +Assert-AreEqual $result.toLower() $azModulePath \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Tests/Utility.UpdatePSModulePathForHostedAgentWorksCorrectly.ps1 b/_generated/AzurePowerShellV4/Tests/Utility.UpdatePSModulePathForHostedAgentWorksCorrectly.ps1 new file mode 100644 index 000000000000..53c9c7875e54 --- /dev/null +++ b/_generated/AzurePowerShellV4/Tests/Utility.UpdatePSModulePathForHostedAgentWorksCorrectly.ps1 @@ -0,0 +1,47 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +. $PSScriptRoot\..\Utility.ps1 + +$azModulePath = "c:\modules\az_3.6.0" + +$azModulePattern = "^az_[0-9]+\.[0-9]+\.[0-9]+$" +$versionPattern = "[0-9]+\.[0-9]+\.[0-9]+$" + +$variableSets = @( + @{ + targetAzurePsVersion = "3.6.0" + azModuleExist = $true + } + @{ + targetAzurePsVersion = "" + azModulePath = $true + } +) + +$temp = $env:PSModulePath + +foreach ($variableSet in $variableSets) { + $env:PSModulePath = $temp + # Arrange + Unregister-Mock Get-LatestModule + if($variableSet.azModuleExist) { + Register-Mock Get-LatestModule { $azModulePath } -- -patternToMatch $azModulePattern -patternToExtract $versionPattern -Classic:$false + } else { + Register-Mock Get-LatestModule { "" } -- -patternToMatch $azModulePattern -patternToExtract $versionPattern -Classic:$false + } + + # Act + Update-PSModulePathForHostedAgent -targetAzurePs $variableSet.targetAzurePsVersion + + # Assert + if($variableSet.azModuleExist) { + Assert-IsGreaterThan -1 $env:PSModulePath.toLower().IndexOf($azModulePath) + } else { + Assert-AreEqual -1 $env:PSModulePath.toLower().IndexOf($azModulePath) + } + + Assert-IsGreaterThan 0 $env:PSModulePath.toLower().IndexOf(";") +} diff --git a/_generated/AzurePowerShellV4/ThirdPartyNotices.txt b/_generated/AzurePowerShellV4/ThirdPartyNotices.txt new file mode 100644 index 000000000000..abc33cfd772f --- /dev/null +++ b/_generated/AzurePowerShellV4/ThirdPartyNotices.txt @@ -0,0 +1,136 @@ + +THIRD-PARTY SOFTWARE NOTICES AND INFORMATION +Do Not Translate or Localize + +Azure PowerShell incorporates third party material from the projects listed below. The original copyright notice and the license under which Microsoft received such third party material are set forth below. Microsoft reserves all other rights not expressly granted, whether by implication, estoppel or otherwise. + +1. OpenSSL (http://www.openssl.org) + +%% OpenSSL NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/) + * + * 4. The names OpenSSL Toolkit and OpenSSL Project must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called OpenSSL + * nor may OpenSSL appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/) + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com) + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * This product includes software written by Tim Hudson (tjh@cryptsoft.com) + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] +========================================= +END OF OpenSSL NOTICES, INFORMATION, AND LICENSE diff --git a/_generated/AzurePowerShellV4/TryMakingModuleAvailable.ps1 b/_generated/AzurePowerShellV4/TryMakingModuleAvailable.ps1 new file mode 100644 index 000000000000..71d91e944af9 --- /dev/null +++ b/_generated/AzurePowerShellV4/TryMakingModuleAvailable.ps1 @@ -0,0 +1,85 @@ +[CmdletBinding()] +param ( + [string] + $targetVersion, + + [string] [Parameter(Mandatory = $true)] [ValidateSet("Windows", "Linux", "Mac")] + $platform +) + +try { + $isWin = $platform -eq "Windows" + + . (Join-Path $PSScriptRoot "Utility.ps1") + $isHostedAgent = Test-IsHostedAgentPathPresent -isWin $isWin + + if (!$isHostedAgent) { + Write-Verbose "Module path not present as expected in hosted agent, skipping step to make module available." + $moduleSource = "privateAgent" + return + } + + if (!$targetVersion) { + Write-Verbose "Latest selected, will make use of the latest available in agent as folder." + $moduleSource = "hostedAgentFolder" + return + } + + $modulePath = Get-SavedModulePath -azurePowerShellVersion $targetVersion -isWin $isWin + if (Test-Path $modulePath) { + Write-Verbose "Az $targetVersion present at $modulePath as folder." + $moduleSource = "hostedAgentFolder" + return + } + + $moduleContainerPath = Get-SavedModuleContainerPath -isWin $isWin + $moduleZipPath = $modulePath + ".zip"; + if (Test-Path $moduleZipPath) { + Write-Verbose "Az $targetVersion present at $moduleZipPath as zip, expanding it." + Expand-ModuleZip -zipPath $moduleZipPath -destination $moduleContainerPath -isWin $isWin + Write-Verbose "Zip expanded" + $moduleSource = "hostedAgentZip" + return + } + + Write-Host "Az version $targetVersion not avaiable locally on the agent. Downloading dynamically." + + try { + Write-Verbose "Getting versions manifest from GHRelease." + $versionsManifest = Invoke-RestMethod -Method Get ` + -Headers @{ "Accept" = "application/vnd.github.VERSION.raw" } ` + -Uri "https://api.github.com/repos/Azure/az-ps-module-versions/contents/versions-manifest.json" + Write-Verbose "Versions manifest downloaded." + $downloadUrlEntity = $versionsManifest | Where-Object version -eq $targetVersion + if ($downloadUrlEntity) { + $downloadUrl = $downloadUrlEntity.files[0].download_url + Write-Verbose "Downloading Az $targetVersion from GHRelease" + (New-Object System.Net.WebClient).DownloadFile($downloadUrl, $moduleZipPath) + Write-Verbose "Download succeeded" + if (Test-Path $moduleZipPath) { + Write-Verbose "Expanding Az $targetVersion downloaded at $moduleZipPath as zip." + Expand-ModuleZip -zipPath $moduleZipPath -destination $moduleContainerPath -isWin $isWin + Write-Verbose "Zip expanded" + $moduleSource = "hostedAgentGHRelease" + return + } + } else { + Write-Verbose "Az $targetVersion not present in versions manifest from GHRelease" + } + } catch { + Write-Verbose "Failed to download from GHRelease" + Write-Verbose $_ + } + + Write-Verbose "Downloading Az $targetVersion from PSGallery." + Save-Module -Path $modulePath -Name Az -RequiredVersion $targetVersion -Force -ErrorAction Stop + $moduleSource = "hostedAgentPSGallery" +} finally { + # Telemetry + # moduleSource value will be privateAgent(in case of self hosted private agents), hostedAgentFolder(when a version is present as folder or + # when latest is selected we will use the one latest available as folder), hostedAgentZip(when the module is available as a zip locally), + # hostedAgentGHRelease(when the module zip is downloaded from our GitHub releases management), hostedAgentPSGallery(when we download from PSGallery + # using the Save-Module cmdlet). + $telemetryJsonContent = @{ targetAzurePs = $targetVersion; moduleSource = $moduleSource } | ConvertTo-Json -Compress + Write-Host "##vso[telemetry.publish area=TaskHub;feature=AzurePowerShellV4]$telemetryJsonContent" +} diff --git a/_generated/AzurePowerShellV4/UpdatePSModulePath.ps1 b/_generated/AzurePowerShellV4/UpdatePSModulePath.ps1 new file mode 100644 index 000000000000..e36160743c59 --- /dev/null +++ b/_generated/AzurePowerShellV4/UpdatePSModulePath.ps1 @@ -0,0 +1,11 @@ +[CmdletBinding()] +param +( + [String] [Parameter(Mandatory = $false)] + $targetAzurePs +) + +# Update PSModulePath for hosted agent +. "$PSScriptRoot\Utility.ps1" +CleanUp-PSModulePathForHostedAgent +Update-PSModulePathForHostedAgent -targetAzurePs $targetAzurePs \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/Utility.ps1 b/_generated/AzurePowerShellV4/Utility.ps1 new file mode 100644 index 000000000000..8e6804ffe66e --- /dev/null +++ b/_generated/AzurePowerShellV4/Utility.ps1 @@ -0,0 +1,203 @@ +function Get-SavedModuleContainerPath { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [bool] + $isWin + ) + + if ($isWin) { + return $env:SystemDrive + "\Modules"; + } else { + return "/usr/share"; + } +} + +function Test-IsHostedAgentPathPresent { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [bool] + $isWin + ) + + $containerPath = Get-SavedModuleContainerPath -isWin $isWin + return Test-Path (Join-Path $containerPath "az_*") +} + +function Get-SavedModulePath { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [string] + $azurePowerShellVersion, + + [Parameter(Mandatory = $true)] + [bool] + $isWin + ) + + $savedModulePath = Join-Path (Get-SavedModuleContainerPath -isWin $isWin) "az_$azurePowerShellVersion" + Write-Verbose "The value of the module path is: $savedModulePath" + return $savedModulePath +} + +function Expand-ModuleZip { + param ( + [string] [Parameter(Mandatory = $true)] + $zipPath, + + [string] [Parameter(Mandatory = $true)] + $destination, + + [bool] [Parameter(Mandatory=$true)] + $isWin + ) + + if ($isWin) { + $parameter = @("x", "-o$destination", "$zipPath") + $command = "$PSScriptRoot\7zip\7z.exe" + &$command @parameter + } else { + $prevProgressPref = $ProgressPreference + $ProgressPreference = 'SilentlyContinue' + Expand-Archive -Path $zipPath -DestinationPath $destination + $ProgressPreference = $prevProgressPref + } +} + +function Update-PSModulePathForHostedAgent { + [CmdletBinding()] + param([string] $targetAzurePs) + try { + if ($targetAzurePs) { + $hostedAgentAzModulePath = Get-SavedModulePath -azurePowerShellVersion $targetAzurePs -isWin $true + } + else { + $hostedAgentAzModulePath = Get-LatestModule -patternToMatch "^az_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" + } + $env:PSModulePath = $hostedAgentAzModulePath + ";" + $env:PSModulePath + $env:PSModulePath = $env:PSModulePath.TrimStart(';') + } finally { + Write-Verbose "The updated value of the PSModulePath is: $($env:PSModulePath)" + } +} + +function Update-PSModulePathForHostedAgentLinux { + [CmdletBinding()] + param([string] $targetAzurePs) + try { + if ($targetAzurePs) { + $hostedAgentAzModulePath = Get-SavedModulePath -azurePowerShellVersion $targetAzurePs -isWin $false + if(!(Test-Path $hostedAgentAzModulePath)) { + Write-Verbose "No module path found with this name" + throw ("Could not find the module path with given version.") + } + } + else { + $hostedAgentAzModulePath = Get-LatestModuleLinux -patternToMatch "^az_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" + } + $env:PSModulePath = $hostedAgentAzModulePath + ":" + $env:PSModulePath + $env:PSModulePath = $env:PSModulePath.TrimStart(':') + } finally { + Write-Verbose "The updated value of the PSModulePath is: $($env:PSModulePath)" + } +} + +function Get-LatestModule { + [CmdletBinding()] + param([string] $patternToMatch, + [string] $patternToExtract) + + $resultFolder = "" + $regexToMatch = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToMatch + $regexToExtract = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToExtract + $maxVersion = [version] "0.0.0" + $modulePath = $env:SystemDrive + "\Modules"; + + try { + if (-not (Test-Path -Path $modulePath)) { + return $resultFolder + } + + $moduleFolders = Get-ChildItem -Directory -Path $modulePath | Where-Object { $regexToMatch.IsMatch($_.Name) } + foreach ($moduleFolder in $moduleFolders) { + $moduleVersion = [version] $($regexToExtract.Match($moduleFolder.Name).Groups[0].Value) + if($moduleVersion -gt $maxVersion) { + $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"Az\$moduleVersion\Az.psm1") + + if(Test-Path -LiteralPath $modulePath -PathType Leaf) { + $maxVersion = $moduleVersion + $resultFolder = $moduleFolder.FullName + } else { + Write-Verbose "A folder matching the module folder pattern was found at $($moduleFolder.FullName) but didn't contain a valid module file" + } + } + } + } + catch { + Write-Verbose "Attempting to find the Latest Module Folder failed with the error: $($_.Exception.Message)" + $resultFolder = "" + } + Write-Verbose "Latest module folder detected: $resultFolder" + return $resultFolder +} + +function Get-LatestModuleLinux { + [CmdletBinding()] + param([string] $patternToMatch, + [string] $patternToExtract) + + $resultFolder = "" + $regexToMatch = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToMatch + $regexToExtract = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToExtract + $maxVersion = [version] "0.0.0" + + try { + $moduleFolders = Get-ChildItem -Directory -Path $("/usr/share") | Where-Object { $regexToMatch.IsMatch($_.Name) } + foreach ($moduleFolder in $moduleFolders) { + $moduleVersion = [version] $($regexToExtract.Match($moduleFolder.Name).Groups[0].Value) + if($moduleVersion -gt $maxVersion) { + $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"Az/$moduleVersion/Az.psm1") + + if(Test-Path -LiteralPath $modulePath -PathType Leaf) { + $maxVersion = $moduleVersion + $resultFolder = $moduleFolder.FullName + } else { + Write-Verbose "A folder matching the module folder pattern was found at $($moduleFolder.FullName) but didn't contain a valid module file" + } + } + } + } + catch { + Write-Verbose "Attempting to find the Latest Module Folder failed with the error: $($_.Exception.Message)" + $resultFolder = "" + } + Write-Verbose "Latest module folder detected: $resultFolder" + return $resultFolder +} + +function CleanUp-PSModulePathForHostedAgent { + # Clean up PSModulePath for hosted agent + $azureRMModulePath = "C:\Modules\azurerm_2.1.0" + $azureModulePath = "C:\Modules\azure_2.1.0" + $azPSModulePath = $env:PSModulePath + + if ($azPSModulePath.split(";") -contains $azureRMModulePath) { + $azPSModulePath = (($azPSModulePath).Split(";") | ? { $_ -ne $azureRMModulePath }) -join ";" + write-verbose "$azureRMModulePath removed. Restart the prompt for the changes to take effect." + } + else { + write-verbose "$azureRMModulePath is not present in $azPSModulePath" + } + + if ($azPSModulePath.split(";") -contains $azureModulePath) { + $azPSModulePath = (($azPSModulePath).Split(";") | ? { $_ -ne $azureModulePath }) -join ";" + write-verbose "$azureModulePath removed. Restart the prompt for the changes to take effect." + } + else { + write-verbose "$azureModulePath is not present in $azPSModulePath" + } + + $env:PSModulePath = $azPSModulePath +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/azurepowershell.ts b/_generated/AzurePowerShellV4/azurepowershell.ts new file mode 100644 index 000000000000..055826a0965a --- /dev/null +++ b/_generated/AzurePowerShellV4/azurepowershell.ts @@ -0,0 +1,169 @@ +import fs = require('fs'); +import path = require('path'); +import os = require('os'); +import tl = require('azure-pipelines-task-lib/task'); +import tr = require('azure-pipelines-task-lib/toolrunner'); +import * as telemetry from 'azure-pipelines-tasks-utility-common/telemetry'; + +import { AzureRMEndpoint } from 'azure-pipelines-tasks-azure-arm-rest/azure-arm-endpoint'; +var uuidV4 = require('uuid/v4'); + +function convertToNullIfUndefined(arg: T): T|null { + return arg ? arg : null; +} + +async function run() { + try { + tl.setResourcePath(path.join(__dirname, 'task.json')); + + // Get inputs. + console.log("## Validating Inputs"); + let _vsts_input_errorActionPreference: string = tl.getInput('errorActionPreference', false) || 'Stop'; + switch (_vsts_input_errorActionPreference.toUpperCase()) { + case 'STOP': + case 'CONTINUE': + case 'SILENTLYCONTINUE': + break; + default: + throw new Error(tl.loc('JS_InvalidErrorActionPreference', _vsts_input_errorActionPreference)); + } + let scriptType: string = tl.getInput('ScriptType', /*required*/true); + let scriptPath = convertToNullIfUndefined(tl.getPathInput('ScriptPath', false)); + let scriptInline: string = convertToNullIfUndefined(tl.getInput('Inline', false)); + let scriptArguments: string = convertToNullIfUndefined(tl.getInput('ScriptArguments', false)); + let _vsts_input_failOnStandardError = convertToNullIfUndefined(tl.getBoolInput('FailOnStandardError', false)); + let targetAzurePs: string = convertToNullIfUndefined(tl.getInput('TargetAzurePs', false)); + let customTargetAzurePs: string = convertToNullIfUndefined(tl.getInput('CustomTargetAzurePs', false)); + let serviceName = tl.getInput('ConnectedServiceNameARM',/*required*/true); + let endpointObject= await new AzureRMEndpoint(serviceName).getEndpoint(); + let input_workingDirectory = tl.getPathInput('workingDirectory', /*required*/ true, /*check*/ true); + let isDebugEnabled = (process.env['SYSTEM_DEBUG'] || "").toLowerCase() === "true"; + + // string constants + let otherVersion = "OtherVersion" + + if (targetAzurePs == otherVersion) { + if (customTargetAzurePs != "") { + targetAzurePs = customTargetAzurePs; + } + else { + console.log(tl.loc('InvalidAzurePsVersion',customTargetAzurePs)); + } + } + else { + targetAzurePs = "" + } + + var endpoint = JSON.stringify(endpointObject); + + if (scriptType.toUpperCase() == 'FILEPATH') { + if (!tl.stats(scriptPath).isFile() || !scriptPath.toUpperCase().match(/\.PS1$/)) { + throw new Error(tl.loc('JS_InvalidFilePath', scriptPath)); + } + } + console.log("## Validating Inputs Complete"); + + // Generate the script contents. + console.log("## Initializing Az module"); + console.log(tl.loc('GeneratingScript')); + let contents: string[] = []; + + if (isDebugEnabled) { + contents.push("$VerbosePreference = 'continue'"); + } + + const makeModuleAvailableScriptPath = path.join(path.resolve(__dirname), 'TryMakingModuleAvailable.ps1'); + contents.push(`${makeModuleAvailableScriptPath} -targetVersion '${targetAzurePs}' -platform Linux`); + + let azFilePath = path.join(path.resolve(__dirname), 'InitializeAz.ps1'); + contents.push(`$ErrorActionPreference = '${_vsts_input_errorActionPreference}'`); + if(targetAzurePs == "") { + contents.push(`${azFilePath} -endpoint '${endpoint}'`); + } + else { + contents.push(`${azFilePath} -endpoint '${endpoint}' -targetAzurePs ${targetAzurePs}`); + } + + if(scriptArguments == null) + { + scriptArguments = ""; + } + + if (scriptType.toUpperCase() == 'FILEPATH') { + contents.push(`. '${scriptPath.replace(/'/g, "''")}' ${scriptArguments}`.trim()); + console.log(tl.loc('JS_FormattedCommand', contents[contents.length - 1])); + } + else { + contents.push(scriptInline); + } + + // Write the script to disk. + tl.assertAgent('2.115.0'); + let tempDirectory = tl.getVariable('agent.tempDirectory'); + tl.checkPath(tempDirectory, `${tempDirectory} (agent.tempDirectory)`); + let filePath = path.join(tempDirectory, uuidV4() + '.ps1'); + await fs.writeFile( + filePath, + '\ufeff' + contents.join(os.EOL), // Prepend the Unicode BOM character. + { encoding: 'utf8' }, // Since UTF8 encoding is specified, node will + function (err) { // encode the BOM into its UTF8 binary sequence. + if (err) throw err; + console.log('Saved!'); + }); + console.log("## Az module initialization Complete"); + console.log("## Beginning Script Execution"); + // Run the script. + // + // Note, prefer "pwsh" over "powershell". At some point we can remove support for "powershell". + // + // Note, use "-Command" instead of "-File" to match the Windows implementation. Refer to + // comment on Windows implementation for an explanation why "-Command" is preferred. + let powershell = tl.tool(tl.which('pwsh') || tl.which('powershell') || tl.which('pwsh', true)) + .arg('-NoLogo') + .arg('-NoProfile') + .arg('-NonInteractive') + .arg('-ExecutionPolicy') + .arg('Unrestricted') + .arg('-Command') + .arg(`. '${filePath.replace(/'/g, "''")}'`); + + let options = { + cwd: input_workingDirectory, + failOnStdErr: false, + errStream: process.stdout, // Direct all output to STDOUT, otherwise the output may appear out + outStream: process.stdout, // of order since Node buffers it's own STDOUT but not STDERR. + ignoreReturnCode: true + }; + + // Listen for stderr. + let stderrFailure = false; + if (_vsts_input_failOnStandardError) { + powershell.on('stderr', (data) => { + stderrFailure = true; + }); + } + + // Run bash. + let exitCode: number = await powershell.exec(options); + + // Fail on exit code. + if (exitCode !== 0) { + tl.setResult(tl.TaskResult.Failed, tl.loc('JS_ExitCode', exitCode)); + } + + // Fail on stderr. + if (stderrFailure) { + tl.setResult(tl.TaskResult.Failed, tl.loc('JS_Stderr')); + } + console.log("## Script Execution Complete"); + } + catch (err) { + // troubleshoot link + const troubleshoot = "https://aka.ms/azurepowershelltroubleshooting"; + console.log(`##[error] run failed: For troubleshooting, refer: ${troubleshoot}`); + tl.setResult(tl.TaskResult.Failed, err.message || 'run() failed'); + } +} + + +run(); diff --git a/_generated/AzurePowerShellV4/icon.png b/_generated/AzurePowerShellV4/icon.png new file mode 100644 index 000000000000..039b77995289 Binary files /dev/null and b/_generated/AzurePowerShellV4/icon.png differ diff --git a/_generated/AzurePowerShellV4/icon.svg b/_generated/AzurePowerShellV4/icon.svg new file mode 100644 index 000000000000..9d97d76e24ec --- /dev/null +++ b/_generated/AzurePowerShellV4/icon.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/_generated/AzurePowerShellV4/make.json b/_generated/AzurePowerShellV4/make.json new file mode 100644 index 000000000000..6e4e2035caab --- /dev/null +++ b/_generated/AzurePowerShellV4/make.json @@ -0,0 +1,52 @@ +{ + "rm": [ + { + "items": [ + "node_modules/https-proxy-agent/node_modules/agent-base", + "node_modules/azure-pipelines-tasks-azure-arm-rest/node_modules/azure-pipelines-task-lib", + "node_modules/azure-pipelines-tasks-utility-common/node_modules/azure-pipelines-task-lib", + "node_modules/azure-pipelines-tool-lib/node_modules/azure-pipelines-task-lib" + ], + "options": "-Rf" + } + ], + "common": [ + { + "module": "../Common/VstsAzureHelpers_", + "type": "ps" + }, + { + "module": "../Common/TlsHelper_", + "type": "ps" + } + ], + "externals": { + "nugetv2": [ + { + "name": "VstsTaskSdk", + "version": "0.11.0", + "repository": "https://www.powershellgallery.com/api/v2/", + "cp": [ + { + "source": [ + "*.dll", + "*.ps1", + "*.psd1", + "*.psm1", + "lib.json", + "Strings" + ], + "dest": "ps_modules/VstsTaskSdk/", + "options": "-R" + } + ] + } + ], + "archivePackages": [ + { + "url": "https://vstsagenttools.blob.core.windows.net/tools/7zip/4/7zip.zip", + "dest": "./" + } + ] + } +} diff --git a/_generated/AzurePowerShellV4/package-lock.json b/_generated/AzurePowerShellV4/package-lock.json new file mode 100644 index 000000000000..4df893519494 --- /dev/null +++ b/_generated/AzurePowerShellV4/package-lock.json @@ -0,0 +1,859 @@ +{ + "name": "azure-powershell-v4", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@azure/msal-common": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-9.1.1.tgz", + "integrity": "sha512-we9xR8lvu47fF0h+J8KyXoRy9+G/fPzm3QEa2TrdR3jaVS3LKAyE2qyMuUkNdbVkvzl8Zr9f7l+IUSP22HeqXw==" + }, + "@azure/msal-node": { + "version": "1.14.5", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.5.tgz", + "integrity": "sha512-NcVdMfn8Z3ogN+9RjOSF7uwf2Gki5DEJl0BdDSL83KUAgVAobtkZi5W8EqxbJLrTO/ET0jv5DregrcR5qg2pEA==", + "requires": { + "@azure/msal-common": "^9.0.1", + "jsonwebtoken": "^8.5.1", + "uuid": "^8.3.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, + "@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "requires": { + "@types/node": "*" + } + }, + "@types/jsonwebtoken": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", + "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "16.18.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.39.tgz", + "integrity": "sha512-8q9ZexmdYYyc5/cfujaXb4YOucpQxAV4RMG0himLyDUOEr8Mr79VrqsFI+cQ2M2h89YIuy95lbxuYjxT4Hk4kQ==" + }, + "@types/q": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.0.7.tgz", + "integrity": "sha512-0WS7XU7sXzQ7J1nbnMKKYdjrrFoO3YtZYgUzeV8JFXffPnHfvSJQleR70I8BOAsOm14i4dyaAZ3YzqIl1YhkXQ==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + }, + "@types/uuid": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz", + "integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==" + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", + "requires": { + "tslib": "^2.4.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "azure-devops-node-api": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.1.0.tgz", + "integrity": "sha512-VY+G45eNKVJfMIO0uyZfbi4PzUR8JHEfsHQjEUAXUGRkYhhBbhGHjy8cpiyYFxLXc3a4PL5cqgqqV/YD1SaCXg==", + "requires": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "azure-pipelines-task-lib": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.4.0.tgz", + "integrity": "sha512-JgtxfjxjRA+KWY0Q5UC1fo48nkbVxFHgKEuasKdJMSNxHydOyNlB5MNw4UTiTXp9b0nnqKeOQOBn5RN3go3aPg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + } + }, + "azure-pipelines-tasks-azure-arm-rest": { + "version": "3.225.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-azure-arm-rest/-/azure-pipelines-tasks-azure-arm-rest-3.225.1.tgz", + "integrity": "sha512-fbRcoYKEbFj2jslocX4wV0hbnN/9ZGepdzcLI+5vdOkGcKNIdOctUNvggrN1KFg9nH+NoxK1pE4+kl316VVpMA==", + "requires": { + "@azure/msal-node": "1.14.5", + "@types/jsonwebtoken": "^8.5.8", + "@types/mocha": "^5.2.7", + "@types/node": "^10.17.0", + "@types/q": "1.5.4", + "async-mutex": "^0.4.0", + "azure-devops-node-api": "^12.0.0", + "azure-pipelines-task-lib": "^3.4.0", + "https-proxy-agent": "^4.0.0", + "jsonwebtoken": "^8.5.1", + "node-fetch": "^2.6.7", + "q": "1.5.1", + "typed-rest-client": "1.8.4", + "xml2js": "0.4.13" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" + }, + "azure-pipelines-task-lib": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.4.0.tgz", + "integrity": "sha512-3eC4OTFw+7xD7A2aUhxR/j+jRlTI+vVfS0CGxt1pCLs4c/KmY0tQWgbqjD3157kmiucWxELBvgZHaD2gCBe9fg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + } + } + } + }, + "azure-pipelines-tasks-utility-common": { + "version": "3.225.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-utility-common/-/azure-pipelines-tasks-utility-common-3.225.0.tgz", + "integrity": "sha512-Na7g1+zcsQpYogyex457QT6o9EB2+WQYwLUXPiszhTdf83hKJUmDMqvl2qm/mHqYuP1zg5KkRfJaPy4/09M8pA==", + "requires": { + "@types/node": "^16.11.39", + "azure-pipelines-task-lib": "^4.4.0", + "azure-pipelines-tool-lib": "^2.0.0-preview", + "js-yaml": "3.13.1", + "semver": "^5.4.1" + } + }, + "azure-pipelines-tool-lib": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/azure-pipelines-tool-lib/-/azure-pipelines-tool-lib-2.0.4.tgz", + "integrity": "sha512-LgAelZKJe3k/t3NsKSKzjeRviphns0w0p5tgwz8uHN70I9m2TToiOKl+fogrdXcM6+jiLBk5KTqrcRBqPpv/XA==", + "requires": { + "@types/semver": "^5.3.0", + "@types/uuid": "^3.4.5", + "azure-pipelines-task-lib": "^4.1.0", + "semver": "^5.7.0", + "semver-compare": "^1.0.0", + "typed-rest-client": "^1.8.6", + "uuid": "^3.3.2" + }, + "dependencies": { + "typed-rest-client": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + } + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + } + } + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + }, + "dependencies": { + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + } + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "requires": { + "has": "^1.0.3" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mockery": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-2.1.0.tgz", + "integrity": "sha512-9VkOmxKlWXoDO/h1jDZaS4lH33aWfRiJiNT/tKj+8OGzrcFDLo8d0syGdbsc3Bc4GvRXPb+NMMvojotmuGJTvA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "requires": { + "asap": "~2.0.6" + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + } + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "typed-rest-client": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.4.tgz", + "integrity": "sha512-MyfKKYzk3I6/QQp6e1T50py4qg+c+9BzOEl2rBmQIpStwNUoqQ73An+Tkfy9YuV7O+o2mpVVJpe+fH//POZkbg==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "typescript": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "dev": true + }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "xml2js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.13.tgz", + "integrity": "sha512-BoxD65qWA2p4znzbaati/Td19uFEc0X6ydj0bFphJO62RrNaGqOyW6ljLWPo3GKDbvW/6dnxAoRX01BsgEWsMA==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": ">=2.4.6" + } + }, + "xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==" + } + } +} diff --git a/_generated/AzurePowerShellV4/package.json b/_generated/AzurePowerShellV4/package.json new file mode 100644 index 000000000000..9d310c0b992f --- /dev/null +++ b/_generated/AzurePowerShellV4/package.json @@ -0,0 +1,18 @@ +{ + "name": "azure-powershell-v4", + "author": { + "name": "Microsoft Corporation" + }, + "dependencies": { + "@types/mocha": "^5.2.7", + "@types/node": "^16.11.39", + "@types/q": "1.0.7", + "agent-base": "6.0.2", + "azure-pipelines-task-lib": "^4.4.0", + "azure-pipelines-tasks-azure-arm-rest": "^3.225.1", + "azure-pipelines-tasks-utility-common": "^3.225.0" + }, + "devDependencies": { + "typescript": "4.0.2" + } +} diff --git a/_generated/AzurePowerShellV4/task.json b/_generated/AzurePowerShellV4/task.json new file mode 100644 index 000000000000..a4a1b586683d --- /dev/null +++ b/_generated/AzurePowerShellV4/task.json @@ -0,0 +1,217 @@ +{ + "id": "72A1931B-EFFB-4D2E-8FD8-F8472A07CB62", + "name": "AzurePowerShell", + "friendlyName": "Azure PowerShell", + "description": "Run a PowerShell script within an Azure environment", + "helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613749)", + "helpUrl": "https://aka.ms/azurepowershelltroubleshooting", + "category": "Deploy", + "visibility": [ + "Build", + "Release" + ], + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 4, + "Minor": 234, + "Patch": 0 + }, + "releaseNotes": "Added support for Az Module and cross platform agents.", + "groups": [ + { + "name": "AzurePowerShellVersionOptions", + "displayName": "Azure PowerShell version options", + "isExpanded": true + }, + { + "name": "advanced", + "displayName": "Advanced", + "isExpanded": false + } + ], + "minimumAgentVersion": "2.115.0", + "inputs": [ + { + "name": "ConnectedServiceNameARM", + "aliases": [ + "azureSubscription" + ], + "type": "connectedService:AzureRM", + "label": "Azure Subscription", + "defaultValue": "", + "required": true, + "helpMarkDown": "Azure Resource Manager subscription to configure before running PowerShell", + "properties": { + "EndpointFilterRule": "ScopeLevel != AzureMLWorkspace" + } + }, + { + "name": "ScriptType", + "type": "radio", + "label": "Script Type", + "required": false, + "helpMarkDown": "Type of the script: File Path or Inline Script", + "defaultValue": "FilePath", + "options": { + "FilePath": "Script File Path", + "InlineScript": "Inline Script" + } + }, + { + "name": "ScriptPath", + "type": "filePath", + "label": "Script Path", + "defaultValue": "", + "required": false, + "helpMarkDown": "Path of the script. Should be fully qualified path or relative to the default working directory.", + "visibleRule": "ScriptType = FilePath" + }, + { + "name": "Inline", + "type": "multiLine", + "label": "Inline Script", + "required": false, + "defaultValue": "# You can write your azure powershell scripts inline here. \n# You can also pass predefined and custom variables to this script using arguments", + "helpMarkDown": "Enter the script to execute.", + "visibleRule": "ScriptType = InlineScript", + "properties": { + "resizable": "true", + "rows": "10", + "maxLength": "5000" + } + }, + { + "name": "ScriptArguments", + "type": "string", + "label": "Script Arguments", + "defaultValue": "", + "visibleRule": "ScriptType = FilePath", + "required": false, + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + }, + "helpMarkDown": "Additional parameters to pass to PowerShell. Can be either ordinal or named parameters." + }, + { + "name": "errorActionPreference", + "type": "pickList", + "label": "ErrorActionPreference", + "required": false, + "defaultValue": "stop", + "options": { + "stop": "Stop", + "continue": "Continue", + "silentlyContinue": "SilentlyContinue" + }, + "helpMarkDown": "Select the value of the ErrorActionPreference variable for executing the script." + }, + { + "name": "FailOnStandardError", + "type": "boolean", + "label": "Fail on Standard Error", + "required": false, + "defaultValue": "false", + "helpMarkDown": "If this is true, this task will fail if any errors are written to the error pipeline, or if any data is written to the Standard Error stream." + }, + { + "name": "RestrictContextToCurrentTask", + "type": "boolean", + "label": "Restrict scope of context to current task", + "required": false, + "defaultValue": "false", + "helpMarkDown": "If this is true, this task will restrict the scope of context to current task only and the context will not be available to other tasks in the pipeline when using private agent." + }, + { + "name": "TargetAzurePs", + "aliases": [ + "azurePowerShellVersion" + ], + "type": "radio", + "label": "Azure PowerShell Version", + "defaultValue": "OtherVersion", + "required": false, + "options": { + "LatestVersion": "Latest installed version", + "OtherVersion": "Specify other version" + }, + "groupName": "AzurePowerShellVersionOptions", + "helpMarkDown": "In case of hosted agents, the supported Azure PowerShell Version is: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (Hosted VS2017 Queue).\nTo pick the latest version available on the agent, select \"Latest installed version\".\n\nFor private agents you can specify preferred version of Azure PowerShell using \"Specify version\"" + }, + { + "name": "CustomTargetAzurePs", + "aliases": [ + "preferredAzurePowerShellVersion" + ], + "type": "string", + "label": "Preferred Azure PowerShell Version", + "defaultValue": "", + "required": true, + "visibleRule": "TargetAzurePs = OtherVersion", + "groupName": "AzurePowerShellVersionOptions", + "helpMarkDown": "Preferred Azure PowerShell Version needs to be a proper semantic version eg. 1.2.3. Regex like 2.\\*,2.3.\\* is not supported. The Hosted VS2017 Pool currently supports Az module version: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0" + }, + { + "name": "pwsh", + "type": "boolean", + "label": "Use PowerShell Core", + "required": false, + "defaultValue": "false", + "helpMarkDown": "If this is true, then on Windows the task will use pwsh.exe from your PATH instead of powershell.exe.", + "groupName": "advanced" + }, + { + "name": "validateScriptSignature", + "type": "boolean", + "label": "Validate script signature", + "required": false, + "defaultValue": "false", + "helpMarkDown": "If this is true, then the task will first check to make sure specified script is signed and valid before executing it.", + "groupName": "advanced", + "visibleRule": "ScriptType = FilePath" + }, + { + "name": "workingDirectory", + "type": "filePath", + "label": "Working Directory", + "required": false, + "defaultValue": "", + "helpMarkDown": "Working directory where the script is run.", + "groupName": "advanced" + } + ], + "instanceNameFormat": "Azure PowerShell script: $(ScriptType)", + "execution": { + "PowerShell3": { + "target": "azurepowershell.ps1", + "platforms": [ + "windows" + ] + }, + "Node10": { + "target": "azurepowershell.js", + "argumentFormat": "" + }, + "Node16": { + "target": "azurepowershell.js", + "argumentFormat": "" + } + }, + "messages": { + "GeneratingScript": "Generating script.", + "JS_FormattedCommand": "Formatted command: %s", + "InvalidScriptArguments0": "Invalid script arguments '{0}'. Line breaks are not allowed.", + "InvalidScriptPath0": "Invalid script path '{0}'. Invalid path characters specified.", + "InvalidAzurePsVersion": "The Azure PowerShell version '{0}' specified is not in the correct format. Please check the format. An example of correct format is 1.0.1", + "JS_ExitCode": "PowerShell exited with code '%s'.", + "JS_Stderr": "PowerShell wrote one or more lines to the standard error stream.", + "ExpiredServicePrincipal": "Could not fetch access token for Azure. Verify if the Service Principal used is valid and not expired." + }, + "_buildConfigMapping": { + "Default": "4.234.0", + "Node20_229_2": "4.234.1" + } +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/task.loc.json b/_generated/AzurePowerShellV4/task.loc.json new file mode 100644 index 000000000000..5cab57b90782 --- /dev/null +++ b/_generated/AzurePowerShellV4/task.loc.json @@ -0,0 +1,217 @@ +{ + "id": "72A1931B-EFFB-4D2E-8FD8-F8472A07CB62", + "name": "AzurePowerShell", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "helpUrl": "https://aka.ms/azurepowershelltroubleshooting", + "category": "Deploy", + "visibility": [ + "Build", + "Release" + ], + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 4, + "Minor": 234, + "Patch": 0 + }, + "releaseNotes": "ms-resource:loc.releaseNotes", + "groups": [ + { + "name": "AzurePowerShellVersionOptions", + "displayName": "ms-resource:loc.group.displayName.AzurePowerShellVersionOptions", + "isExpanded": true + }, + { + "name": "advanced", + "displayName": "ms-resource:loc.group.displayName.advanced", + "isExpanded": false + } + ], + "minimumAgentVersion": "2.115.0", + "inputs": [ + { + "name": "ConnectedServiceNameARM", + "aliases": [ + "azureSubscription" + ], + "type": "connectedService:AzureRM", + "label": "ms-resource:loc.input.label.ConnectedServiceNameARM", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.ConnectedServiceNameARM", + "properties": { + "EndpointFilterRule": "ScopeLevel != AzureMLWorkspace" + } + }, + { + "name": "ScriptType", + "type": "radio", + "label": "ms-resource:loc.input.label.ScriptType", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.ScriptType", + "defaultValue": "FilePath", + "options": { + "FilePath": "Script File Path", + "InlineScript": "Inline Script" + } + }, + { + "name": "ScriptPath", + "type": "filePath", + "label": "ms-resource:loc.input.label.ScriptPath", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.ScriptPath", + "visibleRule": "ScriptType = FilePath" + }, + { + "name": "Inline", + "type": "multiLine", + "label": "ms-resource:loc.input.label.Inline", + "required": false, + "defaultValue": "# You can write your azure powershell scripts inline here. \n# You can also pass predefined and custom variables to this script using arguments", + "helpMarkDown": "ms-resource:loc.input.help.Inline", + "visibleRule": "ScriptType = InlineScript", + "properties": { + "resizable": "true", + "rows": "10", + "maxLength": "5000" + } + }, + { + "name": "ScriptArguments", + "type": "string", + "label": "ms-resource:loc.input.label.ScriptArguments", + "defaultValue": "", + "visibleRule": "ScriptType = FilePath", + "required": false, + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + }, + "helpMarkDown": "ms-resource:loc.input.help.ScriptArguments" + }, + { + "name": "errorActionPreference", + "type": "pickList", + "label": "ms-resource:loc.input.label.errorActionPreference", + "required": false, + "defaultValue": "stop", + "options": { + "stop": "Stop", + "continue": "Continue", + "silentlyContinue": "SilentlyContinue" + }, + "helpMarkDown": "ms-resource:loc.input.help.errorActionPreference" + }, + { + "name": "FailOnStandardError", + "type": "boolean", + "label": "ms-resource:loc.input.label.FailOnStandardError", + "required": false, + "defaultValue": "false", + "helpMarkDown": "ms-resource:loc.input.help.FailOnStandardError" + }, + { + "name": "RestrictContextToCurrentTask", + "type": "boolean", + "label": "ms-resource:loc.input.label.RestrictContextToCurrentTask", + "required": false, + "defaultValue": "false", + "helpMarkDown": "ms-resource:loc.input.help.RestrictContextToCurrentTask" + }, + { + "name": "TargetAzurePs", + "aliases": [ + "azurePowerShellVersion" + ], + "type": "radio", + "label": "ms-resource:loc.input.label.TargetAzurePs", + "defaultValue": "OtherVersion", + "required": false, + "options": { + "LatestVersion": "Latest installed version", + "OtherVersion": "Specify other version" + }, + "groupName": "AzurePowerShellVersionOptions", + "helpMarkDown": "ms-resource:loc.input.help.TargetAzurePs" + }, + { + "name": "CustomTargetAzurePs", + "aliases": [ + "preferredAzurePowerShellVersion" + ], + "type": "string", + "label": "ms-resource:loc.input.label.CustomTargetAzurePs", + "defaultValue": "", + "required": true, + "visibleRule": "TargetAzurePs = OtherVersion", + "groupName": "AzurePowerShellVersionOptions", + "helpMarkDown": "ms-resource:loc.input.help.CustomTargetAzurePs" + }, + { + "name": "pwsh", + "type": "boolean", + "label": "ms-resource:loc.input.label.pwsh", + "required": false, + "defaultValue": "false", + "helpMarkDown": "ms-resource:loc.input.help.pwsh", + "groupName": "advanced" + }, + { + "name": "validateScriptSignature", + "type": "boolean", + "label": "ms-resource:loc.input.label.validateScriptSignature", + "required": false, + "defaultValue": "false", + "helpMarkDown": "ms-resource:loc.input.help.validateScriptSignature", + "groupName": "advanced", + "visibleRule": "ScriptType = FilePath" + }, + { + "name": "workingDirectory", + "type": "filePath", + "label": "ms-resource:loc.input.label.workingDirectory", + "required": false, + "defaultValue": "", + "helpMarkDown": "ms-resource:loc.input.help.workingDirectory", + "groupName": "advanced" + } + ], + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "execution": { + "PowerShell3": { + "target": "azurepowershell.ps1", + "platforms": [ + "windows" + ] + }, + "Node10": { + "target": "azurepowershell.js", + "argumentFormat": "" + }, + "Node16": { + "target": "azurepowershell.js", + "argumentFormat": "" + } + }, + "messages": { + "GeneratingScript": "ms-resource:loc.messages.GeneratingScript", + "JS_FormattedCommand": "ms-resource:loc.messages.JS_FormattedCommand", + "InvalidScriptArguments0": "ms-resource:loc.messages.InvalidScriptArguments0", + "InvalidScriptPath0": "ms-resource:loc.messages.InvalidScriptPath0", + "InvalidAzurePsVersion": "ms-resource:loc.messages.InvalidAzurePsVersion", + "JS_ExitCode": "ms-resource:loc.messages.JS_ExitCode", + "JS_Stderr": "ms-resource:loc.messages.JS_Stderr", + "ExpiredServicePrincipal": "ms-resource:loc.messages.ExpiredServicePrincipal" + }, + "_buildConfigMapping": { + "Default": "4.234.0", + "Node20_229_2": "4.234.1" + } +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4/tsconfig.json b/_generated/AzurePowerShellV4/tsconfig.json new file mode 100644 index 000000000000..6a07b24acf54 --- /dev/null +++ b/_generated/AzurePowerShellV4/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs", + "skipLibCheck": true + } +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV4_Node20/task.json b/_generated/AzurePowerShellV4_Node20/task.json index fe172213b2d3..337dbfca7ee8 100644 --- a/_generated/AzurePowerShellV4_Node20/task.json +++ b/_generated/AzurePowerShellV4_Node20/task.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 1 }, "releaseNotes": "Added support for Az Module and cross platform agents.", "groups": [ @@ -215,7 +215,7 @@ "ExpiredServicePrincipal": "Could not fetch access token for Azure. Verify if the Service Principal used is valid and not expired." }, "_buildConfigMapping": { - "Default": "4.231.0", - "Node20_229_2": "4.231.2" + "Default": "4.234.0", + "Node20_229_2": "4.234.1" } } \ No newline at end of file diff --git a/_generated/AzurePowerShellV4_Node20/task.loc.json b/_generated/AzurePowerShellV4_Node20/task.loc.json index 4c741d5a9ebd..328e84159244 100644 --- a/_generated/AzurePowerShellV4_Node20/task.loc.json +++ b/_generated/AzurePowerShellV4_Node20/task.loc.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 4, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 1 }, "releaseNotes": "ms-resource:loc.releaseNotes", "groups": [ @@ -215,7 +215,7 @@ "ExpiredServicePrincipal": "ms-resource:loc.messages.ExpiredServicePrincipal" }, "_buildConfigMapping": { - "Default": "4.231.0", - "Node20_229_2": "4.231.2" + "Default": "4.234.0", + "Node20_229_2": "4.234.1" } } \ No newline at end of file diff --git a/_generated/AzurePowerShellV5.versionmap.txt b/_generated/AzurePowerShellV5.versionmap.txt index 5f75d031b10a..093b5dc77f7a 100644 --- a/_generated/AzurePowerShellV5.versionmap.txt +++ b/_generated/AzurePowerShellV5.versionmap.txt @@ -1,2 +1,2 @@ -Default|5.231.0 -Node20_229_2|5.231.2 +Default|5.234.0 +Node20_229_2|5.234.1 diff --git a/_generated/AzurePowerShellV5/AzurePowerShell.ps1 b/_generated/AzurePowerShellV5/AzurePowerShell.ps1 new file mode 100644 index 000000000000..a2bcc5ffb40e --- /dev/null +++ b/_generated/AzurePowerShellV5/AzurePowerShell.ps1 @@ -0,0 +1,199 @@ +Trace-VstsEnteringInvocation $MyInvocation +Import-VstsLocStrings "$PSScriptRoot\Task.json" + +# Get inputs. +$scriptType = Get-VstsInput -Name ScriptType -Require +$scriptPath = Get-VstsInput -Name ScriptPath +$scriptInline = Get-VstsInput -Name Inline +$scriptArguments = Get-VstsInput -Name ScriptArguments +$__vsts_input_errorActionPreference = Get-VstsInput -Name errorActionPreference +$__vsts_input_failOnStandardError = Get-VstsInput -Name FailOnStandardError -AsBool +$targetAzurePs = Get-VstsInput -Name TargetAzurePs +$customTargetAzurePs = Get-VstsInput -Name CustomTargetAzurePs +$input_pwsh = Get-VstsInput -Name pwsh -AsBool -Default $false +$input_workingDirectory = Get-VstsInput -Name workingDirectory -Require +$validateScriptSignature = Get-VstsInput -Name validateScriptSignature -AsBool + +# Validate the script path and args do not contains new-lines. Otherwise, it will +# break invoking the script via Invoke-Expression. +if ($scriptType -eq "FilePath") { + if ($scriptPath -match '[\r\n]' -or [string]::IsNullOrWhitespace($scriptPath)) { + throw (Get-VstsLocString -Key InvalidScriptPath0 -ArgumentList $scriptPath) + } +} + +if ($scriptArguments -match '[\r\n]') { + throw (Get-VstsLocString -Key InvalidScriptArguments0 -ArgumentList $scriptArguments) +} + +# string constants +$otherVersion = "OtherVersion" +$latestVersion = "LatestVersion" + +if ($targetAzurePs -eq $otherVersion) { + if ($null -eq $customTargetAzurePs) { + throw (Get-VstsLocString -Key InvalidAzurePsVersion $customTargetAzurePs) + } else { + $targetAzurePs = $customTargetAzurePs.Trim() + } +} + +$pattern = "^[0-9]+\.[0-9]+\.[0-9]+$" +$regex = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $pattern + +if ($targetAzurePs -eq $latestVersion) { + $targetAzurePs = "" +} elseif (-not($regex.IsMatch($targetAzurePs))) { + throw (Get-VstsLocString -Key InvalidAzurePsVersion -ArgumentList $targetAzurePs) +} + +. $PSScriptRoot\TryMakingModuleAvailable.ps1 -targetVersion "$targetAzurePs" -platform Windows + +if ($validateScriptSignature) { + try { + if ($scriptType -ne "InlineScript") { + Write-Host "## Validating Script Signature" + + # Validate script is signed + $scriptSignature = Get-AuthenticodeSignature $scriptPath + if ($scriptSignature.Status -eq "NotSigned") { + throw "Object does not have a digital signature. Please ensure your script is signed and try again." + } + elseif ($scriptSignature.Status -ne "Valid") { + throw "Digital signature of the object did not verify. Please ensure your script is properly signed and try again." + } + + Write-Host "## Validating Script Signature Complete" + } + } + catch + { + $errorMsg = $_.Exception.Message + throw "Unable to validate script signature: $errorMsg" + } +} + +. "$PSScriptRoot\Utility.ps1" + +$serviceName = Get-VstsInput -Name ConnectedServiceNameARM -Require +$endpointObject = Get-VstsEndpoint -Name $serviceName -Require +$endpoint = ConvertTo-Json $endpointObject +$vstsEndpoint = Get-VstsEndpoint -Name SystemVssConnection -Require +$vstsAccessToken = $vstsEndpoint.auth.parameters.AccessToken + +try +{ + # Generate the script contents. + Write-Host (Get-VstsLocString -Key 'GeneratingScript') + $contents = @() + $contents += "`$ErrorActionPreference = '$__vsts_input_errorActionPreference'" + if ($env:system_debug -eq "true") { + $contents += "`$VerbosePreference = 'continue'" + } + + $CoreAzArgument = "-endpoint '$endpoint' -connectedServiceNameARM $serviceName -vstsAccessToken $vstsAccessToken -isPSCore $" + "$input_pwsh" + if ($targetAzurePs) { + $CoreAzArgument += " -targetAzurePs $targetAzurePs" + } + $contents += ". '$PSScriptRoot\CoreAz.ps1' $CoreAzArgument" + + if ($scriptType -eq "InlineScript") { + $contents += "$scriptInline".Replace("`r`n", "`n").Replace("`n", "`r`n") + } else { + $contents += ". '$("$scriptPath".Replace("'", "''"))' $scriptArguments".Trim() + } + + # Write the script to disk. + $__vstsAzPSScriptPath = [System.IO.Path]::Combine($env:Agent_TempDirectory, ([guid]::NewGuid().ToString() + ".ps1")); + $joinedContents = [System.String]::Join( + ([System.Environment]::NewLine), + $contents) + $null = [System.IO.File]::WriteAllText( + $__vstsAzPSScriptPath, + $joinedContents, + ([System.Text.Encoding]::UTF8)) + + # Prepare the external command values. + # + # Note, use "-Command" instead of "-File". On PowerShell V5, V4 and V3 when using "-File", terminating + # errors do not cause a non-zero exit code. + if ($input_pwsh) { + $powershellPath = Get-Command -Name pwsh.exe -CommandType Application | Select-Object -First 1 -ExpandProperty Path + } else { + $powershellPath = Get-Command -Name powershell.exe -CommandType Application | Select-Object -First 1 -ExpandProperty Path + } + Assert-VstsPath -LiteralPath $powershellPath -PathType 'Leaf' + $arguments = "-NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command `". '$($__vstsAzPSScriptPath.Replace("'", "''"))'`"" + $splat = @{ + 'FileName' = $powershellPath + 'Arguments' = $arguments + 'WorkingDirectory' = $input_workingDirectory + } + + # Switch to "Continue". + $global:ErrorActionPreference = 'Continue' + $failed = $false + + # Run the script. + Write-Host '========================== Starting Command Output ===========================' + if (!$__vsts_input_failOnStandardError) { + Invoke-VstsTool @splat + } + else { + $inError = $false + $errorLines = New-Object System.Text.StringBuilder + Invoke-VstsTool @splat 2>&1 | + ForEach-Object { + if ($_ -is [System.Management.Automation.ErrorRecord]) { + # Buffer the error lines. + $failed = $true + $inError = $true + $null = $errorLines.AppendLine("$($_.Exception.Message)") + + # Write to verbose to mitigate if the process hangs. + Write-Verbose "STDERR: $($_.Exception.Message)" + } else { + # Flush the error buffer. + if ($inError) { + $inError = $false + $message = $errorLines.ToString().Trim() + $null = $errorLines.Clear() + if ($message) { + Write-VstsTaskError -Message $message + } + } + + Write-Host "$_" + } + } + + # Flush the error buffer one last time. + if ($inError) { + $inError = $false + $message = $errorLines.ToString().Trim() + $null = $errorLines.Clear() + if ($message) { + Write-VstsTaskError -Message $message + } + } + } + + if ($LASTEXITCODE -ne 0) { + $failed = $true + Write-VstsTaskError -Message (Get-VstsLocString -Key 'PS_ExitCode' -ArgumentList $LASTEXITCODE) + } + + # Fail if any errors. + if ($failed) { + Write-VstsSetResult -Result 'Failed' -Message "Error detected" -DoNotThrow + } +} +finally { + if ($__vstsAzPSInlineScriptPath -and (Test-Path -LiteralPath $__vstsAzPSInlineScriptPath) ) { + Remove-Item -LiteralPath $__vstsAzPSInlineScriptPath -ErrorAction 'SilentlyContinue' + } + + Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_ + Remove-EndpointSecrets + Disconnect-AzureAndClearContext -ErrorAction SilentlyContinue +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/CoreAz.ps1 b/_generated/AzurePowerShellV5/CoreAz.ps1 new file mode 100644 index 000000000000..b78884c0be5f --- /dev/null +++ b/_generated/AzurePowerShellV5/CoreAz.ps1 @@ -0,0 +1,32 @@ +[CmdletBinding()] +param +( + [String] [Parameter(Mandatory = $true)] + $endpoint, + + [String] [Parameter(Mandatory = $false)] + $connectedServiceNameARM, + + [String] [Parameter(Mandatory = $false)] + $targetAzurePs, + + [bool] [Parameter(Mandatory = $false)] + $isPSCore, + + [String] [Parameter(Mandatory = $false)] + $vstsAccessToken +) + +Import-Module "$PSScriptRoot\ps_modules\VstsTaskSdk" -ArgumentList @{ NonInteractive = $true } +Import-VstsLocStrings -LiteralPath "$PSScriptRoot\task.json" + +# Update PSModulePath for hosted agent +. "$PSScriptRoot\Utility.ps1" +CleanUp-PSModulePathForHostedAgent +Update-PSModulePathForHostedAgent -targetAzurePs $targetAzurePs + +$endpointObject = ConvertFrom-Json $endpoint +Import-Module "$PSScriptRoot\ps_modules\VstsAzureHelpers_" +$encryptedToken = ConvertTo-SecureString $vstsAccessToken -AsPlainText -Force +Initialize-AzModule -Endpoint $endpointObject -connectedServiceNameARM $connectedServiceNameARM ` + -azVersion $targetAzurePs -isPSCore $isPSCore -encryptedToken $encryptedToken \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/InitializeAz.ps1 b/_generated/AzurePowerShellV5/InitializeAz.ps1 new file mode 100644 index 000000000000..f820acb0bf50 --- /dev/null +++ b/_generated/AzurePowerShellV5/InitializeAz.ps1 @@ -0,0 +1,122 @@ +[CmdletBinding()] +param +( + [String] [Parameter(Mandatory = $true)] + $endpoint, + [String] [Parameter(Mandatory = $false)] + $targetAzurePs, + [String] [Parameter(Mandatory = $false)] + $clientAssertionJwt +) + +$endpointObject = ConvertFrom-Json $endpoint +$moduleName = "Az.Accounts" +$environmentName = $endpointObject.environment + +. "$PSScriptRoot/Utility.ps1" +Update-PSModulePathForHostedAgentLinux -targetAzurePs $targetAzurePs + +if ($targetAzurePs -eq "") { + $module = Get-Module -Name $moduleName -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1 +} +else{ + $modules = Get-Module -Name $moduleName -ListAvailable + foreach ($moduleVal in $modules) { + # $moduleVal.Path will have value like /usr/local/share/powershell/Modules/Az.Accounts/1.2.1/Az.Accounts.psd1 + $azModulePath = Split-Path (Split-Path (Split-Path $moduleVal.Path -Parent) -Parent) -Parent + $azModulePath = $azModulePath + "/Az/*" + $azModuleVersion = split-path -path $azModulePath -Leaf -Resolve + if ($azModuleVersion -eq $targetAzurePs) { + $module = $moduleVal + break + } + } +} + +if (!$module) { + # Will handle localization later + Write-Verbose "No module found with name: $moduleName" + throw ("Could not find the module Az.Accounts with given version. If the module was recently installed, retry after restarting the Azure Pipelines task agent.") +} + +# Import the module. +Write-Host "##[command]Import-Module -Name $($module.Path) -Global" +$module = Import-Module -Name $module.Path -Global -PassThru -Force + +# Clear context +Write-Host "##[command]Clear-AzContext -Scope Process" +$null = Clear-AzContext -Scope Process +Write-Host "##[command]Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue" +$null = Clear-AzContext -Scope CurrentUser -Force -ErrorAction SilentlyContinue + +$scopeLevel = "Subscription" +if ($endpointObject.scopeLevel) { + $scopeLevel = $endpointObject.scopeLevel +} +$processScope = @{ Scope = "Process" } + +function Format-Splat { + [CmdletBinding()] + param([Parameter(Mandatory = $true)][hashtable]$Hashtable) + + # Collect the parameters (names and values) in an array. + $parameters = foreach ($key in $Hashtable.Keys) { + $value = $Hashtable[$key] + # If the value is a bool, format the parameter as a switch (ending with ':'). + if ($value -is [bool]) { "-$($key):" } else { "-$key" } + $value + } + + "$parameters" # String join the array. +} + +if ($endpointObject.scheme -eq 'ServicePrincipal') { + Write-Verbose "Using ServicePrincipal authentication scheme" + try { + if ($endpointObject.authenticationType -ieq 'SPNKey') { + $psCredential = New-Object System.Management.Automation.PSCredential( + $endpointObject.servicePrincipalClientID, + (ConvertTo-SecureString $endpointObject.servicePrincipalKey -AsPlainText -Force)) + Write-Host "##[command]Connect-AzAccount -ServicePrincipal -Tenant $($endpointObject.tenantId) -Credential $psCredential -Environment $environmentName @processScope" + $null = Connect-AzAccount -ServicePrincipal -Tenant $endpointObject.tenantId ` + -Credential $psCredential ` + -Environment $environmentName @processScope -WarningAction SilentlyContinue + } + else { + # Provide an additional, custom, credentials-related error message. Will handle localization later + throw ("Only SPNKey auth type is supported for ServicePrincipal auth scheme using non windows agent.") + } + } + catch { + # Provide an additional, custom, credentials-related error message. Will handle localization later + Write-Host "Exception is : $($_.Exception.Message)" + throw (New-Object System.Exception("There was an error with the service principal used for the deployment.", $_.Exception)) + } + + if ($scopeLevel -eq "Subscription") { + $SubscriptionId = $endpointObject.subscriptionId + $TenantId = $endpointObject.tenantId + $additional = @{ TenantId = $TenantId } + + Write-Host "##[command] Set-AzContext -SubscriptionId $SubscriptionId $(Format-Splat $additional)" + $null = Set-AzContext -SubscriptionId $SubscriptionId @additional + } +} +elseif ($endpointObject.scheme -eq 'WorkloadIdentityFederation') { + Write-Verbose "Using WorkloadIdentityFederation authentication scheme" + + $logStr = "##[command] Connect-AzAccount -ServicePrincipal -Tenant $($endpointObject.tenantId) -ApplicationId $($endpointObject.servicePrincipalClientID)" + $logStr += " -FederatedToken ***** -Environment $environmentName -Scope Process" + Write-Host $logStr + Connect-AzAccount -ServicePrincipal -Tenant $endpointObject.tenantId -ApplicationId $endpointObject.servicePrincipalClientID ` + -FederatedToken $clientAssertionJwt -Environment $environmentName -Scope 'Process' + + if ($scopeLevel -ne "ManagementGroup") { + Write-Host "##[command] Set-AzContext -SubscriptionId $($endpointObject.subscriptionID) -TenantId $($endpointObject.tenantId)" + Set-AzContext -SubscriptionId $endpointObject.subscriptionID -TenantId $endpointObject.tenantId + } +} +else { + # Provide an additional, custom, credentials-related error message. Will handle localization later + throw ("Only SPN credential and WorkloadIdentityFederation auth schemes are supported for non windows agent.") +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/de-DE/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/de-DE/resources.resjson new file mode 100644 index 000000000000..4d9a18a84ffa --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/de-DE/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[Weitere Informationen zu dieser Aufgabe](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "PowerShell-Skript innerhalb einer Azure-Umgebung ausführen", + "loc.instanceNameFormat": "Azure PowerShell-Skript: $(ScriptType)", + "loc.releaseNotes": "Unterstützung für Az-Modul und plattformübergreifende Agents hinzugefügt.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell-Versionsoptionen", + "loc.group.displayName.advanced": "Erweitert", + "loc.input.label.ConnectedServiceNameARM": "Azure-Abonnement", + "loc.input.help.ConnectedServiceNameARM": "Azure Resource Manager-Abonnement, das vor dem Ausführen von PowerShell konfiguriert wird.", + "loc.input.label.ScriptType": "Skripttyp", + "loc.input.help.ScriptType": "Der Typ des Skripts: Dateipfad oder Inlineskript.", + "loc.input.label.ScriptPath": "Skriptpfad", + "loc.input.help.ScriptPath": "Der Pfad des Skripts. Es muss sich um den vollqualifizierten Pfad oder einen Pfad relativ zum Standardarbeitsverzeichnis handeln.", + "loc.input.label.Inline": "Inlineskript", + "loc.input.help.Inline": "Geben Sie das Skript ein, das ausgeführt werden soll.", + "loc.input.label.ScriptArguments": "Skriptargumente", + "loc.input.help.ScriptArguments": "Zusätzliche Argumente, die an PowerShell übergeben werden sollen. Entweder Ordnungszahl- oder benannte Parameter.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Wählen Sie den Wert der Variablen \"ErrorActionPreference\" für die Skriptausführung.", + "loc.input.label.FailOnStandardError": "Fehler bei Standardfehler.", + "loc.input.help.FailOnStandardError": "Wenn dieser Wert TRUE ist, tritt ein Aufgabenfehler auf, wenn Fehler in die Fehlerpipeline oder Daten in den Standard-Fehlerdatenstrom geschrieben werden.", + "loc.input.label.TargetAzurePs": "Azure PowerShell-Version", + "loc.input.help.TargetAzurePs": "Im Falle gehosteter Agents werden die folgenden Azure PowerShell-Versionen unterstützt: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (gehostete VS2017-Warteschlange).\nWenn Sie die neueste für den Agent verfügbare Version auswählen möchten, wählen Sie \"Neueste installierte Version\" aus.\n\nFür private Agents können Sie mithilfe von \"Version angeben\" die bevorzugte Version von Azure PowerShell festlegen.", + "loc.input.label.CustomTargetAzurePs": "Bevorzugte Azure PowerShell-Version", + "loc.input.help.CustomTargetAzurePs": "Die bevorzugte Azure PowerShell-Version muss einem ordnungsgemäßen semantischen Versionsmuster folgen, z. B. \"1.2.3\". Reguläre Ausdrücke wie 2.\\*,2.3.\\* werden nicht unterstützt. Der gehostete VS2017-Pool unterstützt aktuell die folgenden Az-Modulversionen: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "PowerShell Core verwenden", + "loc.input.help.pwsh": "Sofern TRUE, verwendet die Aufgabe unter Windows anstelle von \"powershell.exe\" die in PATH festgelegte \"pwsh.exe\".", + "loc.input.label.validateScriptSignature": "Skriptsignatur überprüfen", + "loc.input.help.validateScriptSignature": "Wenn dies der Fall ist, überprüft die Aufgabe zunächst, ob das angegebene Skript signiert und gültig ist, bevor es ausgeführt wird.", + "loc.input.label.workingDirectory": "Arbeitsverzeichnis", + "loc.input.help.workingDirectory": "Arbeitsverzeichnis zum Ausführen des Skripts.", + "loc.messages.GeneratingScript": "Skript wird erstellt.", + "loc.messages.JS_FormattedCommand": "Formatierter Befehl: %s", + "loc.messages.InvalidScriptArguments0": "Ungültige Skriptargumente \"{0}\". Zeilenumbrüche sind unzulässig.", + "loc.messages.InvalidScriptPath0": "Ungültiger Skriptpfad \"{0}\". Es wurden ungültige Pfadzeichen angegeben.", + "loc.messages.InvalidAzurePsVersion": "Die angegebene Azure PowerShell-Version \"{0}\" weist nicht das richtige Format auf. Überprüfen Sie das Format. Ein Beispiel für das richtige Format ist etwa 1.0.1.", + "loc.messages.JS_ExitCode": "PowerShell wurde beendet mit dem Code \"%s\".", + "loc.messages.JS_Stderr": "PowerShell hat mindestens eine Zeile in den Standardfehlerstream geschrieben.", + "loc.messages.ExpiredServicePrincipal": "Das Zugriffstoken für Azure konnte nicht abgerufen werden. Stellen Sie sicher, dass der verwendete Dienstprinzipal gültig und nicht abgelaufen ist.", + "loc.messages.PS_ExitCode": "PowerShell wurde beendet mit dem Code \"{0}\"." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/en-US/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..e64b310b685a --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Run a PowerShell script within an Azure environment", + "loc.instanceNameFormat": "Azure PowerShell script: $(ScriptType)", + "loc.releaseNotes": "Added support for Az Module and cross platform agents.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell version options", + "loc.group.displayName.advanced": "Advanced", + "loc.input.label.ConnectedServiceNameARM": "Azure Subscription", + "loc.input.help.ConnectedServiceNameARM": "Azure Resource Manager subscription to configure before running PowerShell", + "loc.input.label.ScriptType": "Script Type", + "loc.input.help.ScriptType": "Type of the script: File Path or Inline Script", + "loc.input.label.ScriptPath": "Script Path", + "loc.input.help.ScriptPath": "Path of the script. Should be fully qualified path or relative to the default working directory.", + "loc.input.label.Inline": "Inline Script", + "loc.input.help.Inline": "Enter the script to execute.", + "loc.input.label.ScriptArguments": "Script Arguments", + "loc.input.help.ScriptArguments": "Additional parameters to pass to PowerShell. Can be either ordinal or named parameters.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Select the value of the ErrorActionPreference variable for executing the script.", + "loc.input.label.FailOnStandardError": "Fail on Standard Error", + "loc.input.help.FailOnStandardError": "If this is true, this task will fail if any errors are written to the error pipeline, or if any data is written to the Standard Error stream.", + "loc.input.label.TargetAzurePs": "Azure PowerShell Version", + "loc.input.help.TargetAzurePs": "In case of hosted agents, the supported Azure PowerShell Version is: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (Hosted VS2017 Queue).\nTo pick the latest version available on the agent, select \"Latest installed version\".\n\nFor private agents you can specify preferred version of Azure PowerShell using \"Specify version\"", + "loc.input.label.CustomTargetAzurePs": "Preferred Azure PowerShell Version", + "loc.input.help.CustomTargetAzurePs": "Preferred Azure PowerShell Version needs to be a proper semantic version eg. 1.2.3. Regex like 2.\\*,2.3.\\* is not supported. The Hosted VS2017 Pool currently supports Az module version: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "Use PowerShell Core", + "loc.input.help.pwsh": "If this is true, then on Windows the task will use pwsh.exe from your PATH instead of powershell.exe.", + "loc.input.label.validateScriptSignature": "Validate script signature", + "loc.input.help.validateScriptSignature": "If this is true, then the task will first check to make sure specified script is signed and valid before executing it.", + "loc.input.label.workingDirectory": "Working Directory", + "loc.input.help.workingDirectory": "Working directory where the script is run.", + "loc.messages.GeneratingScript": "Generating script.", + "loc.messages.JS_FormattedCommand": "Formatted command: %s", + "loc.messages.InvalidScriptArguments0": "Invalid script arguments '{0}'. Line breaks are not allowed.", + "loc.messages.InvalidScriptPath0": "Invalid script path '{0}'. Invalid path characters specified.", + "loc.messages.InvalidAzurePsVersion": "The Azure PowerShell version '{0}' specified is not in the correct format. Please check the format. An example of correct format is 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell exited with code '%s'.", + "loc.messages.JS_Stderr": "PowerShell wrote one or more lines to the standard error stream.", + "loc.messages.ExpiredServicePrincipal": "Could not fetch access token for Azure. Verify if the Service Principal used is valid and not expired.", + "loc.messages.PS_ExitCode": "PowerShell exited with code '{0}'." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/es-ES/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/es-ES/resources.resjson new file mode 100644 index 000000000000..1953d36b3225 --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/es-ES/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[Obtener más información acerca de esta tarea](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Ejecutar un script de PowerShell en un entorno de Azure", + "loc.instanceNameFormat": "Script de Azure PowerShell: $(ScriptType)", + "loc.releaseNotes": "Se ha agregado compatibilidad con el módulo Az y los agentes multiplataforma.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Opciones de versión de Azure PowerShell", + "loc.group.displayName.advanced": "Avanzado", + "loc.input.label.ConnectedServiceNameARM": "Suscripción a Azure", + "loc.input.help.ConnectedServiceNameARM": "Suscripción de Azure Resource Manager para configurar antes de ejecutar PowerShell", + "loc.input.label.ScriptType": "Tipo de script", + "loc.input.help.ScriptType": "Tipo del script: ruta de acceso del archivo o script en línea", + "loc.input.label.ScriptPath": "Ruta de acceso del script", + "loc.input.help.ScriptPath": "Ruta de acceso del script. Debe ser una ruta de acceso completa o relativa al directorio de trabajo predeterminado.", + "loc.input.label.Inline": "Script alineado", + "loc.input.help.Inline": "Escriba el script que se va a ejecutar.", + "loc.input.label.ScriptArguments": "Argumentos de script", + "loc.input.help.ScriptArguments": "Parámetros adicionales que pasar a PowerShell. Pueden ser parámetros ordinales o con nombre.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Seleccione el valor de la variable ErrorActionPreference para ejecutar el script.", + "loc.input.label.FailOnStandardError": "Error si se produce un error estándar", + "loc.input.help.FailOnStandardError": "Si es true, se producirá un error en la tarea si se escriben errores en la canalización de errores o si se escriben datos en el flujo de error estándar.", + "loc.input.label.TargetAzurePs": "Versión de Azure PowerShell", + "loc.input.help.TargetAzurePs": "En el caso de los agentes hospedados, las versiones de Azure PowerShell admitidas son 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (Hosted VS2017 Queue).\nPara seleccionar la última versión disponible en el agente, seleccione \"Latest installed version\".\n\nPara los agentes privados, puede especificar la versión de Azure PowerShell que prefiera con la opción \"Specify version\"", + "loc.input.label.CustomTargetAzurePs": "Versión de Azure PowerShell preferida", + "loc.input.help.CustomTargetAzurePs": "La versión preferida de Azure PowerShell debe ser una versión de semántica adecuada, por ejemplo, 1.2.3. No se admite una notación regex como 2.\\*,2.3.\\*. El grupo Hosted VS2017 Pool es compatible con las versiones del módulo Az 1.0.0, 1.6.0, 2.3.2, 2.6.0 y 3.1.0", + "loc.input.label.pwsh": "Usar PowerShell Core", + "loc.input.help.pwsh": "Si es true, la tarea usará pwsh.exe desde PATH en lugar de powershell.exe en Windows.", + "loc.input.label.validateScriptSignature": "Validación de la firma del script", + "loc.input.help.validateScriptSignature": "Si es true, la tarea comprobará primero para asegurarse de que el script especificado está firmado y es válido antes de ejecutarlo.", + "loc.input.label.workingDirectory": "Directorio de trabajo", + "loc.input.help.workingDirectory": "Directorio de trabajo donde se ejecuta el script.", + "loc.messages.GeneratingScript": "Generando script.", + "loc.messages.JS_FormattedCommand": "Comando con formato: %s", + "loc.messages.InvalidScriptArguments0": "Argumentos de script '{0}' no válidos. No se permiten los saltos de línea.", + "loc.messages.InvalidScriptPath0": "Ruta del script '{0}' no válida. Los caracteres de ruta de acceso especificados no son válidos.", + "loc.messages.InvalidAzurePsVersion": "La versión de Azure PowerShell \"{0}\" especificada no tiene el formato correcto. Compruebe el formato. Ejemplo de formato correcto: 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell se cerró con el código \"%s\".", + "loc.messages.JS_Stderr": "PowerShell escribió una o varias líneas en la secuencia de error estándar.", + "loc.messages.ExpiredServicePrincipal": "No se pudo capturar el token de acceso de Azure. Compruebe que la entidad de servicio usada es válida y no ha expirado.", + "loc.messages.PS_ExitCode": "PowerShell se cerró con el código \"{0}\"." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/fr-FR/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/fr-FR/resources.resjson new file mode 100644 index 000000000000..415241dc76b2 --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/fr-FR/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[En savoir plus sur cette tâche](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Exécuter un script PowerShell dans un environnement Azure", + "loc.instanceNameFormat": "Script Azure PowerShell : $(ScriptType)", + "loc.releaseNotes": "Ajout de la prise en charge du module Azure et des agents multiplateformes.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Options de version Azure PowerShell", + "loc.group.displayName.advanced": "Avancé", + "loc.input.label.ConnectedServiceNameARM": "Abonnement Azure", + "loc.input.help.ConnectedServiceNameARM": "Abonnement Azure Resource Manager à configurer avant d'exécuter PowerShell", + "loc.input.label.ScriptType": "Type de script", + "loc.input.help.ScriptType": "Type du script : chemin de fichier ou script inline", + "loc.input.label.ScriptPath": "Chemin d'accès du script", + "loc.input.help.ScriptPath": "Chemin d'accès du script. Doit être un chemin d'accès complet ou relatif au répertoire de travail par défaut.", + "loc.input.label.Inline": "Script inline", + "loc.input.help.Inline": "Entrez le script à exécuter.", + "loc.input.label.ScriptArguments": "Arguments de script", + "loc.input.help.ScriptArguments": "Paramètres supplémentaires à passer à PowerShell. Peuvent être des paramètres ordinaux ou nommés.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Sélectionnez la valeur de la variable ErrorActionPreference pour l'exécution du script.", + "loc.input.label.FailOnStandardError": "Échec sur une erreur standard", + "loc.input.help.FailOnStandardError": "Si la valeur est true, et si des erreurs sont écrites dans le pipeline d'erreurs ou si des données sont écrites dans le flux d'erreurs standard, cette tâche se solde par un échec.", + "loc.input.label.TargetAzurePs": "Version d'Azure PowerShell", + "loc.input.help.TargetAzurePs": "Dans le cas d'agents hébergés, les versions d'Azure PowerShell prises en charge sont les suivantes : 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (file d'attente VS2017 hébergée).\nPour choisir la dernière version disponible sur l'agent, sélectionnez \"Dernière version installée\".\n\nPour les agents privés, vous pouvez spécifier la version par défaut d'Azure PowerShell via \"Spécifier la version\"", + "loc.input.label.CustomTargetAzurePs": "Version préférée d'Azure PowerShell", + "loc.input.help.CustomTargetAzurePs": "La version par défaut d'Azure PowerShell doit être une version sémantique appropriée, par exemple 1.2.3. La notation regex telle que 2.\\*,2.3.\\* n'est pas prise en charge. Le pool VS2017 hébergé prend en charge les versions de module Az suivantes : 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "Utilisez PowerShell Core", + "loc.input.help.pwsh": "Si la valeur est true, dans Windows, la tâche utilise pwsh.exe à partir de votre variable PATH au lieu de powershell.exe.", + "loc.input.label.validateScriptSignature": "Valider la signature du script", + "loc.input.help.validateScriptSignature": "Si la valeur est true, la tâche vérifie d’abord que le script spécifié est signé et valide avant de l’exécuter.", + "loc.input.label.workingDirectory": "Répertoire de travail", + "loc.input.help.workingDirectory": "Répertoire de travail où le script est exécuté.", + "loc.messages.GeneratingScript": "Génération du script.", + "loc.messages.JS_FormattedCommand": "Commande mise en forme : %s", + "loc.messages.InvalidScriptArguments0": "Arguments de script '{0}' non valides. Les sauts de ligne ne sont pas autorisés.", + "loc.messages.InvalidScriptPath0": "Chemin de script '{0}' non valide. Caractères non valides spécifiés dans le chemin.", + "loc.messages.InvalidAzurePsVersion": "La version '{0}' spécifiée pour Azure PowerShell n'est pas au format approprié. Vérifiez le format. Exemple de format correct : 1.0.1", + "loc.messages.JS_ExitCode": "Arrêt de PowerShell. Code de sortie : '%s'.", + "loc.messages.JS_Stderr": "PowerShell a écrit une ou plusieurs lignes dans le flux d'erreurs standard.", + "loc.messages.ExpiredServicePrincipal": "Impossible de récupérer (fetch) le jeton d'accès pour Azure. Vérifiez si le principal de service utilisé est valide et s'il n'a pas expiré.", + "loc.messages.PS_ExitCode": "Arrêt de PowerShell. Code de sortie : '{0}'." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/it-IT/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/it-IT/resources.resjson new file mode 100644 index 000000000000..1e89ea59c698 --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/it-IT/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[Altre informazioni su questa attività](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Consente di eseguire uno script PowerShell in un ambiente Azure", + "loc.instanceNameFormat": "Script Azure PowerShell: $(ScriptType)", + "loc.releaseNotes": "È stato aggiunto il supporto per il modulo AZ e gli agenti multipiattaforma.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Opzioni della versione di Azure PowerShell", + "loc.group.displayName.advanced": "Avanzate", + "loc.input.label.ConnectedServiceNameARM": "Sottoscrizione di Azure", + "loc.input.help.ConnectedServiceNameARM": "Sottoscrizione di Azure Resource Manager da configurare prima di eseguire PowerShell", + "loc.input.label.ScriptType": "Tipo di script", + "loc.input.help.ScriptType": "Tipo dello script: Percorso file o Script inline", + "loc.input.label.ScriptPath": "Percorso script", + "loc.input.help.ScriptPath": "Percorso dello script. Deve essere un percorso completo o relativo rispetto alla directory di lavoro predefinita.", + "loc.input.label.Inline": "Script inline", + "loc.input.help.Inline": "Consente di immettere lo script da eseguire.", + "loc.input.label.ScriptArguments": "Argomenti script", + "loc.input.help.ScriptArguments": "Parametri aggiuntivi da passare a PowerShell. Possono essere ordinali o denominati.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Consente di selezionare il valore della variabile ErrorActionPreference per l'esecuzione dello script.", + "loc.input.label.FailOnStandardError": "Interrompi in caso di errore standard", + "loc.input.help.FailOnStandardError": "Se il valore è true, questa attività non riuscirà nel caso in cui vengano scritti errori nella pipeline degli errori oppure se vengono scritti dati nel flusso STDERR.", + "loc.input.label.TargetAzurePs": "Versione di Azure PowerShell", + "loc.input.help.TargetAzurePs": "In caso di agenti ospitati la versione supportata di Azure PowerShell è: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (Hosted VS2017 Queue).\nPer selezionare l'ultima versione disponibile per l'agente ospitato, selezionare \"Ultima versione installata\".\n\nPer gli agenti privati è possibile selezionare \"Specifica versione\" per specificare la versione preferita di Azure PowerShell", + "loc.input.label.CustomTargetAzurePs": "Versione preferita di Azure PowerShell", + "loc.input.help.CustomTargetAzurePs": "La versione preferita di Azure PowerShell deve essere una versione semantica valida, ad esempio 1.2.3. Espressioni regolari come 2.\\*,2.3.\\* non sono supportate. La versione Hosted VS2017 Pool supporta attualmente le versioni seguenti del modulo Az: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "Usa PowerShell Core", + "loc.input.help.pwsh": "Se è impostata su true, in Windows l'attività userà pwsh.exe da PATH invece di powershell.exe.", + "loc.input.label.validateScriptSignature": "Convalida firma script", + "loc.input.help.validateScriptSignature": "Se è True, l'attività verificherà innanzitutto che lo script specificato sia firmato e valido prima di eseguirlo.", + "loc.input.label.workingDirectory": "Directory di lavoro", + "loc.input.help.workingDirectory": "Directory di lavoro in cui viene eseguito lo script.", + "loc.messages.GeneratingScript": "Generazione dello script.", + "loc.messages.JS_FormattedCommand": "Comando formattato: %s", + "loc.messages.InvalidScriptArguments0": "Gli argomenti '{0}' dello script non sono validi. Le interruzioni di riga non sono consentite.", + "loc.messages.InvalidScriptPath0": "Il percorso '{0}' dello script non è valido. Sono stati specificati caratteri non validi.", + "loc.messages.InvalidAzurePsVersion": "Il formato della versione di Azure PowerShell '{0}' specificata non è corretto. Controllare il formato. Un esempio di formato corretto è 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell terminato con codice '%s'.", + "loc.messages.JS_Stderr": "PowerShell ha scritto una o più righe nel flusso di errore standard.", + "loc.messages.ExpiredServicePrincipal": "Non è stato possibile recuperare il token di accesso per Azure. Verificare che l'entità servizio usata sia valida e non sia scaduta.", + "loc.messages.PS_ExitCode": "PowerShell terminato con codice '{0}'." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/ja-JP/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/ja-JP/resources.resjson new file mode 100644 index 000000000000..f2b1b4f51de3 --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/ja-JP/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[このタスクの詳細を表示](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Azure 環境内で PowerShell スクリプトを実行します", + "loc.instanceNameFormat": "Azure PowerShell スクリプト: $(ScriptType)", + "loc.releaseNotes": "Az モジュールとクロス プラットフォームのエージェントのサポートが追加されました。", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell バージョンのオプション", + "loc.group.displayName.advanced": "詳細設定", + "loc.input.label.ConnectedServiceNameARM": "Azure サブスクリプション", + "loc.input.help.ConnectedServiceNameARM": "PowerShell を実行する前に構成する Azure Resource Manager サブスクリプション", + "loc.input.label.ScriptType": "スクリプトの種類", + "loc.input.help.ScriptType": "スクリプトの種類: ファイル パスまたはインライン スクリプト", + "loc.input.label.ScriptPath": "スクリプト パス", + "loc.input.help.ScriptPath": "スクリプトのパス。完全修飾パスか、既定の作業ディレクトリを基準とした相対パスのいずれかです。", + "loc.input.label.Inline": "インライン スクリプト", + "loc.input.help.Inline": "実行するスクリプトを入力します。", + "loc.input.label.ScriptArguments": "スクリプトの引数", + "loc.input.help.ScriptArguments": "PowerShell に渡す追加のパラメーター。順序によるパラメーターまたは名前指定されたパラメーターのいずれかです。", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "スクリプトを実行するための ErrorActionPreference 変数の値を選択します。", + "loc.input.label.FailOnStandardError": "標準エラーで失敗", + "loc.input.help.FailOnStandardError": "これが true の場合、何らかのエラーがエラー パイプラインに書き込まれるか、何らかのデータが標準エラー ストリームに書き込まれる場合、このタスクは失敗します。", + "loc.input.label.TargetAzurePs": "Azure PowerShell バージョン", + "loc.input.help.TargetAzurePs": "ホステッド エージェントの場合、サポートされている Azure PowerShell のバージョンは、1.0.0、1.6.0、2.3.2、2.6.0、3.1.0 (ホステッド VS2017 キュー) です。\nエージェントで利用可能な最新バージョンを選ぶには、[Latest installed version](インストールされている最新バージョン) を選択します。\n\nプライベート エージェントの場合は、[Specify version](バージョンを指定する) を使用して優先されるバージョンの Azure PowerShell を指定できます。", + "loc.input.label.CustomTargetAzurePs": "優先される Azure PowerShell バージョン", + "loc.input.help.CustomTargetAzurePs": "優先される Azure PowerShell バージョンは、1.2.3 などの適切なセマンティック バージョンである必要があります。2.\\*、2.3.\\* などの正規表現はサポートされていません。ホステッド VS2017 プールは、現在次の Az モジュール バージョンをサポートしています: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0", + "loc.input.label.pwsh": "PowerShell Core を使用する", + "loc.input.help.pwsh": "これが true の場合、Windows 上のタスクは powershell.exe ではなく PATH からの pwsh.exe を使用します。", + "loc.input.label.validateScriptSignature": "スクリプトの署名を検証する", + "loc.input.help.validateScriptSignature": "これが true の場合、タスクはまず、指定されたスクリプトが署名され、有効であることを確認してからこれを実行します。", + "loc.input.label.workingDirectory": "作業ディレクトリ", + "loc.input.help.workingDirectory": "スクリプトが実行される作業ディレクトリ。", + "loc.messages.GeneratingScript": "スクリプトを生成しています。", + "loc.messages.JS_FormattedCommand": "フォーマット後のコマンド: %s", + "loc.messages.InvalidScriptArguments0": "スクリプトの引数 '{0}' が無効です。改行は使用できません。", + "loc.messages.InvalidScriptPath0": "スクリプト パス '{0}' が無効です。無効なパス文字が指定されました。", + "loc.messages.InvalidAzurePsVersion": "指定した Azure PowerShell バージョン '{0}' は、形式が正しくありません。形式をご確認ください。正しい形式の例は、1.0.1 です", + "loc.messages.JS_ExitCode": "PowerShell がコード '%s' で終了しました。", + "loc.messages.JS_Stderr": "PowerShell が標準エラー ストリームに 1 行以上を書き込みました。", + "loc.messages.ExpiredServicePrincipal": "Azure のアクセス トークンをフェッチできませんでした。使用されているサービス プリンシパルが有効であり、有効期限が切れていないことを確認してください。", + "loc.messages.PS_ExitCode": "PowerShell がコード '{0}' で終了しました。" +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/ko-KR/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/ko-KR/resources.resjson new file mode 100644 index 000000000000..4459a234b77f --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/ko-KR/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[이 작업에 대한 자세한 정보](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Azure 환경에서 PowerShell 스크립트 실행", + "loc.instanceNameFormat": "Azure PowerShell 스크립트: $(ScriptType)", + "loc.releaseNotes": "Az 모듈 및 플랫폼 간 에이전트에 대한 지원이 추가되었습니다.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell 버전 옵션", + "loc.group.displayName.advanced": "고급", + "loc.input.label.ConnectedServiceNameARM": "Azure 구독", + "loc.input.help.ConnectedServiceNameARM": "PowerShell을 실행하기 전에 구성할 Azure Resource Manager 구독", + "loc.input.label.ScriptType": "스크립트 유형", + "loc.input.help.ScriptType": "스크립트 유형: 파일 경로 또는 인라인 스크립트", + "loc.input.label.ScriptPath": "스크립트 경로", + "loc.input.help.ScriptPath": "스크립트의 경로입니다. 정규화된 경로이거나 기본 작업 디렉터리에 대한 상대 경로여야 합니다.", + "loc.input.label.Inline": "인라인 스크립트", + "loc.input.help.Inline": "실행할 스크립트를 입력합니다.", + "loc.input.label.ScriptArguments": "스크립트 인수", + "loc.input.help.ScriptArguments": "PowerShell에 전달할 추가 인수입니다. 서수 매개 변수나 명명된 매개 변수 중 하나일 수 있습니다.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "스크립트 실행에 대한 ErrorActionPreference 변수의 값을 선택합니다.", + "loc.input.label.FailOnStandardError": "표준 오류 시 실패", + "loc.input.help.FailOnStandardError": "이 값이 true이면 오류 파이프라인에 오류가 작성되거나 표준 오류 스트림에 데이터가 작성될 경우 이 작업은 실패하게 됩니다.", + "loc.input.label.TargetAzurePs": "Azure PowerShell 버전", + "loc.input.help.TargetAzurePs": "호스트된 에이전트의 경우 지원되는 Azure PowerShell 버전은 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0(Hosted VS2017 Queue)입니다.\n에이전트에서 사용 가능한 최신 버전을 선택하려면 \"설치된 최신 버전\"을 선택합니다.\n\n사용자 에이전트의 경우 \"버전 지정\"을 사용하여 기본 Azure PowerShell 버전을 지정할 수 있습니다.", + "loc.input.label.CustomTargetAzurePs": "기본 Azure PowerShell 버전", + "loc.input.help.CustomTargetAzurePs": "기본 Azure PowerShell 버전은 올바른 의미 체계 버전(예: 1.2.3)이어야 합니다. 2.\\*,2.3.\\*와 같은 Regex는 지원되지 않습니다. Hosted VS2017 풀은 현재 Az 모듈 버전 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0을 지원합니다.", + "loc.input.label.pwsh": "PowerShell Core 사용", + "loc.input.help.pwsh": "true이면, Windows에서 작업이 powershell.exe 대신 PATH의 pwsh.exe를 사용합니다.", + "loc.input.label.validateScriptSignature": "스크립트 서명 유효성 검사", + "loc.input.help.validateScriptSignature": "true이면 작업을 실행하기 전에 먼저 지정한 스크립트가 서명되어 있고 유효한지 확인합니다.", + "loc.input.label.workingDirectory": "작업 디렉터리", + "loc.input.help.workingDirectory": "스크립트가 실행되는 작업 디렉터리입니다.", + "loc.messages.GeneratingScript": "스크립트를 생성 중입니다.", + "loc.messages.JS_FormattedCommand": "형식이 지정된 명령: %s", + "loc.messages.InvalidScriptArguments0": "스크립트 인수 '{0}'이(가) 잘못되었습니다. 줄 바꿈은 허용되지 않습니다.", + "loc.messages.InvalidScriptPath0": "스크립트 경로 '{0}'이(가) 잘못되었습니다. 잘못된 경로 문자를 지정했습니다.", + "loc.messages.InvalidAzurePsVersion": "지정한 Azure PowerShell 버전 '{0}'의 형식이 잘못되었습니다. 형식을 확인하세요. 올바른 형식의 예는 1.0.1입니다.", + "loc.messages.JS_ExitCode": "PowerShell이 코드 '%s'(으)로 종료되었습니다.", + "loc.messages.JS_Stderr": "PowerShell이 표준 오류 스트림에 하나 이상의 줄을 썼습니다.", + "loc.messages.ExpiredServicePrincipal": "Azure의 액세스 토큰을 페치할 수 없습니다. 사용한 서비스 주체가 유효하고 만료되지 않았는지 확인하세요.", + "loc.messages.PS_ExitCode": "PowerShell이 코드 '{0}'(으)로 종료되었습니다." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/ru-RU/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/ru-RU/resources.resjson new file mode 100644 index 000000000000..0e75c654e99e --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/ru-RU/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[См. дополнительные сведения об этой задаче](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "Выполнение скрипта PowerShell в среде Azure", + "loc.instanceNameFormat": "Сценарий Azure PowerShell: $(ScriptType)", + "loc.releaseNotes": "Добавлена поддержка модуля Az и кроссплатформенных агентов.", + "loc.group.displayName.AzurePowerShellVersionOptions": "Параметры версии Azure PowerShell", + "loc.group.displayName.advanced": "Дополнительно", + "loc.input.label.ConnectedServiceNameARM": "Подписка Azure", + "loc.input.help.ConnectedServiceNameARM": "Подписка на Azure Resource Manager для настройки перед запуском PowerShell", + "loc.input.label.ScriptType": "Тип сценария", + "loc.input.help.ScriptType": "Тип сценария: путь к файлу или встроенный сценарий", + "loc.input.label.ScriptPath": "Путь к скрипту", + "loc.input.help.ScriptPath": "Путь к сценарию. Это должен быть полный путь или путь относительно рабочего каталога по умолчанию.", + "loc.input.label.Inline": "Встроенный сценарий", + "loc.input.help.Inline": "Введите сценарий для выполнения.", + "loc.input.label.ScriptArguments": "Аргументы скрипта", + "loc.input.help.ScriptArguments": "Дополнительные параметры для передачи в PowerShell. Могут быть как порядковыми, так и именованными.", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "Выберите значение переменной ErrorActionPreference для выполнения скрипта.", + "loc.input.label.FailOnStandardError": "Сбой со стандартной ошибкой", + "loc.input.help.FailOnStandardError": "Если задано значение True, задача будет завершаться сбоем при записи любых ошибок в конвейер ошибок или записи любых данных в стандартный поток ошибок.", + "loc.input.label.TargetAzurePs": "Версия Azure PowerShell", + "loc.input.help.TargetAzurePs": "Для размещенных агентов поддерживаются следующие версии Azure PowerShell: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (размещенная очередь Visual Studio 2017).\nЧтобы выбрать последнюю версию, доступную в агенте, выберите пункт \"Последняя установленная версия\".\n\nДля частных агентов можно указать предпочтительную версию Azure PowerShell с помощью элемента \"Указать версию\"", + "loc.input.label.CustomTargetAzurePs": "Предпочтительная версия Azure PowerShell", + "loc.input.help.CustomTargetAzurePs": "Предпочтительная версия Azure PowerShell должна быть надлежащей семантической версией, например 1.2.3. Регулярные выражения, например 2.\\*,2.3.\\*, не поддерживаются. Размещенный пул Visual Studio 2017 сейчас поддерживает следующие версии модуля Az: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0", + "loc.input.label.pwsh": "Использовать PowerShell Core", + "loc.input.help.pwsh": "Если задано значение True, в Windows задача будет использовать программу pwsh.exe, указанную в переменной PATH, вместо powershell.exe.", + "loc.input.label.validateScriptSignature": "Проверка подписи сценария", + "loc.input.help.validateScriptSignature": "Если задано значение true, задача сначала проверит, что указанный сценарий подписан и действителен, прежде чем выполнить его.", + "loc.input.label.workingDirectory": "Рабочий каталог", + "loc.input.help.workingDirectory": "Рабочий каталог, в котором выполняется скрипт.", + "loc.messages.GeneratingScript": "Формируется скрипт.", + "loc.messages.JS_FormattedCommand": "Отформатирована команда: %s", + "loc.messages.InvalidScriptArguments0": "Недопустимые аргументы скрипта \"{0}\". Разрывы строк запрещены.", + "loc.messages.InvalidScriptPath0": "Недопустимый путь к скрипту \"{0}\". Указаны символы, недопустимые в пути.", + "loc.messages.InvalidAzurePsVersion": "Указанная версия Azure PowerShell \"{0}\" имеет неправильный формат. Проверьте формат. Пример правильного формата: 1.0.1", + "loc.messages.JS_ExitCode": "Завершение работы PowerShell с кодом \"%s\".", + "loc.messages.JS_Stderr": "Оболочка PowerShell записала одну или несколько строк в стандартный поток ошибок.", + "loc.messages.ExpiredServicePrincipal": "Не удалось получить маркер доступа для Azure. Убедитесь, что используемый субъект-служба является допустимым, а срок его действия не истек.", + "loc.messages.PS_ExitCode": "Завершение работы PowerShell с кодом \"{0}\"." +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/zh-CN/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/zh-CN/resources.resjson new file mode 100644 index 000000000000..5310d72bc283 --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/zh-CN/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[详细了解此任务](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "在 Azure 环境中运行 PowerShell 脚本", + "loc.instanceNameFormat": "Azure PowerShell 脚本: $(ScriptType)", + "loc.releaseNotes": "添加了对 Azure 模块和跨平台代理的支持。", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell 版本选项", + "loc.group.displayName.advanced": "高级", + "loc.input.label.ConnectedServiceNameARM": "Azure 订阅", + "loc.input.help.ConnectedServiceNameARM": "在运行 PowerShell 之前配置的 Azure 资源管理器订阅", + "loc.input.label.ScriptType": "脚本类型", + "loc.input.help.ScriptType": "脚本类型: 文件路径或内联脚本", + "loc.input.label.ScriptPath": "脚本路径", + "loc.input.help.ScriptPath": "脚本的路径。应是完全限定的路径或相对于默认工作目录。", + "loc.input.label.Inline": "内联脚本", + "loc.input.help.Inline": "输入要执行的脚本。", + "loc.input.label.ScriptArguments": "脚本参数", + "loc.input.help.ScriptArguments": "要传递给 PowerShell 的其他参数。可以是序号或命名参数。", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "选择执行脚本的 ErrorActionPreference 变量的值。", + "loc.input.label.FailOnStandardError": "因标准错误失败", + "loc.input.help.FailOnStandardError": "如果为 true,当有错误被写入错误管道或有数据被写入标准错误流时,此任务将失败。", + "loc.input.label.TargetAzurePs": "Azure PowerShell 版本", + "loc.input.help.TargetAzurePs": "对于托管代理,受支持的 Azure PowerShell 版本为: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0 (托管的 VS2017 队列)。\n若要选择代理上的最新可用版本,请选择“已安装的最新版本”。\n\n对于专用代理,可以使用“指定版本”指定 Azure PowerShell 的首选版本", + "loc.input.label.CustomTargetAzurePs": "首选 Azure PowerShell 版本", + "loc.input.help.CustomTargetAzurePs": "首选 Azure PowerShell 版本需为正确的语义版本,例如 1.2.3。不支持 2.\\*、2.3.\\* 等正则表达式。托管 VS2017 池当前支持 Azure 模块版本: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0", + "loc.input.label.pwsh": "使用 PowerShell Core", + "loc.input.help.pwsh": "如果为 true,则在 Windows 上,任务将使用来自 PATH 的 pwsh.exe,而不是 powershell.exe。", + "loc.input.label.validateScriptSignature": "验证脚本签名", + "loc.input.help.validateScriptSignature": "如果为 true,则任务将首先检查以确保指定的脚本已签名并且在执行前有效。", + "loc.input.label.workingDirectory": "工作目录", + "loc.input.help.workingDirectory": "在其中运行脚本的工作目录。", + "loc.messages.GeneratingScript": "正在生成脚本。", + "loc.messages.JS_FormattedCommand": "已设置格式的命令: %s", + "loc.messages.InvalidScriptArguments0": "脚本参数“{0}”无效。不允许换行。", + "loc.messages.InvalidScriptPath0": "脚本路径“{0}”无效。指定的路径字符无效。", + "loc.messages.InvalidAzurePsVersion": "指定的 Azure PowerShell 版本“{0}”格式不正确。请检查格式。正确格式的示例为 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell 已退出,代码为“%s”。", + "loc.messages.JS_Stderr": "PowerShell 向标准错误流写入一个或多个行。", + "loc.messages.ExpiredServicePrincipal": "无法提取 Azure 的访问令牌。请确保使用的服务主体有效且未过期。", + "loc.messages.PS_ExitCode": "PowerShell 已退出,代码为“{0}”。" +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Strings/resources.resjson/zh-TW/resources.resjson b/_generated/AzurePowerShellV5/Strings/resources.resjson/zh-TW/resources.resjson new file mode 100644 index 000000000000..1532a782e6fe --- /dev/null +++ b/_generated/AzurePowerShellV5/Strings/resources.resjson/zh-TW/resources.resjson @@ -0,0 +1,42 @@ +{ + "loc.friendlyName": "Azure PowerShell", + "loc.helpMarkDown": "[深入了解此工作](https://go.microsoft.com/fwlink/?LinkID=613749)", + "loc.description": "在 Azure 環境中執行 PowerShell 指令碼", + "loc.instanceNameFormat": "Azure PowerShell 指令碼: $(ScriptType)", + "loc.releaseNotes": "新增了 Az 模組和跨平台代理程式的支援。", + "loc.group.displayName.AzurePowerShellVersionOptions": "Azure PowerShell 版本選項", + "loc.group.displayName.advanced": "進階", + "loc.input.label.ConnectedServiceNameARM": "Azure 訂用帳戶", + "loc.input.help.ConnectedServiceNameARM": "執行 PowerShell 之前要設定的 Azure Resource Manager 訂用帳戶", + "loc.input.label.ScriptType": "指令碼類型", + "loc.input.help.ScriptType": "指令碼類型: 檔案路徑或內嵌指令碼", + "loc.input.label.ScriptPath": "指令碼路徑", + "loc.input.help.ScriptPath": "指令碼的路徑。必須是完整路徑名稱或預設工作目錄的相對路徑。", + "loc.input.label.Inline": "內嵌指令碼", + "loc.input.help.Inline": "請輸入要執行的指令碼。", + "loc.input.label.ScriptArguments": "指令碼引數", + "loc.input.help.ScriptArguments": "傳遞至 PowerShell 的額外引數。可以是序數或具名參數。", + "loc.input.label.errorActionPreference": "ErrorActionPreference", + "loc.input.help.errorActionPreference": "請選取用於執行指令碼的 ErrorActionPreference 變數值。", + "loc.input.label.FailOnStandardError": "發生標準錯誤的失敗", + "loc.input.help.FailOnStandardError": "若此項為 true,如果在錯誤管線中寫入任何錯誤,或在標準錯誤資料流中寫入任何資料,此工作就會失敗。", + "loc.input.label.TargetAzurePs": "Azure PowerShell 版本", + "loc.input.help.TargetAzurePs": "若為裝載的代理程式,則支援的 Azure PowerShell 版本為: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0 (裝載的 VS2017 佇列)。\n若要挑選代理程式上可用的最新版本,請選取 [最新安裝的版本]。\n\n若為私人代理程式,您可以使用 [指定版本] 指定慣用的 Azure PowerShell 版本", + "loc.input.label.CustomTargetAzurePs": "慣用的 Azure PowerShell 版本", + "loc.input.help.CustomTargetAzurePs": "慣用的 Azure PowerShell 版本必須是正確的語意版本,例如 1.2.3。不支援像 2.\\*,2.3.\\* 這樣的 Regex。裝載的 VS2017 集區目前支援 Az 模組版本: 1.0.0、1.6.0、2.3.2、2.6.0、3.1.0", + "loc.input.label.pwsh": "使用 PowerShell Core", + "loc.input.help.pwsh": "若此為 true,那麼在 Windows 上,工作就會使用 PATH 中的 pwsh.exe 而非 powershell.exe。", + "loc.input.label.validateScriptSignature": "驗證指令碼簽章", + "loc.input.help.validateScriptSignature": "如果此為 true,則工作會先進行檢查,確定指定的指令碼已簽署且有效,然後再執行。", + "loc.input.label.workingDirectory": "工作目錄", + "loc.input.help.workingDirectory": "指令碼執行所在的工作目錄。", + "loc.messages.GeneratingScript": "正在產生指令碼。", + "loc.messages.JS_FormattedCommand": "經過格式化的命令: %s", + "loc.messages.InvalidScriptArguments0": "指令碼引數 '{0}' 無效。不允許分行符號。", + "loc.messages.InvalidScriptPath0": "指令碼路徑 '{0}' 無效。指定的路徑字元無效。", + "loc.messages.InvalidAzurePsVersion": "指定的 Azure PowerShell 版本 '{0}' 格式不正確。請檢查格式。正確格式的範例為 1.0.1", + "loc.messages.JS_ExitCode": "PowerShell 已結束,代碼為 '%s'。", + "loc.messages.JS_Stderr": "PowerShell 已將一或多行寫入標準錯誤資料流。", + "loc.messages.ExpiredServicePrincipal": "無法擷取 Azure 的存取權杖。請驗證使用的服務主體是否有效且未過期。", + "loc.messages.PS_ExitCode": "PowerShell 已結束,代碼為 '{0}'。" +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Tests/ChecksForPowerShell.ps1 b/_generated/AzurePowerShellV5/Tests/ChecksForPowerShell.ps1 new file mode 100644 index 000000000000..7ea294a29d90 --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/ChecksForPowerShell.ps1 @@ -0,0 +1,32 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +$targetAzurePs = "4.1.0" +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "$PSScriptRoot/PerformsBasicFlow_TargetScript.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { 'arg1 arg2' } -- -Name ScriptArguments +Register-Mock Get-VstsInput { "continue" } -- -Name errorActionPreference +Register-Mock Get-VstsInput { $true } -- -Name FailOnStandardError +Register-Mock Get-VstsInput { $false } -- -Name pwsh -AsBool +Register-Mock Update-PSModulePathForHostedAgent +Register-Mock Get-Module +Register-Mock Initialize-AzModule +Register-Mock Get-VstsEndpoint { @{auth = @{ scheme = "ServicePrincipal" }} } +Register-Mock Remove-EndpointSecrets +Register-Mock Disconnect-AzureAndClearContext +Register-Mock Assert-VstsPath +Register-Mock Invoke-VstsTool { } +Register-Mock Write-VstsTaskError +Register-Mock Write-VstsSetResult +Register-Mock Expand-ModuleZip +Register-Mock Invoke-RestMethod +Register-Mock Save-Module + +# Act. +$actual = & $PSScriptRoot\..\AzurePowerShell.ps1 + +Assert-WasCalled Invoke-VstsTool -Times 1 +Assert-WasCalled Invoke-VstsTool -ArgumentsEvaluator {($args | ConvertTo-Json) -like '*powershell.exe*'} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Tests/ChecksForPowerShellCore.ps1 b/_generated/AzurePowerShellV5/Tests/ChecksForPowerShellCore.ps1 new file mode 100644 index 000000000000..ebf4f7706981 --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/ChecksForPowerShellCore.ps1 @@ -0,0 +1,32 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +$targetAzurePs = "4.1.0" +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "$PSScriptRoot/PerformsBasicFlow_TargetScript.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { 'arg1 arg2' } -- -Name ScriptArguments +Register-Mock Get-VstsInput { "continue" } -- -Name errorActionPreference +Register-Mock Get-VstsInput { $true } -- -Name FailOnStandardError +Register-Mock Get-VstsInput { $true } -- -Name pwsh -AsBool -Default $false +Register-Mock Update-PSModulePathForHostedAgent +Register-Mock Get-Module +Register-Mock Initialize-AzModule +Register-Mock Get-VstsEndpoint { @{auth = @{ scheme = "ServicePrincipal" }} } +Register-Mock Remove-EndpointSecrets +Register-Mock Disconnect-AzureAndClearContext +Register-Mock Assert-VstsPath +Register-Mock Invoke-VstsTool { } +Register-Mock Write-VstsTaskError +Register-Mock Write-VstsSetResult +Register-Mock Expand-ModuleZip +Register-Mock Invoke-RestMethod +Register-Mock Save-Module + +# Act. +$actual = & $PSScriptRoot\..\AzurePowerShell.ps1 + +Assert-WasCalled Invoke-VstsTool -Times 1 +Assert-WasCalled Invoke-VstsTool -ArgumentsEvaluator {($args | ConvertTo-Json) -like '*pwsh.exe*'} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Tests/ChecksForWorkingDirectory.ps1 b/_generated/AzurePowerShellV5/Tests/ChecksForWorkingDirectory.ps1 new file mode 100644 index 000000000000..4747d0181cc4 --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/ChecksForWorkingDirectory.ps1 @@ -0,0 +1,34 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +$targetAzurePs = "4.1.0" +$input_workingDirectory = "C:\Users" +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "$PSScriptRoot/PerformsBasicFlow_TargetScript.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { 'arg1 arg2' } -- -Name ScriptArguments +Register-Mock Get-VstsInput { "continue" } -- -Name errorActionPreference +Register-Mock Get-VstsInput { $true } -- -Name FailOnStandardError +Register-Mock Get-VstsInput { $true } -- -Name pwsh -AsBool +Register-Mock Get-VstsInput { $input_workingDirectory } -- -Name workingDirectory -Require +Register-Mock Update-PSModulePathForHostedAgent +Register-Mock Get-Module +Register-Mock Initialize-AzModule +Register-Mock Get-VstsEndpoint { @{auth = @{ scheme = "ServicePrincipal" }} } +Register-Mock Remove-EndpointSecrets +Register-Mock Disconnect-AzureAndClearContext +Register-Mock Assert-VstsPath +Register-Mock Invoke-VstsTool { } +Register-Mock Write-VstsTaskError +Register-Mock Write-VstsSetResult +Register-Mock Expand-ModuleZip +Register-Mock Invoke-RestMethod +Register-Mock Save-Module + +# Act. +$actual = & $PSScriptRoot\..\AzurePowerShell.ps1 + +Assert-WasCalled Invoke-VstsTool -Times 1 +Assert-WasCalled Invoke-VstsTool -ArgumentsEvaluator {($args | ConvertTo-Json) -like '*C:\\Users*'} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Tests/L0.ts b/_generated/AzurePowerShellV5/Tests/L0.ts new file mode 100644 index 000000000000..419e7a10004e --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/L0.ts @@ -0,0 +1,58 @@ +/// +/// +/// + +import Q = require('q'); +import assert = require('assert'); +import path = require('path'); +var psm = require('../../../Tests/lib/psRunner'); +var psr = null; + +describe('AzurePowerShell Suite', function () { + this.timeout(parseInt(process.env.TASK_TEST_TIMEOUT) || 20000); + + before((done) => { + if (psm.testSupported()) { + psr = new psm.PSRunner(); + psr.start(); + } + + done(); + }); + + after(function () { + if (psr) { + psr.kill(); + } + }); + + if (psm.testSupported()) { + it('checks for powershell core', (done) => { + psr.run(path.join(__dirname, 'ChecksForPowerShellCore.ps1'), done); + }) + it('checks for powershell', (done) => { + psr.run(path.join(__dirname, 'ChecksForPowerShell.ps1'), done); + }) + it('checks for working directory', (done) => { + psr.run(path.join(__dirname, 'ChecksForWorkingDirectory.ps1'), done); + }) + it('performs basic flow', (done) => { + psr.run(path.join(__dirname, 'PerformsBasicFlow.ps1'), done); + }) + it('throws when otherversion is specified in a wrong format', (done) => { + psr.run(path.join(__dirname, 'ThrowsForInvalidVersion.ps1'), done); + }) + it('throws when invalid script arguments', (done) => { + psr.run(path.join(__dirname, 'ThrowsWhenInvalidScriptArguments.ps1'), done); + }) + it('throws when invalid script path', (done) => { + psr.run(path.join(__dirname, 'ThrowsWhenInvalidScriptPath.ps1'), done); + }) + it('Get-LatestModule returns the latest available module', (done) => { + psr.run(path.join(__dirname, 'Utility.Get-LatestModule.ps1'), done); + }) + it('Update-PSModulePathForHostedAgent updated psmodulepath correctly', (done) => { + psr.run(path.join(__dirname, 'Utility.UpdatePSModulePathForHostedAgentWorksCorrectly.ps1'), done); + }) + } +}); \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Tests/PerformsBasicFlow.ps1 b/_generated/AzurePowerShellV5/Tests/PerformsBasicFlow.ps1 new file mode 100644 index 000000000000..7cb63f9cb4c8 --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/PerformsBasicFlow.ps1 @@ -0,0 +1,35 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +$targetAzurePs = "4.1.0" +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "$PSScriptRoot/PerformsBasicFlow_TargetScript.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { 'arg1 arg2' } -- -Name ScriptArguments +Register-Mock Get-VstsInput { "continue" } -- -Name errorActionPreference +Register-Mock Get-VstsInput { $true } -- -Name FailOnStandardError +Register-Mock Update-PSModulePathForHostedAgent +Register-Mock Get-Module +Register-Mock Initialize-AzModule +Register-Mock Get-VstsEndpoint { @{auth = @{ scheme = "ServicePrincipal" }} } +Register-Mock Remove-EndpointSecrets +Register-Mock Disconnect-AzureAndClearContext +Register-Mock Assert-VstsPath +Register-Mock Invoke-VstsTool { } +Register-Mock Write-VstsTaskError +Register-Mock Write-VstsSetResult +Register-Mock Expand-ModuleZip +Register-Mock Invoke-RestMethod +Register-Mock Save-Module + +# Act. +$actual = & $PSScriptRoot\..\AzurePowerShell.ps1 + +# Assert the error action preference was set to Continue. +Assert-AreEqual "Continue" $global:ErrorActionPreference +$global:ErrorActionPreference = 'Stop' # Reset to stop. + +# Assert the Azure helpers module was imported and invoked. +Assert-WasCalled Import-Module -- ([System.IO.Path]::GetFullPath("$PSScriptRoot\..\ps_modules\VstsAzureHelpers_")) diff --git a/_generated/AzurePowerShellV5/Tests/PerformsBasicFlow_TargetScript.ps1 b/_generated/AzurePowerShellV5/Tests/PerformsBasicFlow_TargetScript.ps1 new file mode 100644 index 000000000000..53aafdebcdd8 --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/PerformsBasicFlow_TargetScript.ps1 @@ -0,0 +1,4 @@ +# Return key information. +New-Object psobject -Property @{ + Args = $args +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Tests/ThrowsForInvalidVersion.ps1 b/_generated/AzurePowerShellV5/Tests/ThrowsForInvalidVersion.ps1 new file mode 100644 index 000000000000..5afc27858f1e --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/ThrowsForInvalidVersion.ps1 @@ -0,0 +1,15 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 + +Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require +Register-Mock Get-VstsInput { "foobar.ps1" } -- -Name ScriptPath +Register-Mock Get-VstsInput { "OtherVersion" } -- -Name TargetAzurePs +Register-Mock Get-VstsInput { "x.y.z" } -- -Name CustomTargetAzurePs + +# Act/Assert. +Assert-Throws { + & $PSScriptRoot\..\AzurePowerShell.ps1 +} -MessagePattern "InvalidAzurePsVersion*x.y.z" diff --git a/_generated/AzurePowerShellV5/Tests/ThrowsWhenInvalidScriptArguments.ps1 b/_generated/AzurePowerShellV5/Tests/ThrowsWhenInvalidScriptArguments.ps1 new file mode 100644 index 000000000000..af93358163bc --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/ThrowsWhenInvalidScriptArguments.ps1 @@ -0,0 +1,14 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +foreach ($arguments in @( "script`rarguments", "script`narguments" )) { + Unregister-Mock Get-VstsInput + Register-Mock Get-VstsInput { $arguments } -- -Name ScriptArguments + + # Act/Assert. + Assert-Throws { + & $PSScriptRoot\..\AzurePowerShell.ps1 + } -MessagePattern "InvalidScriptArguments0*$arguments" +} diff --git a/_generated/AzurePowerShellV5/Tests/ThrowsWhenInvalidScriptPath.ps1 b/_generated/AzurePowerShellV5/Tests/ThrowsWhenInvalidScriptPath.ps1 new file mode 100644 index 000000000000..a1334790ccba --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/ThrowsWhenInvalidScriptPath.ps1 @@ -0,0 +1,16 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +foreach ($path in @( "script`rpath", "script`npath" )) { + Unregister-Mock Get-VstsInput + Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require + Register-Mock Get-VstsInput { $path } -- -Name ScriptPath + Register-Mock Get-VstsInput { "4.1.0" } -- -Name TargetAzurePs + + # Act/Assert. + Assert-Throws { + & $PSScriptRoot\..\AzurePowerShell.ps1 + } -MessagePattern "InvalidScriptPath0*$path" +} diff --git a/_generated/AzurePowerShellV5/Tests/Utility.Get-LatestModule.ps1 b/_generated/AzurePowerShellV5/Tests/Utility.Get-LatestModule.ps1 new file mode 100644 index 000000000000..71609db6ede0 --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/Utility.Get-LatestModule.ps1 @@ -0,0 +1,30 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +. $PSScriptRoot\..\Utility.ps1 + +$azModulePath = "c:\modules\az_4.1.0" + +$azModulePattern = "^az_[0-9]+\.[0-9]+\.[0-9]+$" +$versionPattern = "[0-9]+\.[0-9]+\.[0-9]+$" + +$mockDirectoryStructure = @( + @{ + Name = "az_4.1.0" + FullName = "C:\Modules\az_4.1.0" + } + @{ + Name = "az_3.6.0" + FullName = "C:\Modules\az_3.6.0" + } +) + +Register-Mock Get-ChildItem { $mockDirectoryStructure } -- -Directory -Path "C:\Modules" +Register-Mock Test-Path { $true } + +# Act +$result = Get-LatestModule -patternToMatch $azModulePattern -patternToExtract $versionPattern +# Assert +Assert-AreEqual $result.toLower() $azModulePath \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/Tests/Utility.UpdatePSModulePathForHostedAgentWorksCorrectly.ps1 b/_generated/AzurePowerShellV5/Tests/Utility.UpdatePSModulePathForHostedAgentWorksCorrectly.ps1 new file mode 100644 index 000000000000..53c9c7875e54 --- /dev/null +++ b/_generated/AzurePowerShellV5/Tests/Utility.UpdatePSModulePathForHostedAgentWorksCorrectly.ps1 @@ -0,0 +1,47 @@ +[CmdletBinding()] +param() + +# Arrange. +. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 +. $PSScriptRoot\..\Utility.ps1 + +$azModulePath = "c:\modules\az_3.6.0" + +$azModulePattern = "^az_[0-9]+\.[0-9]+\.[0-9]+$" +$versionPattern = "[0-9]+\.[0-9]+\.[0-9]+$" + +$variableSets = @( + @{ + targetAzurePsVersion = "3.6.0" + azModuleExist = $true + } + @{ + targetAzurePsVersion = "" + azModulePath = $true + } +) + +$temp = $env:PSModulePath + +foreach ($variableSet in $variableSets) { + $env:PSModulePath = $temp + # Arrange + Unregister-Mock Get-LatestModule + if($variableSet.azModuleExist) { + Register-Mock Get-LatestModule { $azModulePath } -- -patternToMatch $azModulePattern -patternToExtract $versionPattern -Classic:$false + } else { + Register-Mock Get-LatestModule { "" } -- -patternToMatch $azModulePattern -patternToExtract $versionPattern -Classic:$false + } + + # Act + Update-PSModulePathForHostedAgent -targetAzurePs $variableSet.targetAzurePsVersion + + # Assert + if($variableSet.azModuleExist) { + Assert-IsGreaterThan -1 $env:PSModulePath.toLower().IndexOf($azModulePath) + } else { + Assert-AreEqual -1 $env:PSModulePath.toLower().IndexOf($azModulePath) + } + + Assert-IsGreaterThan 0 $env:PSModulePath.toLower().IndexOf(";") +} diff --git a/_generated/AzurePowerShellV5/ThirdPartyNotices.txt b/_generated/AzurePowerShellV5/ThirdPartyNotices.txt new file mode 100644 index 000000000000..abc33cfd772f --- /dev/null +++ b/_generated/AzurePowerShellV5/ThirdPartyNotices.txt @@ -0,0 +1,136 @@ + +THIRD-PARTY SOFTWARE NOTICES AND INFORMATION +Do Not Translate or Localize + +Azure PowerShell incorporates third party material from the projects listed below. The original copyright notice and the license under which Microsoft received such third party material are set forth below. Microsoft reserves all other rights not expressly granted, whether by implication, estoppel or otherwise. + +1. OpenSSL (http://www.openssl.org) + +%% OpenSSL NOTICES, INFORMATION, AND LICENSE BEGIN HERE +========================================= + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/) + * + * 4. The names OpenSSL Toolkit and OpenSSL Project must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called OpenSSL + * nor may OpenSSL appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/) + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com) + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * This product includes software written by Tim Hudson (tjh@cryptsoft.com) + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] +========================================= +END OF OpenSSL NOTICES, INFORMATION, AND LICENSE diff --git a/_generated/AzurePowerShellV5/TryMakingModuleAvailable.ps1 b/_generated/AzurePowerShellV5/TryMakingModuleAvailable.ps1 new file mode 100644 index 000000000000..cf41cc06bfd7 --- /dev/null +++ b/_generated/AzurePowerShellV5/TryMakingModuleAvailable.ps1 @@ -0,0 +1,85 @@ +[CmdletBinding()] +param ( + [string] + $targetVersion, + + [string] [Parameter(Mandatory = $true)] [ValidateSet("Windows", "Linux", "Mac")] + $platform +) + +try { + $isWin = $platform -eq "Windows" + + . (Join-Path $PSScriptRoot "Utility.ps1") + $isHostedAgent = Test-IsHostedAgentPathPresent -isWin $isWin + + if (!$isHostedAgent) { + Write-Verbose "Module path not present as expected in hosted agent, skipping step to make module available." + $moduleSource = "privateAgent" + return + } + + if (!$targetVersion) { + Write-Verbose "Latest selected, will make use of the latest available in agent as folder." + $moduleSource = "hostedAgentFolder" + return + } + + $modulePath = Get-SavedModulePath -azurePowerShellVersion $targetVersion -isWin $isWin + if (Test-Path $modulePath) { + Write-Verbose "Az $targetVersion present at $modulePath as folder." + $moduleSource = "hostedAgentFolder" + return + } + + $moduleContainerPath = Get-SavedModuleContainerPath -isWin $isWin + $moduleZipPath = $modulePath + ".zip"; + if (Test-Path $moduleZipPath) { + Write-Verbose "Az $targetVersion present at $moduleZipPath as zip, expanding it." + Expand-ModuleZip -zipPath $moduleZipPath -destination $moduleContainerPath -isWin $isWin + Write-Verbose "Zip expanded" + $moduleSource = "hostedAgentZip" + return + } + + Write-Host "Az version $targetVersion not avaiable locally on the agent. Downloading dynamically." + + try { + Write-Verbose "Getting versions manifest from GHRelease." + $versionsManifest = Invoke-RestMethod -Method Get ` + -Headers @{ "Accept" = "application/vnd.github.VERSION.raw" } ` + -Uri "https://api.github.com/repos/Azure/az-ps-module-versions/contents/versions-manifest.json" + Write-Verbose "Versions manifest downloaded." + $downloadUrlEntity = $versionsManifest | Where-Object version -eq $targetVersion + if ($downloadUrlEntity) { + $downloadUrl = $downloadUrlEntity.files[0].download_url + Write-Verbose "Downloading Az $targetVersion from GHRelease" + (New-Object System.Net.WebClient).DownloadFile($downloadUrl, $moduleZipPath) + Write-Verbose "Download succeeded" + if (Test-Path $moduleZipPath) { + Write-Verbose "Expanding Az $targetVersion downloaded at $moduleZipPath as zip." + Expand-ModuleZip -zipPath $moduleZipPath -destination $moduleContainerPath -isWin $isWin + Write-Verbose "Zip expanded" + $moduleSource = "hostedAgentGHRelease" + return + } + } else { + Write-Verbose "Az $targetVersion not present in versions manifest from GHRelease" + } + } catch { + Write-Verbose "Failed to download from GHRelease" + Write-Verbose $_ + } + + Write-Verbose "Downloading Az $targetVersion from PSGallery." + Save-Module -Path $modulePath -Name Az -RequiredVersion $targetVersion -Force -ErrorAction Stop + $moduleSource = "hostedAgentPSGallery" +} finally { + # Telemetry + # moduleSource value will be privateAgent(in case of self hosted private agents), hostedAgentFolder(when a version is present as folder or + # when latest is selected we will use the one latest available as folder), hostedAgentZip(when the module is available as a zip locally), + # hostedAgentGHRelease(when the module zip is downloaded from our GitHub releases management), hostedAgentPSGallery(when we download from PSGallery + # using the Save-Module cmdlet). + $telemetryJsonContent = @{ targetAzurePs = $targetVersion; moduleSource = $moduleSource } | ConvertTo-Json -Compress + Write-Host "##vso[telemetry.publish area=TaskHub;feature=AzurePowerShellV5]$telemetryJsonContent" +} diff --git a/_generated/AzurePowerShellV5/Utility.ps1 b/_generated/AzurePowerShellV5/Utility.ps1 new file mode 100644 index 000000000000..8e6804ffe66e --- /dev/null +++ b/_generated/AzurePowerShellV5/Utility.ps1 @@ -0,0 +1,203 @@ +function Get-SavedModuleContainerPath { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [bool] + $isWin + ) + + if ($isWin) { + return $env:SystemDrive + "\Modules"; + } else { + return "/usr/share"; + } +} + +function Test-IsHostedAgentPathPresent { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [bool] + $isWin + ) + + $containerPath = Get-SavedModuleContainerPath -isWin $isWin + return Test-Path (Join-Path $containerPath "az_*") +} + +function Get-SavedModulePath { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [string] + $azurePowerShellVersion, + + [Parameter(Mandatory = $true)] + [bool] + $isWin + ) + + $savedModulePath = Join-Path (Get-SavedModuleContainerPath -isWin $isWin) "az_$azurePowerShellVersion" + Write-Verbose "The value of the module path is: $savedModulePath" + return $savedModulePath +} + +function Expand-ModuleZip { + param ( + [string] [Parameter(Mandatory = $true)] + $zipPath, + + [string] [Parameter(Mandatory = $true)] + $destination, + + [bool] [Parameter(Mandatory=$true)] + $isWin + ) + + if ($isWin) { + $parameter = @("x", "-o$destination", "$zipPath") + $command = "$PSScriptRoot\7zip\7z.exe" + &$command @parameter + } else { + $prevProgressPref = $ProgressPreference + $ProgressPreference = 'SilentlyContinue' + Expand-Archive -Path $zipPath -DestinationPath $destination + $ProgressPreference = $prevProgressPref + } +} + +function Update-PSModulePathForHostedAgent { + [CmdletBinding()] + param([string] $targetAzurePs) + try { + if ($targetAzurePs) { + $hostedAgentAzModulePath = Get-SavedModulePath -azurePowerShellVersion $targetAzurePs -isWin $true + } + else { + $hostedAgentAzModulePath = Get-LatestModule -patternToMatch "^az_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" + } + $env:PSModulePath = $hostedAgentAzModulePath + ";" + $env:PSModulePath + $env:PSModulePath = $env:PSModulePath.TrimStart(';') + } finally { + Write-Verbose "The updated value of the PSModulePath is: $($env:PSModulePath)" + } +} + +function Update-PSModulePathForHostedAgentLinux { + [CmdletBinding()] + param([string] $targetAzurePs) + try { + if ($targetAzurePs) { + $hostedAgentAzModulePath = Get-SavedModulePath -azurePowerShellVersion $targetAzurePs -isWin $false + if(!(Test-Path $hostedAgentAzModulePath)) { + Write-Verbose "No module path found with this name" + throw ("Could not find the module path with given version.") + } + } + else { + $hostedAgentAzModulePath = Get-LatestModuleLinux -patternToMatch "^az_[0-9]+\.[0-9]+\.[0-9]+$" -patternToExtract "[0-9]+\.[0-9]+\.[0-9]+$" + } + $env:PSModulePath = $hostedAgentAzModulePath + ":" + $env:PSModulePath + $env:PSModulePath = $env:PSModulePath.TrimStart(':') + } finally { + Write-Verbose "The updated value of the PSModulePath is: $($env:PSModulePath)" + } +} + +function Get-LatestModule { + [CmdletBinding()] + param([string] $patternToMatch, + [string] $patternToExtract) + + $resultFolder = "" + $regexToMatch = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToMatch + $regexToExtract = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToExtract + $maxVersion = [version] "0.0.0" + $modulePath = $env:SystemDrive + "\Modules"; + + try { + if (-not (Test-Path -Path $modulePath)) { + return $resultFolder + } + + $moduleFolders = Get-ChildItem -Directory -Path $modulePath | Where-Object { $regexToMatch.IsMatch($_.Name) } + foreach ($moduleFolder in $moduleFolders) { + $moduleVersion = [version] $($regexToExtract.Match($moduleFolder.Name).Groups[0].Value) + if($moduleVersion -gt $maxVersion) { + $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"Az\$moduleVersion\Az.psm1") + + if(Test-Path -LiteralPath $modulePath -PathType Leaf) { + $maxVersion = $moduleVersion + $resultFolder = $moduleFolder.FullName + } else { + Write-Verbose "A folder matching the module folder pattern was found at $($moduleFolder.FullName) but didn't contain a valid module file" + } + } + } + } + catch { + Write-Verbose "Attempting to find the Latest Module Folder failed with the error: $($_.Exception.Message)" + $resultFolder = "" + } + Write-Verbose "Latest module folder detected: $resultFolder" + return $resultFolder +} + +function Get-LatestModuleLinux { + [CmdletBinding()] + param([string] $patternToMatch, + [string] $patternToExtract) + + $resultFolder = "" + $regexToMatch = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToMatch + $regexToExtract = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList $patternToExtract + $maxVersion = [version] "0.0.0" + + try { + $moduleFolders = Get-ChildItem -Directory -Path $("/usr/share") | Where-Object { $regexToMatch.IsMatch($_.Name) } + foreach ($moduleFolder in $moduleFolders) { + $moduleVersion = [version] $($regexToExtract.Match($moduleFolder.Name).Groups[0].Value) + if($moduleVersion -gt $maxVersion) { + $modulePath = [System.IO.Path]::Combine($moduleFolder.FullName,"Az/$moduleVersion/Az.psm1") + + if(Test-Path -LiteralPath $modulePath -PathType Leaf) { + $maxVersion = $moduleVersion + $resultFolder = $moduleFolder.FullName + } else { + Write-Verbose "A folder matching the module folder pattern was found at $($moduleFolder.FullName) but didn't contain a valid module file" + } + } + } + } + catch { + Write-Verbose "Attempting to find the Latest Module Folder failed with the error: $($_.Exception.Message)" + $resultFolder = "" + } + Write-Verbose "Latest module folder detected: $resultFolder" + return $resultFolder +} + +function CleanUp-PSModulePathForHostedAgent { + # Clean up PSModulePath for hosted agent + $azureRMModulePath = "C:\Modules\azurerm_2.1.0" + $azureModulePath = "C:\Modules\azure_2.1.0" + $azPSModulePath = $env:PSModulePath + + if ($azPSModulePath.split(";") -contains $azureRMModulePath) { + $azPSModulePath = (($azPSModulePath).Split(";") | ? { $_ -ne $azureRMModulePath }) -join ";" + write-verbose "$azureRMModulePath removed. Restart the prompt for the changes to take effect." + } + else { + write-verbose "$azureRMModulePath is not present in $azPSModulePath" + } + + if ($azPSModulePath.split(";") -contains $azureModulePath) { + $azPSModulePath = (($azPSModulePath).Split(";") | ? { $_ -ne $azureModulePath }) -join ";" + write-verbose "$azureModulePath removed. Restart the prompt for the changes to take effect." + } + else { + write-verbose "$azureModulePath is not present in $azPSModulePath" + } + + $env:PSModulePath = $azPSModulePath +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/azurepowershell.ts b/_generated/AzurePowerShellV5/azurepowershell.ts new file mode 100644 index 000000000000..c5378d87d040 --- /dev/null +++ b/_generated/AzurePowerShellV5/azurepowershell.ts @@ -0,0 +1,165 @@ +import fs = require('fs'); +import path = require('path'); +import os = require('os'); +import tl = require('azure-pipelines-task-lib/task'); +import tr = require('azure-pipelines-task-lib/toolrunner'); + +import { AzureRMEndpoint } from 'azure-pipelines-tasks-azure-arm-rest/azure-arm-endpoint'; +var uuidV4 = require('uuid/v4'); + +function convertToNullIfUndefined(arg: T): T|null { + return arg ? arg : null; +} + +async function run() { + try { + tl.setResourcePath(path.join(__dirname, 'task.json')); + + // Get inputs. + let _vsts_input_errorActionPreference: string = tl.getInput('errorActionPreference', false) || 'Stop'; + switch (_vsts_input_errorActionPreference.toUpperCase()) { + case 'STOP': + case 'CONTINUE': + case 'SILENTLYCONTINUE': + break; + default: + throw new Error(tl.loc('JS_InvalidErrorActionPreference', _vsts_input_errorActionPreference)); + } + + let scriptType: string = tl.getInput('ScriptType', /*required*/true); + let scriptPath = convertToNullIfUndefined(tl.getPathInput('ScriptPath', false)); + let scriptInline: string = convertToNullIfUndefined(tl.getInput('Inline', false)); + let scriptArguments: string = convertToNullIfUndefined(tl.getInput('ScriptArguments', false)); + let _vsts_input_failOnStandardError = convertToNullIfUndefined(tl.getBoolInput('FailOnStandardError', false)); + let targetAzurePs: string = convertToNullIfUndefined(tl.getInput('TargetAzurePs', false)); + let customTargetAzurePs: string = convertToNullIfUndefined(tl.getInput('CustomTargetAzurePs', false)); + let serviceName = tl.getInput('ConnectedServiceNameARM',/*required*/true); + let endpointObject= await new AzureRMEndpoint(serviceName).getEndpoint(); + let input_workingDirectory = tl.getPathInput('workingDirectory', /*required*/ true, /*check*/ true); + let isDebugEnabled = (process.env['SYSTEM_DEBUG'] || "").toLowerCase() === "true"; + + // string constants + let otherVersion = "OtherVersion" + + if (targetAzurePs == otherVersion) { + if (customTargetAzurePs != "") { + targetAzurePs = customTargetAzurePs; + } + else { + console.log(tl.loc('InvalidAzurePsVersion',customTargetAzurePs)); + } + } + else { + targetAzurePs = "" + } + + var endpoint = JSON.stringify(endpointObject); + + if (scriptType.toUpperCase() == 'FILEPATH') { + if (!tl.stats(scriptPath).isFile() || !scriptPath.toUpperCase().match(/\.PS1$/)) { + throw new Error(tl.loc('JS_InvalidFilePath', scriptPath)); + } + } + + // Generate the script contents. + console.log(tl.loc('GeneratingScript')); + let contents: string[] = []; + + if (isDebugEnabled) { + contents.push("$VerbosePreference = 'continue'"); + } + + const makeModuleAvailableScriptPath = path.join(path.resolve(__dirname), 'TryMakingModuleAvailable.ps1'); + contents.push(`${makeModuleAvailableScriptPath} -targetVersion '${targetAzurePs}' -platform Linux`); + + contents.push(`$ErrorActionPreference = '${_vsts_input_errorActionPreference}'`); + + let azFilePath = path.join(path.resolve(__dirname), 'InitializeAz.ps1'); + let initAzCommand = `${azFilePath} -endpoint '${endpoint}'` + if (targetAzurePs != "") { + initAzCommand += ` -targetAzurePs ${targetAzurePs}`; + } + if (endpointObject.scheme === 'WorkloadIdentityFederation') { + const oidc_token = await endpointObject.applicationTokenCredentials.getFederatedToken(); + initAzCommand += ` -clientAssertionJwt ${oidc_token}`; + } + contents.push(initAzCommand); + + if (scriptArguments == null) { + scriptArguments = ""; + } + + if (scriptType.toUpperCase() == 'FILEPATH') { + contents.push(`. '${scriptPath.replace(/'/g, "''")}' ${scriptArguments}`.trim()); + console.log(tl.loc('JS_FormattedCommand', contents[contents.length - 1])); + } + else { + contents.push(scriptInline); + } + + // Write the script to disk. + tl.assertAgent('2.115.0'); + let tempDirectory = tl.getVariable('agent.tempDirectory'); + tl.checkPath(tempDirectory, `${tempDirectory} (agent.tempDirectory)`); + let filePath = path.join(tempDirectory, uuidV4() + '.ps1'); + + await fs.writeFile( + filePath, + '\ufeff' + contents.join(os.EOL), // Prepend the Unicode BOM character. + { encoding: 'utf8' }, // Since UTF8 encoding is specified, node will + // encode the BOM into its UTF8 binary sequence. + function (err) { + if (err) throw err; + console.log('File saved!'); + }); + + // Run the script. + // + // Note, prefer "pwsh" over "powershell". At some point we can remove support for "powershell". + // + // Note, use "-Command" instead of "-File" to match the Windows implementation. Refer to + // comment on Windows implementation for an explanation why "-Command" is preferred. + let powershell = tl.tool(tl.which('pwsh') || tl.which('powershell') || tl.which('pwsh', true)) + .arg('-NoLogo') + .arg('-NoProfile') + .arg('-NonInteractive') + .arg('-ExecutionPolicy') + .arg('Unrestricted') + .arg('-Command') + .arg(`. '${filePath.replace(/'/g, "''")}'`); + + let options = { + cwd: input_workingDirectory, + failOnStdErr: false, + errStream: process.stdout, // Direct all output to STDOUT, otherwise the output may appear out + outStream: process.stdout, // of order since Node buffers it's own STDOUT but not STDERR. + ignoreReturnCode: true + }; + + // Listen for stderr. + let stderrFailure = false; + if (_vsts_input_failOnStandardError) { + powershell.on('stderr', (data) => { + stderrFailure = true; + }); + } + + // Run bash. + let exitCode: number = await powershell.exec(options); + + // Fail on exit code. + if (exitCode !== 0) { + tl.setResult(tl.TaskResult.Failed, tl.loc('JS_ExitCode', exitCode)); + } + + // Fail on stderr. + if (stderrFailure) { + tl.setResult(tl.TaskResult.Failed, tl.loc('JS_Stderr')); + } + } + catch (err) { + tl.setResult(tl.TaskResult.Failed, err.message || 'run() failed'); + } +} + +run(); diff --git a/_generated/AzurePowerShellV5/icon.png b/_generated/AzurePowerShellV5/icon.png new file mode 100644 index 000000000000..039b77995289 Binary files /dev/null and b/_generated/AzurePowerShellV5/icon.png differ diff --git a/_generated/AzurePowerShellV5/icon.svg b/_generated/AzurePowerShellV5/icon.svg new file mode 100644 index 000000000000..9d97d76e24ec --- /dev/null +++ b/_generated/AzurePowerShellV5/icon.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/_generated/AzurePowerShellV5/make.json b/_generated/AzurePowerShellV5/make.json new file mode 100644 index 000000000000..6f84ab04b3b0 --- /dev/null +++ b/_generated/AzurePowerShellV5/make.json @@ -0,0 +1,50 @@ +{ + "rm": [ + { + "items": [ + "node_modules/https-proxy-agent/node_modules/agent-base", + "node_modules/azure-pipelines-tasks-azure-arm-rest/node_modules/azure-pipelines-task-lib" + ], + "options": "-Rf" + } + ], + "common": [ + { + "module": "../Common/VstsAzureHelpers_", + "type": "ps" + }, + { + "module": "../Common/TlsHelper_", + "type": "ps" + } + ], + "externals": { + "nugetv2": [ + { + "name": "VstsTaskSdk", + "version": "0.11.0", + "repository": "https://www.powershellgallery.com/api/v2/", + "cp": [ + { + "source": [ + "*.dll", + "*.ps1", + "*.psd1", + "*.psm1", + "lib.json", + "Strings" + ], + "dest": "ps_modules/VstsTaskSdk/", + "options": "-R" + } + ] + } + ], + "archivePackages": [ + { + "url": "https://vstsagenttools.blob.core.windows.net/tools/7zip/4/7zip.zip", + "dest": "./" + } + ] + } +} diff --git a/_generated/AzurePowerShellV5/package-lock.json b/_generated/AzurePowerShellV5/package-lock.json new file mode 100644 index 000000000000..ab4ddb83aeb0 --- /dev/null +++ b/_generated/AzurePowerShellV5/package-lock.json @@ -0,0 +1,859 @@ +{ + "name": "azure-powershell-v5", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@azure/msal-common": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-9.1.1.tgz", + "integrity": "sha512-we9xR8lvu47fF0h+J8KyXoRy9+G/fPzm3QEa2TrdR3jaVS3LKAyE2qyMuUkNdbVkvzl8Zr9f7l+IUSP22HeqXw==" + }, + "@azure/msal-node": { + "version": "1.14.5", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.5.tgz", + "integrity": "sha512-NcVdMfn8Z3ogN+9RjOSF7uwf2Gki5DEJl0BdDSL83KUAgVAobtkZi5W8EqxbJLrTO/ET0jv5DregrcR5qg2pEA==", + "requires": { + "@azure/msal-common": "^9.0.1", + "jsonwebtoken": "^8.5.1", + "uuid": "^8.3.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, + "@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "requires": { + "@types/node": "*" + } + }, + "@types/jsonwebtoken": { + "version": "8.5.9", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz", + "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "16.18.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.39.tgz", + "integrity": "sha512-8q9ZexmdYYyc5/cfujaXb4YOucpQxAV4RMG0himLyDUOEr8Mr79VrqsFI+cQ2M2h89YIuy95lbxuYjxT4Hk4kQ==" + }, + "@types/q": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.0.7.tgz", + "integrity": "sha512-0WS7XU7sXzQ7J1nbnMKKYdjrrFoO3YtZYgUzeV8JFXffPnHfvSJQleR70I8BOAsOm14i4dyaAZ3YzqIl1YhkXQ==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + }, + "@types/uuid": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.10.tgz", + "integrity": "sha512-BgeaZuElf7DEYZhWYDTc/XcLZXdVgFkVSTa13BqKvbnmUrxr3TJFKofUxCtDO9UQOdhnV+HPOESdHiHKZOJV1A==" + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "async-mutex": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.4.0.tgz", + "integrity": "sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==", + "requires": { + "tslib": "^2.4.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "azure-devops-node-api": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.1.0.tgz", + "integrity": "sha512-VY+G45eNKVJfMIO0uyZfbi4PzUR8JHEfsHQjEUAXUGRkYhhBbhGHjy8cpiyYFxLXc3a4PL5cqgqqV/YD1SaCXg==", + "requires": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "azure-pipelines-task-lib": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.4.0.tgz", + "integrity": "sha512-JgtxfjxjRA+KWY0Q5UC1fo48nkbVxFHgKEuasKdJMSNxHydOyNlB5MNw4UTiTXp9b0nnqKeOQOBn5RN3go3aPg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + } + }, + "azure-pipelines-tasks-azure-arm-rest": { + "version": "3.225.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-azure-arm-rest/-/azure-pipelines-tasks-azure-arm-rest-3.225.1.tgz", + "integrity": "sha512-fbRcoYKEbFj2jslocX4wV0hbnN/9ZGepdzcLI+5vdOkGcKNIdOctUNvggrN1KFg9nH+NoxK1pE4+kl316VVpMA==", + "requires": { + "@azure/msal-node": "1.14.5", + "@types/jsonwebtoken": "^8.5.8", + "@types/mocha": "^5.2.7", + "@types/node": "^10.17.0", + "@types/q": "1.5.4", + "async-mutex": "^0.4.0", + "azure-devops-node-api": "^12.0.0", + "azure-pipelines-task-lib": "^3.4.0", + "https-proxy-agent": "^4.0.0", + "jsonwebtoken": "^8.5.1", + "node-fetch": "^2.6.7", + "q": "1.5.1", + "typed-rest-client": "1.8.4", + "xml2js": "0.4.13" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" + }, + "azure-pipelines-task-lib": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.4.0.tgz", + "integrity": "sha512-3eC4OTFw+7xD7A2aUhxR/j+jRlTI+vVfS0CGxt1pCLs4c/KmY0tQWgbqjD3157kmiucWxELBvgZHaD2gCBe9fg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + } + } + } + }, + "azure-pipelines-tasks-utility-common": { + "version": "3.225.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-utility-common/-/azure-pipelines-tasks-utility-common-3.225.0.tgz", + "integrity": "sha512-Na7g1+zcsQpYogyex457QT6o9EB2+WQYwLUXPiszhTdf83hKJUmDMqvl2qm/mHqYuP1zg5KkRfJaPy4/09M8pA==", + "requires": { + "@types/node": "^16.11.39", + "azure-pipelines-task-lib": "^4.4.0", + "azure-pipelines-tool-lib": "^2.0.0-preview", + "js-yaml": "3.13.1", + "semver": "^5.4.1" + } + }, + "azure-pipelines-tool-lib": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/azure-pipelines-tool-lib/-/azure-pipelines-tool-lib-2.0.4.tgz", + "integrity": "sha512-LgAelZKJe3k/t3NsKSKzjeRviphns0w0p5tgwz8uHN70I9m2TToiOKl+fogrdXcM6+jiLBk5KTqrcRBqPpv/XA==", + "requires": { + "@types/semver": "^5.3.0", + "@types/uuid": "^3.4.5", + "azure-pipelines-task-lib": "^4.1.0", + "semver": "^5.7.0", + "semver-compare": "^1.0.0", + "typed-rest-client": "^1.8.6", + "uuid": "^3.3.2" + }, + "dependencies": { + "typed-rest-client": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + } + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + } + } + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + }, + "dependencies": { + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + } + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "requires": { + "has": "^1.0.3" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mockery": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-2.1.0.tgz", + "integrity": "sha512-9VkOmxKlWXoDO/h1jDZaS4lH33aWfRiJiNT/tKj+8OGzrcFDLo8d0syGdbsc3Bc4GvRXPb+NMMvojotmuGJTvA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "requires": { + "asap": "~2.0.6" + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + } + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "tslib": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz", + "integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==" + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "typed-rest-client": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.4.tgz", + "integrity": "sha512-MyfKKYzk3I6/QQp6e1T50py4qg+c+9BzOEl2rBmQIpStwNUoqQ73An+Tkfy9YuV7O+o2mpVVJpe+fH//POZkbg==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "typescript": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "dev": true + }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "xml2js": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.13.tgz", + "integrity": "sha512-BoxD65qWA2p4znzbaati/Td19uFEc0X6ydj0bFphJO62RrNaGqOyW6ljLWPo3GKDbvW/6dnxAoRX01BsgEWsMA==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": ">=2.4.6" + } + }, + "xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==" + } + } +} diff --git a/_generated/AzurePowerShellV5/package.json b/_generated/AzurePowerShellV5/package.json new file mode 100644 index 000000000000..df70454a2343 --- /dev/null +++ b/_generated/AzurePowerShellV5/package.json @@ -0,0 +1,18 @@ +{ + "name": "azure-powershell-v5", + "author": { + "name": "Microsoft Corporation" + }, + "dependencies": { + "@types/mocha": "^5.2.7", + "@types/node": "^16.11.39", + "@types/q": "1.0.7", + "agent-base": "6.0.2", + "azure-pipelines-task-lib": "^4.4.0", + "azure-pipelines-tasks-azure-arm-rest": "^3.225.1", + "azure-pipelines-tasks-utility-common": "^3.225.0" + }, + "devDependencies": { + "typescript": "4.0.2" + } +} diff --git a/_generated/AzurePowerShellV5/task.json b/_generated/AzurePowerShellV5/task.json new file mode 100644 index 000000000000..1c64fbea9257 --- /dev/null +++ b/_generated/AzurePowerShellV5/task.json @@ -0,0 +1,210 @@ +{ + "id": "72A1931B-EFFB-4D2E-8FD8-F8472A07CB62", + "name": "AzurePowerShell", + "friendlyName": "Azure PowerShell", + "description": "Run a PowerShell script within an Azure environment", + "helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613749)", + "helpUrl": "https://aka.ms/azurepowershelltroubleshooting", + "category": "Deploy", + "visibility": [ + "Build", + "Release" + ], + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 5, + "Minor": 234, + "Patch": 0 + }, + "releaseNotes": "Added support for Az Module and cross platform agents.", + "groups": [ + { + "name": "AzurePowerShellVersionOptions", + "displayName": "Azure PowerShell version options", + "isExpanded": true + }, + { + "name": "advanced", + "displayName": "Advanced", + "isExpanded": false + } + ], + "minimumAgentVersion": "2.115.0", + "inputs": [ + { + "name": "ConnectedServiceNameARM", + "aliases": [ + "azureSubscription" + ], + "type": "connectedService:AzureRM", + "label": "Azure Subscription", + "defaultValue": "", + "required": true, + "helpMarkDown": "Azure Resource Manager subscription to configure before running PowerShell", + "properties": { + "EndpointFilterRule": "ScopeLevel != AzureMLWorkspace" + } + }, + { + "name": "ScriptType", + "type": "radio", + "label": "Script Type", + "required": false, + "helpMarkDown": "Type of the script: File Path or Inline Script", + "defaultValue": "FilePath", + "options": { + "FilePath": "Script File Path", + "InlineScript": "Inline Script" + } + }, + { + "name": "ScriptPath", + "type": "filePath", + "label": "Script Path", + "defaultValue": "", + "required": false, + "helpMarkDown": "Path of the script. Should be fully qualified path or relative to the default working directory.", + "visibleRule": "ScriptType = FilePath" + }, + { + "name": "Inline", + "type": "multiLine", + "label": "Inline Script", + "required": false, + "defaultValue": "# You can write your azure powershell scripts inline here. \n# You can also pass predefined and custom variables to this script using arguments", + "helpMarkDown": "Enter the script to execute.", + "visibleRule": "ScriptType = InlineScript", + "properties": { + "resizable": "true", + "rows": "10", + "maxLength": "5000" + } + }, + { + "name": "ScriptArguments", + "type": "string", + "label": "Script Arguments", + "defaultValue": "", + "visibleRule": "ScriptType = FilePath", + "required": false, + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + }, + "helpMarkDown": "Additional parameters to pass to PowerShell. Can be either ordinal or named parameters." + }, + { + "name": "errorActionPreference", + "type": "pickList", + "label": "ErrorActionPreference", + "required": false, + "defaultValue": "stop", + "options": { + "stop": "Stop", + "continue": "Continue", + "silentlyContinue": "SilentlyContinue" + }, + "helpMarkDown": "Select the value of the ErrorActionPreference variable for executing the script." + }, + { + "name": "FailOnStandardError", + "type": "boolean", + "label": "Fail on Standard Error", + "required": false, + "defaultValue": "false", + "helpMarkDown": "If this is true, this task will fail if any errors are written to the error pipeline, or if any data is written to the Standard Error stream." + }, + { + "name": "TargetAzurePs", + "aliases": [ + "azurePowerShellVersion" + ], + "type": "radio", + "label": "Azure PowerShell Version", + "defaultValue": "OtherVersion", + "required": false, + "options": { + "LatestVersion": "Latest installed version", + "OtherVersion": "Specify other version" + }, + "groupName": "AzurePowerShellVersionOptions", + "helpMarkDown": "In case of hosted agents, the supported Azure PowerShell Version is: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0 (Hosted VS2017 Queue).\nTo pick the latest version available on the agent, select \"Latest installed version\".\n\nFor private agents you can specify preferred version of Azure PowerShell using \"Specify version\"" + }, + { + "name": "CustomTargetAzurePs", + "aliases": [ + "preferredAzurePowerShellVersion" + ], + "type": "string", + "label": "Preferred Azure PowerShell Version", + "defaultValue": "", + "required": true, + "visibleRule": "TargetAzurePs = OtherVersion", + "groupName": "AzurePowerShellVersionOptions", + "helpMarkDown": "Preferred Azure PowerShell Version needs to be a proper semantic version eg. 1.2.3. Regex like 2.\\*,2.3.\\* is not supported. The Hosted VS2017 Pool currently supports Az module version: 1.0.0, 1.6.0, 2.3.2, 2.6.0, 3.1.0" + }, + { + "name": "pwsh", + "type": "boolean", + "label": "Use PowerShell Core", + "required": false, + "defaultValue": "false", + "helpMarkDown": "If this is true, then on Windows the task will use pwsh.exe from your PATH instead of powershell.exe.", + "groupName": "advanced" + }, + { + "name": "validateScriptSignature", + "type": "boolean", + "label": "Validate script signature", + "required": false, + "defaultValue": "false", + "helpMarkDown": "If this is true, then the task will first check to make sure specified script is signed and valid before executing it.", + "groupName": "advanced", + "visibleRule": "ScriptType = FilePath" + }, + { + "name": "workingDirectory", + "type": "filePath", + "label": "Working Directory", + "required": false, + "defaultValue": "", + "helpMarkDown": "Working directory where the script is run.", + "groupName": "advanced" + } + ], + "instanceNameFormat": "Azure PowerShell script: $(ScriptType)", + "execution": { + "PowerShell3": { + "target": "azurepowershell.ps1", + "platforms": [ + "windows" + ] + }, + "Node10": { + "target": "azurepowershell.js", + "argumentFormat": "" + }, + "Node16": { + "target": "azurepowershell.js", + "argumentFormat": "" + } + }, + "messages": { + "GeneratingScript": "Generating script.", + "JS_FormattedCommand": "Formatted command: %s", + "InvalidScriptArguments0": "Invalid script arguments '{0}'. Line breaks are not allowed.", + "InvalidScriptPath0": "Invalid script path '{0}'. Invalid path characters specified.", + "InvalidAzurePsVersion": "The Azure PowerShell version '{0}' specified is not in the correct format. Please check the format. An example of correct format is 1.0.1", + "JS_ExitCode": "PowerShell exited with code '%s'.", + "JS_Stderr": "PowerShell wrote one or more lines to the standard error stream.", + "ExpiredServicePrincipal": "Could not fetch access token for Azure. Verify if the Service Principal used is valid and not expired.", + "PS_ExitCode": "PowerShell exited with code '{0}'." + }, + "_buildConfigMapping": { + "Default": "5.234.0", + "Node20_229_2": "5.234.1" + } +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/task.loc.json b/_generated/AzurePowerShellV5/task.loc.json new file mode 100644 index 000000000000..ba16ddbc27ad --- /dev/null +++ b/_generated/AzurePowerShellV5/task.loc.json @@ -0,0 +1,210 @@ +{ + "id": "72A1931B-EFFB-4D2E-8FD8-F8472A07CB62", + "name": "AzurePowerShell", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "helpUrl": "https://aka.ms/azurepowershelltroubleshooting", + "category": "Deploy", + "visibility": [ + "Build", + "Release" + ], + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 5, + "Minor": 234, + "Patch": 0 + }, + "releaseNotes": "ms-resource:loc.releaseNotes", + "groups": [ + { + "name": "AzurePowerShellVersionOptions", + "displayName": "ms-resource:loc.group.displayName.AzurePowerShellVersionOptions", + "isExpanded": true + }, + { + "name": "advanced", + "displayName": "ms-resource:loc.group.displayName.advanced", + "isExpanded": false + } + ], + "minimumAgentVersion": "2.115.0", + "inputs": [ + { + "name": "ConnectedServiceNameARM", + "aliases": [ + "azureSubscription" + ], + "type": "connectedService:AzureRM", + "label": "ms-resource:loc.input.label.ConnectedServiceNameARM", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.ConnectedServiceNameARM", + "properties": { + "EndpointFilterRule": "ScopeLevel != AzureMLWorkspace" + } + }, + { + "name": "ScriptType", + "type": "radio", + "label": "ms-resource:loc.input.label.ScriptType", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.ScriptType", + "defaultValue": "FilePath", + "options": { + "FilePath": "Script File Path", + "InlineScript": "Inline Script" + } + }, + { + "name": "ScriptPath", + "type": "filePath", + "label": "ms-resource:loc.input.label.ScriptPath", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.ScriptPath", + "visibleRule": "ScriptType = FilePath" + }, + { + "name": "Inline", + "type": "multiLine", + "label": "ms-resource:loc.input.label.Inline", + "required": false, + "defaultValue": "# You can write your azure powershell scripts inline here. \n# You can also pass predefined and custom variables to this script using arguments", + "helpMarkDown": "ms-resource:loc.input.help.Inline", + "visibleRule": "ScriptType = InlineScript", + "properties": { + "resizable": "true", + "rows": "10", + "maxLength": "5000" + } + }, + { + "name": "ScriptArguments", + "type": "string", + "label": "ms-resource:loc.input.label.ScriptArguments", + "defaultValue": "", + "visibleRule": "ScriptType = FilePath", + "required": false, + "properties": { + "editorExtension": "ms.vss-services-azure.parameters-grid" + }, + "helpMarkDown": "ms-resource:loc.input.help.ScriptArguments" + }, + { + "name": "errorActionPreference", + "type": "pickList", + "label": "ms-resource:loc.input.label.errorActionPreference", + "required": false, + "defaultValue": "stop", + "options": { + "stop": "Stop", + "continue": "Continue", + "silentlyContinue": "SilentlyContinue" + }, + "helpMarkDown": "ms-resource:loc.input.help.errorActionPreference" + }, + { + "name": "FailOnStandardError", + "type": "boolean", + "label": "ms-resource:loc.input.label.FailOnStandardError", + "required": false, + "defaultValue": "false", + "helpMarkDown": "ms-resource:loc.input.help.FailOnStandardError" + }, + { + "name": "TargetAzurePs", + "aliases": [ + "azurePowerShellVersion" + ], + "type": "radio", + "label": "ms-resource:loc.input.label.TargetAzurePs", + "defaultValue": "OtherVersion", + "required": false, + "options": { + "LatestVersion": "Latest installed version", + "OtherVersion": "Specify other version" + }, + "groupName": "AzurePowerShellVersionOptions", + "helpMarkDown": "ms-resource:loc.input.help.TargetAzurePs" + }, + { + "name": "CustomTargetAzurePs", + "aliases": [ + "preferredAzurePowerShellVersion" + ], + "type": "string", + "label": "ms-resource:loc.input.label.CustomTargetAzurePs", + "defaultValue": "", + "required": true, + "visibleRule": "TargetAzurePs = OtherVersion", + "groupName": "AzurePowerShellVersionOptions", + "helpMarkDown": "ms-resource:loc.input.help.CustomTargetAzurePs" + }, + { + "name": "pwsh", + "type": "boolean", + "label": "ms-resource:loc.input.label.pwsh", + "required": false, + "defaultValue": "false", + "helpMarkDown": "ms-resource:loc.input.help.pwsh", + "groupName": "advanced" + }, + { + "name": "validateScriptSignature", + "type": "boolean", + "label": "ms-resource:loc.input.label.validateScriptSignature", + "required": false, + "defaultValue": "false", + "helpMarkDown": "ms-resource:loc.input.help.validateScriptSignature", + "groupName": "advanced", + "visibleRule": "ScriptType = FilePath" + }, + { + "name": "workingDirectory", + "type": "filePath", + "label": "ms-resource:loc.input.label.workingDirectory", + "required": false, + "defaultValue": "", + "helpMarkDown": "ms-resource:loc.input.help.workingDirectory", + "groupName": "advanced" + } + ], + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "execution": { + "PowerShell3": { + "target": "azurepowershell.ps1", + "platforms": [ + "windows" + ] + }, + "Node10": { + "target": "azurepowershell.js", + "argumentFormat": "" + }, + "Node16": { + "target": "azurepowershell.js", + "argumentFormat": "" + } + }, + "messages": { + "GeneratingScript": "ms-resource:loc.messages.GeneratingScript", + "JS_FormattedCommand": "ms-resource:loc.messages.JS_FormattedCommand", + "InvalidScriptArguments0": "ms-resource:loc.messages.InvalidScriptArguments0", + "InvalidScriptPath0": "ms-resource:loc.messages.InvalidScriptPath0", + "InvalidAzurePsVersion": "ms-resource:loc.messages.InvalidAzurePsVersion", + "JS_ExitCode": "ms-resource:loc.messages.JS_ExitCode", + "JS_Stderr": "ms-resource:loc.messages.JS_Stderr", + "ExpiredServicePrincipal": "ms-resource:loc.messages.ExpiredServicePrincipal", + "PS_ExitCode": "ms-resource:loc.messages.PS_ExitCode" + }, + "_buildConfigMapping": { + "Default": "5.234.0", + "Node20_229_2": "5.234.1" + } +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5/tsconfig.json b/_generated/AzurePowerShellV5/tsconfig.json new file mode 100644 index 000000000000..6a07b24acf54 --- /dev/null +++ b/_generated/AzurePowerShellV5/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs", + "skipLibCheck": true + } +} \ No newline at end of file diff --git a/_generated/AzurePowerShellV5_Node20/task.json b/_generated/AzurePowerShellV5_Node20/task.json index 21c03050df4a..336a3f181f8c 100644 --- a/_generated/AzurePowerShellV5_Node20/task.json +++ b/_generated/AzurePowerShellV5_Node20/task.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 1 }, "releaseNotes": "Added support for Az Module and cross platform agents.", "groups": [ @@ -208,7 +208,7 @@ "PS_ExitCode": "PowerShell exited with code '{0}'." }, "_buildConfigMapping": { - "Default": "5.231.0", - "Node20_229_2": "5.231.2" + "Default": "5.234.0", + "Node20_229_2": "5.234.1" } } \ No newline at end of file diff --git a/_generated/AzurePowerShellV5_Node20/task.loc.json b/_generated/AzurePowerShellV5_Node20/task.loc.json index 602775cf5b7c..0a53c9f811c6 100644 --- a/_generated/AzurePowerShellV5_Node20/task.loc.json +++ b/_generated/AzurePowerShellV5_Node20/task.loc.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 5, - "Minor": 231, - "Patch": 2 + "Minor": 234, + "Patch": 1 }, "releaseNotes": "ms-resource:loc.releaseNotes", "groups": [ @@ -208,7 +208,7 @@ "PS_ExitCode": "ms-resource:loc.messages.PS_ExitCode" }, "_buildConfigMapping": { - "Default": "5.231.0", - "Node20_229_2": "5.231.2" + "Default": "5.234.0", + "Node20_229_2": "5.234.1" } } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0.versionmap.txt b/_generated/AzureTestPlanV0.versionmap.txt new file mode 100644 index 000000000000..ea6fe113e445 --- /dev/null +++ b/_generated/AzureTestPlanV0.versionmap.txt @@ -0,0 +1,2 @@ +Default|0.234.0 +Node20-225|0.234.1 diff --git a/_generated/AzureTestPlanV0_Node20/.npmrc b/_generated/AzureTestPlanV0_Node20/.npmrc new file mode 100644 index 000000000000..5fca0d518be7 --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/.npmrc @@ -0,0 +1 @@ +scripts-prepend-node-path=true diff --git a/_generated/AzureTestPlanV0_Node20/Invokers/gradleinvoker.ts b/_generated/AzureTestPlanV0_Node20/Invokers/gradleinvoker.ts new file mode 100644 index 000000000000..02dcc2bea99a --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/Invokers/gradleinvoker.ts @@ -0,0 +1,31 @@ +import { spawn } from '../testexecutor' +import tl = require('azure-pipelines-task-lib/task'); +import utils = require('../utils'); +import constants = require('../constants'); +export async function executegradletests(testsToBeExecuted: string[]) { + + //public doc link: https://docs.gradle.org/current/userguide/command_line_interface.html + //gradle command like "gradle test --tests= --tests=" + + const executable = constants.GRADLE_EXECUTABLE; + const args = [] + + args.push('test'); + + for (let testcase of testsToBeExecuted) { + + // in some cases found that gradle is including () in test name + utils.removeParenthesesFromEnd(testcase); + args.push('--tests=' + testcase); + } + + tl.debug("Executing gradle tests with executable : " + executable); + tl.debug("Executing gradle tests with args :" + args); + + const { status, error } = await spawn(executable, args) + if (error) { + tl.error("Error executing gradle command, " + error); + } + + return { exitCode: status ?? 1 } +} \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/Invokers/maveninvoker.ts b/_generated/AzureTestPlanV0_Node20/Invokers/maveninvoker.ts new file mode 100644 index 000000000000..5dd8faa44c28 --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/Invokers/maveninvoker.ts @@ -0,0 +1,39 @@ +import { spawn } from '../testexecutor' +import tl = require('azure-pipelines-task-lib/task'); +import utils = require('../utils'); +import constants = require('../constants'); + +export async function executemaventests(testsToBeExecuted: string[]) { + + //public doc link: https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html + //maven command like "mvn test -Dtest=," + + const executable = constants.MVN_EXECUTABLE; + const args = [] + const testsToRun =[] + + for (let tests of testsToBeExecuted) { + const modifiedTest = utils.replaceLastDotWithHash(tests); + testsToRun.push(modifiedTest); + } + + if (testsToRun.length > 0) + { + const testsList = testsToRun.join(',') + const dtest = constants.MAVEN_DTEST; + const combinedTestArgs = dtest + testsList; + + args.push('test'); + args.push(combinedTestArgs); + } + + tl.debug("Executing java maven tests with executable : " + executable); + tl.debug("Executing java maven tests with args :" + args); + + const { status, error } = await spawn(executable, args) + if (error) { + tl.error("Error executing mvn command, " + error); + } + + return { exitCode: status ?? 1 } + } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/Invokers/pythonivoker.ts b/_generated/AzureTestPlanV0_Node20/Invokers/pythonivoker.ts new file mode 100644 index 000000000000..9188f8822fe2 --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/Invokers/pythonivoker.ts @@ -0,0 +1,29 @@ +import { spawn } from '../testexecutor' +import tl = require('azure-pipelines-task-lib/task'); +import constants = require('../constants'); + +export async function executepythontests(testsToBeExecuted: string[]) { + + //public doc link: https://docs.pytest.org/en/7.1.x/how-to/usage.html#specifying-which-tests-to-run + //pytest command like "pytest -v --junitxml=junit.xml" + + const executable = constants.PYTEST_EXECUTABLE; + let args: string[] = []; + + for (let testcase of testsToBeExecuted) { + args.push(testcase); + } + + args.push('--junitxml=junit.xml') + + tl.debug("Executing python tests with executable : " + executable); + tl.debug("Executing python tests with args :" + args); + + const { status, error } = await spawn(executable, args) + + if (error) { + tl.error("Error executing pytest command, " + error); + } + + return { exitCode: status ?? 1 } +} \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/Strings/resources.resjson/en-US/resources.resjson b/_generated/AzureTestPlanV0_Node20/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..ab005739518c --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,22 @@ +{ + "loc.friendlyName": "Azure Test Plan", + "loc.helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613742)", + "loc.description": "Run manual and automated tests in test plan in Java and python language", + "loc.instanceNameFormat": "Azure Test Plan - $(testSelector)", + "loc.input.label.testSelector": "Test cases to be executed", + "loc.input.help.testSelector": "
      • Manual tests: Use this option to trigger manual tests from your test plan.
      • Automated tests: Use this option to run tests from your test plan that have automated test method associated with it.
      • ", + "loc.input.label.testPlan": "Test plan", + "loc.input.help.testPlan": "Select a test plan containing test suites with test cases.", + "loc.input.label.testSuite": "Test suite", + "loc.input.help.testSuite": "Select one or more test suites containing test cases.", + "loc.input.label.testConfiguration": "Test configuration", + "loc.input.help.testConfiguration": "Select Test Configuration.", + "loc.input.label.testLanguageInput": "Select Test framework language", + "loc.input.help.testLanguageInput": "Test Framework Language of automated tests in test plan", + "loc.messages.testPlanInput": "Test plan Id : %s", + "loc.messages.testplanConfigInput": "Test plan configuration Id : %s", + "loc.messages.testSuiteSelected": "Test suite Id selected: %s", + "loc.messages.automatedTestsTriggered": "Trigerring execution of Automated tests from test plan", + "loc.messages.ErrorFailTaskOnExecutingTests": "Error occured while executing test command", + "loc.messages.ErrorFailTaskOnAPIFailure": "Error occured while fetching automated tests from test plan inputs" +} \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/automatedTestInvoker.ts b/_generated/AzureTestPlanV0_Node20/automatedTestInvoker.ts new file mode 100644 index 000000000000..e4645c0ceb9f --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/automatedTestInvoker.ts @@ -0,0 +1,36 @@ +import * as tl from 'azure-pipelines-task-lib/task' +import { executepythontests } from './Invokers/pythonivoker' +import { executemaventests } from './Invokers/maveninvoker' +import { executegradletests } from './Invokers/gradleinvoker' + +export async function testInvoker(testsToBeExecuted: string[]) { + + const testLanguageStrings = tl.getDelimitedInput('testLanguageInput', ',', true); + + for (const testLanguage of testLanguageStrings) { + + if (testLanguage === null || testLanguage === undefined) { + console.log("Please select the test framework language from the task dropdown list to execute automated tests"); + return; + } + + switch (testLanguage) { + case 'Java-Maven': + await executemaventests(testsToBeExecuted); + break; + + case 'Java-Gradle': + await executegradletests(testsToBeExecuted); + break; + + case 'Python': + await executepythontests(testsToBeExecuted); + break; + + default: + console.log('Invalid test Language Input selected.'); + } + + } + +} \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/automatedTests.ts b/_generated/AzureTestPlanV0_Node20/automatedTests.ts new file mode 100644 index 000000000000..711e1fc3a57e --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/automatedTests.ts @@ -0,0 +1,68 @@ +import tl = require('azure-pipelines-task-lib/task'); +import { testInvoker } from './automatedTestInvoker' +import { TestPlanData, getAutomatedTestData } from './getAutomatedTests'; +import { TestCase } from 'azure-devops-node-api/interfaces/TestPlanInterfaces'; + + +export async function automatedTestsFlow(testSelectorInput: string) { + + let listOfTestsToBeExecuted: string[] = []; + + console.log(tl.loc('automatedTestsTriggered')); + await getFQNsOfAutomatedTestCases() + .then((testsToBeExecuted) => { + listOfTestsToBeExecuted = testsToBeExecuted; + }) + .catch((error) => { + tl.error("Error while fetching FqnsOfAutomatedTestCases :" + error); + tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnAPIFailure')); + }); + + tl.debug("Invoking test execution for tests: " + listOfTestsToBeExecuted); + + if (listOfTestsToBeExecuted !== null && listOfTestsToBeExecuted !== undefined && listOfTestsToBeExecuted.length > 0) { + testInvoker(listOfTestsToBeExecuted); + } + else { + console.log("No automated tests found for given test plan inputs "); + if (testSelectorInput === 'automatedTests') { + tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnNoAutomatedTestsFound')); + } + else { + tl.setResult(tl.TaskResult.Succeeded, "Successfully triggered manual test execution"); + } + } + +} + +export async function getFQNsOfAutomatedTestCases(): Promise{ + + let testpointidslist: number[]; + let fqnlist: string[]; + + const testPlan = parseInt(tl.getInput('testPlan')); + const testPlanConfigId = parseInt(tl.getInput('testConfiguration')); + const testSuiteStrings = tl.getDelimitedInput('testSuite', ',', true); + const testSuites = new Array(); + testSuiteStrings.forEach(element => { + const testSuiteId = parseInt(element); + testSuites.push(testSuiteId); + }) + + console.log('Test Plan Id:' + testPlan); + console.log('Test Plan Configuration Id:' + testPlanConfigId); + console.log('Test Suite Ids:' + testSuites); + + await getAutomatedTestData(testPlan, testSuites, testPlanConfigId) + .then((testPlanData) => { + testpointidslist = testPlanData.testPointIds; + fqnlist = testPlanData.listOfFQNOfTestCases; + }) + .catch((error) => { + tl.error("Error while fetching Automated Test Cases Data :" + error); + tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnAPIFailure')); + }); + + return fqnlist; +} + diff --git a/_generated/AzureTestPlanV0_Node20/constants.ts b/_generated/AzureTestPlanV0_Node20/constants.ts new file mode 100644 index 000000000000..14970c3408da --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/constants.ts @@ -0,0 +1,7 @@ +// Constants +export const MVN_EXECUTABLE: string = 'mvn'; +export const MAVEN_DTEST: string = '-Dtest='; +export const GRADLE_EXECUTABLE: string = 'gradle'; +export const PYTEST_EXECUTABLE: string = 'pytest'; +export const AUTOMATED_TEST_NAME = "Microsoft.VSTS.TCM.AutomatedTestName"; +export const AUTOMATED_TEST_STORAGE = "Microsoft.VSTS.TCM.AutomatedTestStorage"; diff --git a/_generated/AzureTestPlanV0_Node20/getAutomatedTests.ts b/_generated/AzureTestPlanV0_Node20/getAutomatedTests.ts new file mode 100644 index 000000000000..d7149d83032a --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/getAutomatedTests.ts @@ -0,0 +1,105 @@ +import { Console } from "console"; +import tl = require('azure-pipelines-task-lib/task'); +import apim = require('azure-devops-node-api'); +import { WorkItemDetails, TestCase } from 'azure-devops-node-api/interfaces/TestPlanInterfaces'; +import { PagedList } from 'azure-devops-node-api/interfaces/common/VSSInterfaces'; +import TestPlanInterfaces = require('azure-devops-node-api/interfaces/TestPlanInterfaces'); +import VSSInterfaces = require('azure-devops-node-api/interfaces/common/VSSInterfaces'); +import constants = require('./constants'); + + +export interface TestPlanData { + testPointIds: number[]; + listOfFQNOfTestCases: string[]; +} +export async function getAutomatedTestData(testPlanId: number, testSuiteIds: number[], testConfigurationId: number): Promise { + + const testPlanData: TestPlanData = { testPointIds: [], listOfFQNOfTestCases: [] }; + let token = null; + const AutomatedTestName = constants.AUTOMATED_TEST_NAME; + const AutomatedTestStorage = constants.AUTOMATED_TEST_STORAGE; + + if (testPlanId == 0 || testConfigurationId == 0) { + return testPlanData; + } + + for (const testSuiteId of testSuiteIds) { + if (testSuiteId === 0) { + continue; + } + + let testCasesData: TestCase[] = []; + + do { + try { + let testCasesResponse = await fetchTestPlanList(testPlanId, testSuiteId, testConfigurationId.toString(), token); + + token = testCasesResponse.continuationToken; + + for (let key in testCasesResponse) { + if (testCasesResponse.hasOwnProperty(key)) { + testCasesData.push(testCasesResponse[key]); + } + } + + } catch (error) { + tl.error("Error fetching test cases list:" + error); + token = undefined; + } + } while ((token !== undefined) && (token !== null)); + + if (testCasesData.length === 0) { + console.log(`No test cases for test suite ${testSuiteId}`); + continue; + } + + testCasesData.forEach(testCase => { + let automatedTestName = ''; + let automatedTestStorage = ''; + + for (const witField of testCase.workItem?.workItemFields || []) { + const parsedWitField = JSON.parse(JSON.stringify(witField)); // Deep copy for safety + + if (parsedWitField[AutomatedTestName] !== undefined && parsedWitField[AutomatedTestName] !== null) { + automatedTestName = parsedWitField[AutomatedTestName].toString(); + testPlanData.listOfFQNOfTestCases.push(automatedTestName); + } + + if (parsedWitField[AutomatedTestStorage] !== undefined && parsedWitField[AutomatedTestStorage] !== null) { + automatedTestStorage = parsedWitField[AutomatedTestStorage].toString(); + } + } + + if (automatedTestName !== '' && automatedTestStorage !== '') { + if (testCase.pointAssignments.length > 0) { + testPlanData.testPointIds.push(testCase.pointAssignments[0].id); + } + } + }); + + } + + return testPlanData; +} + +export async function fetchTestPlanList(testPlanId: number, testSuiteId: number, testConfigurationId: string, continuationToken: string): Promise> { + + let url = tl.getEndpointUrl('SYSTEMVSSCONNECTION', false); + let token = tl.getEndpointAuthorizationParameter('SYSTEMVSSCONNECTION', 'ACCESSTOKEN', false); + let projectId = tl.getVariable('System.TeamProjectId'); + let auth = token.length == 52 ? apim.getPersonalAccessTokenHandler(token) : apim.getBearerHandler(token); + let vsts: apim.WebApi = new apim.WebApi(url, auth); + let testPlanApi = await vsts.getTestPlanApi(); + + tl.debug("Fetching test case list for test plan:" + testPlanId + " test suite id:" + testSuiteId + " test configuration id:" + testConfigurationId); + + return testPlanApi.getTestCaseList( + projectId, + testPlanId, + testSuiteId, + null, + testConfigurationId, + null, + continuationToken) + +} diff --git a/_generated/AzureTestPlanV0_Node20/icon.png b/_generated/AzureTestPlanV0_Node20/icon.png new file mode 100644 index 000000000000..686d0730e9fa Binary files /dev/null and b/_generated/AzureTestPlanV0_Node20/icon.png differ diff --git a/_generated/AzureTestPlanV0_Node20/icon.svg b/_generated/AzureTestPlanV0_Node20/icon.svg new file mode 100644 index 000000000000..40206e1780c4 --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/icon.svg @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/_generated/AzureTestPlanV0_Node20/manualTests.ts b/_generated/AzureTestPlanV0_Node20/manualTests.ts new file mode 100644 index 000000000000..e435be48fd58 --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/manualTests.ts @@ -0,0 +1,6 @@ +import tl = require('azure-pipelines-task-lib/task'); + +export function manualTestsFlow() { + console.log("To do:"); + console.log("Manual trigger flow to be implemented"); +} \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/package-lock.json b/_generated/AzureTestPlanV0_Node20/package-lock.json new file mode 100644 index 000000000000..df8150002c7a --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/package-lock.json @@ -0,0 +1,964 @@ +{ + "name": "azure-tasks-runTestPlan", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", + "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==" + }, + "@types/node": { + "version": "20.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/q": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.7.tgz", + "integrity": "sha512-HBPgtzp44867rkL+IzQ3560/E/BlobwCjeXsuKqogrcE99SKgZR4tvBBCuNJZMhUFMz26M7cjKWZg785lllwpA==" + }, + "@types/qs": { + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz", + "integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==" + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + }, + "@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + }, + "adm-zip": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==" + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, + "azure-pipelines-task-lib": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.6.1.tgz", + "integrity": "sha512-3/LFgNNHY0Cw9vArQPxM6ZgPWt3/G2Yy6F75k2AJzKUCotp5X9gZcvF399tVo6T6lTOlp3Vm7VBXq+kzZ6hZmw==", + "requires": { + "adm-zip": "^0.5.10", + "deasync": "^0.1.28", + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "nodejs-file-downloader": "^4.11.1", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "uuid": "^3.0.1" + } + }, + "azure-pipelines-tasks-docker-common": { + "version": "2.198.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-docker-common/-/azure-pipelines-tasks-docker-common-2.198.1.tgz", + "integrity": "sha512-lgN/sNVhxVxnIM1HoUy8BO8A7idw1ypICBmdPOJUdw21Oy+7cplWfTnygFLPvGSFCN3VnSJFbzBe8LewcWplow==", + "requires": { + "@types/mocha": "^5.2.7", + "@types/node": "^10.17.0", + "@types/q": "1.5.4", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^3.1.0", + "del": "2.2.0", + "q": "1.4.1" + }, + "dependencies": { + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" + }, + "azure-pipelines-task-lib": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-3.4.0.tgz", + "integrity": "sha512-3eC4OTFw+7xD7A2aUhxR/j+jRlTI+vVfS0CGxt1pCLs4c/KmY0tQWgbqjD3157kmiucWxELBvgZHaD2gCBe9fg==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + } + } + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha512-/CdEdaw49VZVmyIDGUQKDDT53c7qBkO6g5CefWz91Ae+l4+cRtcDYwMTXh6me4O8TMldeGHG3N2Bl84V78Ywbg==" + } + } + }, + "azure-pipelines-tasks-utility-common": { + "version": "3.225.1", + "resolved": "https://registry.npmjs.org/azure-pipelines-tasks-utility-common/-/azure-pipelines-tasks-utility-common-3.225.1.tgz", + "integrity": "sha512-4wtVKuvx2PcQI0W8xkMdS/S+tf9Qu7wMJl4HSTLE1gjQ2x9o/6QbhMogz6O1+8ofxvTqmI4scA7GHKccDAwQpQ==", + "requires": { + "@types/node": "^16.11.39", + "azure-pipelines-task-lib": "^4.4.0", + "azure-pipelines-tool-lib": "^2.0.0-preview", + "js-yaml": "3.13.1", + "semver": "^5.4.1" + }, + "dependencies": { + "@types/node": { + "version": "16.18.70", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.70.tgz", + "integrity": "sha512-8eIk20G5VVVQNZNouHjLA2b8utE2NvGybLjMaF4lyhA9uhGwnmXF8o+icdXKGSQSNANJewXva/sFUoZLwAaYAg==" + } + } + }, + "azure-pipelines-tool-lib": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/azure-pipelines-tool-lib/-/azure-pipelines-tool-lib-2.0.6.tgz", + "integrity": "sha512-972uj4vMieY2tHrVowjHDR5N8rvuJP7eIOzchjUz+eHTEtRCLWbQbfJpVxcbfsA+KZJOomqTxgZ3+icS642hqw==", + "requires": { + "@types/semver": "^5.3.0", + "@types/uuid": "^3.4.5", + "azure-pipelines-task-lib": "^4.1.0", + "semver": "^5.7.0", + "semver-compare": "^1.0.0", + "typed-rest-client": "^1.8.6", + "uuid": "^3.3.2" + }, + "dependencies": { + "@types/uuid": { + "version": "3.4.12", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.12.tgz", + "integrity": "sha512-4mZWvs9415R6KNlPUZaMDgpnNpFZrO7yZoFfVc6phuOpnUlU06KGu4+83e857jfWkYBMNVZF/1HDoG/aEbePow==" + } + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "requires": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "deasync": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.29.tgz", + "integrity": "sha512-EBtfUhVX23CE9GR6m+F8WPeImEE4hR/FW9RkK0PMl9V1t283s0elqsTD8EZjaKX28SY1BW2rYfCgNsAYdpamUw==", + "requires": { + "bindings": "^1.5.0", + "node-addon-api": "^1.7.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "del": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.0.tgz", + "integrity": "sha512-AZDiRb78EEGYCsAZTG3v+CM5q8J0BIs+wI7QeUtyosm+zIMm4XSmp6aI/K7cU9l+YaKpDKN9dYP1xTrNjLQ+LA==", + "requires": { + "globby": "^4.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "requires": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" + }, + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globby": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz", + "integrity": "sha512-JPDtMSr0bt25W64q792rvlrSwIaZwqUAhqdYKSr57Wh/xBcQ5JDWLM85ndn+Q1WdBQXLb9YGCl0QN/T0HpqU0A==", + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^6.0.1", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "requires": { + "get-intrinsic": "^1.2.2" + } + }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + } + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "requires": { + "hasown": "^2.0.0" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha512-cnS56eR9SPAscL77ik76ATVqoPARTqPIVkMDVxRaWH06zT+6+CzIroYRJ0VVvm0Z1zfAvxvz9i/D3Ppjaqt5Nw==" + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==", + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mockery": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-2.1.0.tgz", + "integrity": "sha512-9VkOmxKlWXoDO/h1jDZaS4lH33aWfRiJiNT/tKj+8OGzrcFDLo8d0syGdbsc3Bc4GvRXPb+NMMvojotmuGJTvA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==" + }, + "nodejs-file-downloader": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/nodejs-file-downloader/-/nodejs-file-downloader-4.12.1.tgz", + "integrity": "sha512-LpfCTNhh805AlLnJnzt1PuEj+RmbrccbAQZ6hBRw2e6QPVR0Qntuo6qqyvPHG5s77/0w0IEKgRAD4nbSnr/X4w==", + "requires": { + "follow-redirects": "^1.15.1", + "https-proxy-agent": "^5.0.0", + "mime-types": "^2.1.27", + "sanitize-filename": "^1.6.3" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "requires": { + "pinkie": "^2.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "requires": { + "asap": "~2.0.6" + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, + "qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==" + }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + } + } + }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "typed-rest-client": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", + "requires": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "dev": true + }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + } + } +} diff --git a/_generated/AzureTestPlanV0_Node20/package.json b/_generated/AzureTestPlanV0_Node20/package.json new file mode 100644 index 000000000000..a62592d1e683 --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/package.json @@ -0,0 +1,34 @@ +{ + "name": "azure-tasks-runTestPlan", + "version": "1.0.0", + "description": "Azure Pipelines Run Manual and Automated Test execution Task", + "main": "runTestPlan.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/azure-pipelines-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/azure-pipelines-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/azure-pipelines-tasks#readme", + "dependencies": { + "@types/node": "^20.3.1", + "@types/q": "^1.0.7", + "@types/mocha": "^9.1.1", + "@types/uuid": "^8.3.0", + "azure-pipelines-task-lib": "^4.1.0", + "azure-pipelines-tasks-docker-common": "2.198.1", + "azure-pipelines-tasks-utility-common": "^3.212.0", + "azure-pipelines-tool-lib": "^2.0.0-preview", + "typed-rest-client": "^1.8.9", + "axios": "^1.6.2" + }, + "devDependencies": { + "typescript": "5.1.6" + } +} diff --git a/_generated/AzureTestPlanV0_Node20/runTestPlan.ts b/_generated/AzureTestPlanV0_Node20/runTestPlan.ts new file mode 100644 index 000000000000..a1f3c4001a2e --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/runTestPlan.ts @@ -0,0 +1,19 @@ +import * as tl from 'azure-pipelines-task-lib/task'; +import { manualTestsFlow} from './manualTests' +import { automatedTestsFlow} from './automatedTests' + +export async function run() { + + const testSelectorInput = tl.getInput('testSelector'); + console.log('Test Selector selected : ' + testSelectorInput); + + // trigger manual, automated or both tests based on user's input + if (testSelectorInput.includes('manualTests')) { + manualTestsFlow(); + } + if (testSelectorInput.includes('automatedTests')) { + automatedTestsFlow(testSelectorInput); + } +} + +run(); diff --git a/_generated/AzureTestPlanV0_Node20/task.json b/_generated/AzureTestPlanV0_Node20/task.json new file mode 100644 index 000000000000..58b1be53809a --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/task.json @@ -0,0 +1,144 @@ +{ + "id": "105e2492-460a-4da6-56d5-2fa9ab3f0174", + "name": "AzureTestPlan", + "friendlyName": "Azure Test Plan", + "description": "Run manual and automated tests in test plan in Java and python language", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/test/publish-test-results", + "helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkID=613742)", + "category": "Test", + "visibility": [ + "Build", + "Release" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 234, + "Patch": 1 + }, + "preview": true, + "demands": [], + "minimumAgentVersion": "2.144.0", + "inputs": [ + { + "name": "testSelector", + "type": "pickList", + "label": "Test cases to be executed", + "required": true, + "helpMarkDown": "
        • Manual tests: Use this option to trigger manual tests from your test plan.
        • Automated tests: Use this option to run tests from your test plan that have automated test method associated with it.
        • ", + "options": { + "manualTests": "Manual tests", + "automatedTests": "Automated tests" + }, + "properties": { + "MultiSelectFlatList": "True" + } + }, + { + "name": "testPlan", + "type": "pickList", + "label": "Test plan", + "defaultValue": "", + "required": true, + "helpMarkDown": "Select a test plan containing test suites with test cases.", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testSuite", + "type": "pickList", + "label": "Test suite", + "defaultValue": "", + "helpMarkDown": "Select one or more test suites containing test cases.", + "required": true, + "properties": { + "MultiSelect": "True", + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testConfiguration", + "type": "pickList", + "label": "Test configuration", + "defaultValue": "", + "required": true, + "helpMarkDown": "Select Test Configuration.", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testLanguageInput", + "type": "pickList", + "label": "Select Test framework language", + "helpMarkDown": "Test Framework Language of automated tests in test plan", + "options": { + "Java-Maven": "Java-Maven", + "Java-Gradle": "Java-Gradle", + "Python": "Python" + }, + "properties": { + "MultiSelectFlatList": "True" + } + } + ], + "dataSourceBindings": [ + { + "target": "testPlan", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans?filterActivePlans=true&api-version=3.0-preview.2&$skip={{skip}}&$top=1000", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }", + "callbackContextTemplate": "{\"skip\": \"{{add skip 1000}}\"}", + "callbackRequiredTemplate": "{{isEqualNumber result.count 1000}}", + "initialContextTemplate": "{\"skip\": \"0\"}" + }, + { + "target": "testConfiguration", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/configurations?api-version=3.0-preview.1", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }" + }, + { + "target": "testSuite", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans/{{testPlan}}/suites?$asTreeView=true&api-version=3.0-preview.2", + "parameters": { + "testPlan": "$(testPlan)" + }, + "resultSelector": "jsonpath:$.value[*]" + } + ], + "instanceNameFormat": "Azure Test Plan - $(testSelector)", + "execution": { + "Node10": { + "target": "runTestPlan.js", + "argumentFormat": "" + }, + "Node16": { + "target": "runTestPlan.js", + "argumentFormat": "" + }, + "Node20_1": { + "target": "runTestPlan.js", + "argumentFormat": "" + } + }, + "messages": { + "testPlanInput": "Test plan Id : %s", + "testplanConfigInput": "Test plan configuration Id : %s", + "testSuiteSelected": "Test suite Id selected: %s", + "automatedTestsTriggered": "Trigerring execution of Automated tests from test plan", + "ErrorFailTaskOnExecutingTests": "Error occured while executing test command", + "ErrorFailTaskOnAPIFailure": "Error occured while fetching automated tests from test plan inputs" + }, + "_buildConfigMapping": { + "Default": "0.234.0", + "Node20-225": "0.234.1" + } +} \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/task.loc.json b/_generated/AzureTestPlanV0_Node20/task.loc.json new file mode 100644 index 000000000000..be1862893e1b --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/task.loc.json @@ -0,0 +1,144 @@ +{ + "id": "105e2492-460a-4da6-56d5-2fa9ab3f0174", + "name": "AzureTestPlan", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/test/publish-test-results", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "category": "Test", + "visibility": [ + "Build", + "Release" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 0, + "Minor": 234, + "Patch": 1 + }, + "preview": true, + "demands": [], + "minimumAgentVersion": "2.144.0", + "inputs": [ + { + "name": "testSelector", + "type": "pickList", + "label": "ms-resource:loc.input.label.testSelector", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testSelector", + "options": { + "manualTests": "Manual tests", + "automatedTests": "Automated tests" + }, + "properties": { + "MultiSelectFlatList": "True" + } + }, + { + "name": "testPlan", + "type": "pickList", + "label": "ms-resource:loc.input.label.testPlan", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testPlan", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testSuite", + "type": "pickList", + "label": "ms-resource:loc.input.label.testSuite", + "defaultValue": "", + "helpMarkDown": "ms-resource:loc.input.help.testSuite", + "required": true, + "properties": { + "MultiSelect": "True", + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testConfiguration", + "type": "pickList", + "label": "ms-resource:loc.input.label.testConfiguration", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testConfiguration", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + } + }, + { + "name": "testLanguageInput", + "type": "pickList", + "label": "ms-resource:loc.input.label.testLanguageInput", + "helpMarkDown": "ms-resource:loc.input.help.testLanguageInput", + "options": { + "Java-Maven": "Java-Maven", + "Java-Gradle": "Java-Gradle", + "Python": "Python" + }, + "properties": { + "MultiSelectFlatList": "True" + } + } + ], + "dataSourceBindings": [ + { + "target": "testPlan", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans?filterActivePlans=true&api-version=3.0-preview.2&$skip={{skip}}&$top=1000", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }", + "callbackContextTemplate": "{\"skip\": \"{{add skip 1000}}\"}", + "callbackRequiredTemplate": "{{isEqualNumber result.count 1000}}", + "initialContextTemplate": "{\"skip\": \"0\"}" + }, + { + "target": "testConfiguration", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/configurations?api-version=3.0-preview.1", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }" + }, + { + "target": "testSuite", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans/{{testPlan}}/suites?$asTreeView=true&api-version=3.0-preview.2", + "parameters": { + "testPlan": "$(testPlan)" + }, + "resultSelector": "jsonpath:$.value[*]" + } + ], + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "execution": { + "Node10": { + "target": "runTestPlan.js", + "argumentFormat": "" + }, + "Node16": { + "target": "runTestPlan.js", + "argumentFormat": "" + }, + "Node20_1": { + "target": "runTestPlan.js", + "argumentFormat": "" + } + }, + "messages": { + "testPlanInput": "ms-resource:loc.messages.testPlanInput", + "testplanConfigInput": "ms-resource:loc.messages.testplanConfigInput", + "testSuiteSelected": "ms-resource:loc.messages.testSuiteSelected", + "automatedTestsTriggered": "ms-resource:loc.messages.automatedTestsTriggered", + "ErrorFailTaskOnExecutingTests": "ms-resource:loc.messages.ErrorFailTaskOnExecutingTests", + "ErrorFailTaskOnAPIFailure": "ms-resource:loc.messages.ErrorFailTaskOnAPIFailure" + }, + "_buildConfigMapping": { + "Default": "0.234.0", + "Node20-225": "0.234.1" + } +} \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/testexecutor.ts b/_generated/AzureTestPlanV0_Node20/testexecutor.ts new file mode 100644 index 000000000000..afb60df1681f --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/testexecutor.ts @@ -0,0 +1,23 @@ +import * as path from 'path'; +import * as fs from 'fs'; +import * as semver from "semver" +import { spawnSync } from 'child_process' +import tl = require('azure-pipelines-task-lib/task'); + +export function spawn(executable: string, args: string[]): Promise { + + console.log("-------------------------------------------") + console.log("test execution begins") + console.log("-------------------------------------------") + console.log('Test command executable: ' + executable); + console.log('Test command args: ' + args); + + const { status, error } = spawnSync(executable, args, { stdio: 'inherit' }) + + return Promise.resolve({ status, error }) +} + +interface SpawnResult { + status: number | null + error?: Error +} \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/tsconfig.json b/_generated/AzureTestPlanV0_Node20/tsconfig.json new file mode 100644 index 000000000000..0438b79f69ac --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs" + } +} \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/utils.ts b/_generated/AzureTestPlanV0_Node20/utils.ts new file mode 100644 index 000000000000..5ea70d7cea39 --- /dev/null +++ b/_generated/AzureTestPlanV0_Node20/utils.ts @@ -0,0 +1,23 @@ +export function removeParenthesesFromEnd(inputString) { + // Check if the string ends with parentheses + if (inputString.endsWith('()')) { + // Remove the parentheses from the end + return inputString.slice(0, -2); + } else { + // If no parentheses at the end, return the original string + return inputString; + } +} + +export function replaceLastDotWithHash(inputString) { + const lastDotIndex = inputString.lastIndexOf('.'); + + if (lastDotIndex !== -1) { + const stringWithHash = inputString.slice(0, lastDotIndex) + '#' + inputString.slice(lastDotIndex + 1); + return stringWithHash; + } else { + // If there is no dot in the string, return the original string + return inputString; + } +} + diff --git a/_generated/CondaEnvironmentV1.versionmap.txt b/_generated/CondaEnvironmentV1.versionmap.txt index 6584f283a070..26181367ed1e 100644 --- a/_generated/CondaEnvironmentV1.versionmap.txt +++ b/_generated/CondaEnvironmentV1.versionmap.txt @@ -1,2 +1,2 @@ -Default|1.234.0 -Node20-225|1.234.1 +Default|1.235.0 +Node20-225|1.235.1 diff --git a/_generated/CondaEnvironmentV1/Strings/resources.resjson/en-US/resources.resjson b/_generated/CondaEnvironmentV1/Strings/resources.resjson/en-US/resources.resjson index 2352ea09a954..74ac7b229902 100644 --- a/_generated/CondaEnvironmentV1/Strings/resources.resjson/en-US/resources.resjson +++ b/_generated/CondaEnvironmentV1/Strings/resources.resjson/en-US/resources.resjson @@ -24,5 +24,6 @@ "loc.messages.ReactivateExistingEnvironment": "Found existing environment %s and the task's \"Clean environment\" parameter is not set. Reactivating ...", "loc.messages.ParameterRequired": "The `%s` parameter is required", "loc.messages.PlatformNotRecognized": "Platform not recognized", - "loc.messages.PrependPath": "Prepending PATH environment variable with directory: %s" + "loc.messages.PrependPath": "Prepending PATH environment variable with directory: %s", + "loc.messages.DeprecatedTask": "The CondaEnvironment@1 (Conda environment) task has been deprecated since February 13, 2019 and will soon be retired. Use the Conda CLI ('conda') directly from a bash/pwsh/script task." } \ No newline at end of file diff --git a/_generated/CondaEnvironmentV1/main.ts b/_generated/CondaEnvironmentV1/main.ts index 6bd77de58ee9..321d5f4a1173 100644 --- a/_generated/CondaEnvironmentV1/main.ts +++ b/_generated/CondaEnvironmentV1/main.ts @@ -16,6 +16,11 @@ import { condaEnvironment } from './conda'; cleanEnvironment: task.getBoolInput('cleanEnvironment') }, getPlatform()); + let shouldFail = task.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + + if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(task.loc("DeprecatedTask")); + } task.setResult(task.TaskResult.Succeeded, ""); } catch (e) { task.setResult(task.TaskResult.Failed, e.message); diff --git a/_generated/CondaEnvironmentV1/task.json b/_generated/CondaEnvironmentV1/task.json index 5e59c248789c..48948eb4c677 100644 --- a/_generated/CondaEnvironmentV1/task.json +++ b/_generated/CondaEnvironmentV1/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, @@ -101,10 +101,11 @@ "ReactivateExistingEnvironment": "Found existing environment %s and the task's \"Clean environment\" parameter is not set. Reactivating ...", "ParameterRequired": "The `%s` parameter is required", "PlatformNotRecognized": "Platform not recognized", - "PrependPath": "Prepending PATH environment variable with directory: %s" + "PrependPath": "Prepending PATH environment variable with directory: %s", + "DeprecatedTask": "The CondaEnvironment@1 (Conda environment) task has been deprecated since February 13, 2019 and will soon be retired. Use the Conda CLI ('conda') directly from a bash/pwsh/script task." }, "_buildConfigMapping": { - "Default": "1.234.0", - "Node20-225": "1.234.1" + "Default": "1.235.0", + "Node20-225": "1.235.1" } } \ No newline at end of file diff --git a/_generated/CondaEnvironmentV1/task.loc.json b/_generated/CondaEnvironmentV1/task.loc.json index 2045eb23adf7..c7dfb5c58d09 100644 --- a/_generated/CondaEnvironmentV1/task.loc.json +++ b/_generated/CondaEnvironmentV1/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 0 }, "deprecated": true, @@ -101,10 +101,11 @@ "ReactivateExistingEnvironment": "ms-resource:loc.messages.ReactivateExistingEnvironment", "ParameterRequired": "ms-resource:loc.messages.ParameterRequired", "PlatformNotRecognized": "ms-resource:loc.messages.PlatformNotRecognized", - "PrependPath": "ms-resource:loc.messages.PrependPath" + "PrependPath": "ms-resource:loc.messages.PrependPath", + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" }, "_buildConfigMapping": { - "Default": "1.234.0", - "Node20-225": "1.234.1" + "Default": "1.235.0", + "Node20-225": "1.235.1" } } \ No newline at end of file diff --git a/_generated/CondaEnvironmentV1_Node20/Strings/resources.resjson/en-US/resources.resjson b/_generated/CondaEnvironmentV1_Node20/Strings/resources.resjson/en-US/resources.resjson index 2352ea09a954..74ac7b229902 100644 --- a/_generated/CondaEnvironmentV1_Node20/Strings/resources.resjson/en-US/resources.resjson +++ b/_generated/CondaEnvironmentV1_Node20/Strings/resources.resjson/en-US/resources.resjson @@ -24,5 +24,6 @@ "loc.messages.ReactivateExistingEnvironment": "Found existing environment %s and the task's \"Clean environment\" parameter is not set. Reactivating ...", "loc.messages.ParameterRequired": "The `%s` parameter is required", "loc.messages.PlatformNotRecognized": "Platform not recognized", - "loc.messages.PrependPath": "Prepending PATH environment variable with directory: %s" + "loc.messages.PrependPath": "Prepending PATH environment variable with directory: %s", + "loc.messages.DeprecatedTask": "The CondaEnvironment@1 (Conda environment) task has been deprecated since February 13, 2019 and will soon be retired. Use the Conda CLI ('conda') directly from a bash/pwsh/script task." } \ No newline at end of file diff --git a/_generated/CondaEnvironmentV1_Node20/main.ts b/_generated/CondaEnvironmentV1_Node20/main.ts index aef867b1603c..d84435b32f2d 100644 --- a/_generated/CondaEnvironmentV1_Node20/main.ts +++ b/_generated/CondaEnvironmentV1_Node20/main.ts @@ -17,6 +17,11 @@ import { condaEnvironment } from './conda'; cleanEnvironment: task.getBoolInput('cleanEnvironment') }, getPlatform()); + let shouldFail = task.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + + if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(task.loc("DeprecatedTask")); + } task.setResult(task.TaskResult.Succeeded, ""); } catch (e) { error = e; diff --git a/_generated/CondaEnvironmentV1_Node20/task.json b/_generated/CondaEnvironmentV1_Node20/task.json index fbe487714822..942a8652c533 100644 --- a/_generated/CondaEnvironmentV1_Node20/task.json +++ b/_generated/CondaEnvironmentV1_Node20/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 1 }, "deprecated": true, @@ -105,10 +105,11 @@ "ReactivateExistingEnvironment": "Found existing environment %s and the task's \"Clean environment\" parameter is not set. Reactivating ...", "ParameterRequired": "The `%s` parameter is required", "PlatformNotRecognized": "Platform not recognized", - "PrependPath": "Prepending PATH environment variable with directory: %s" + "PrependPath": "Prepending PATH environment variable with directory: %s", + "DeprecatedTask": "The CondaEnvironment@1 (Conda environment) task has been deprecated since February 13, 2019 and will soon be retired. Use the Conda CLI ('conda') directly from a bash/pwsh/script task." }, "_buildConfigMapping": { - "Default": "1.234.0", - "Node20-225": "1.234.1" + "Default": "1.235.0", + "Node20-225": "1.235.1" } } \ No newline at end of file diff --git a/_generated/CondaEnvironmentV1_Node20/task.loc.json b/_generated/CondaEnvironmentV1_Node20/task.loc.json index 7d361eaa2842..3dea60551c5f 100644 --- a/_generated/CondaEnvironmentV1_Node20/task.loc.json +++ b/_generated/CondaEnvironmentV1_Node20/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 1 }, "deprecated": true, @@ -105,10 +105,11 @@ "ReactivateExistingEnvironment": "ms-resource:loc.messages.ReactivateExistingEnvironment", "ParameterRequired": "ms-resource:loc.messages.ParameterRequired", "PlatformNotRecognized": "ms-resource:loc.messages.PlatformNotRecognized", - "PrependPath": "ms-resource:loc.messages.PrependPath" + "PrependPath": "ms-resource:loc.messages.PrependPath", + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" }, "_buildConfigMapping": { - "Default": "1.234.0", - "Node20-225": "1.234.1" + "Default": "1.235.0", + "Node20-225": "1.235.1" } } \ No newline at end of file diff --git a/_generated/DotNetCoreInstallerV1.versionmap.txt b/_generated/DotNetCoreInstallerV1.versionmap.txt index e3500890f3b7..6f666948200c 100644 --- a/_generated/DotNetCoreInstallerV1.versionmap.txt +++ b/_generated/DotNetCoreInstallerV1.versionmap.txt @@ -1,2 +1,2 @@ -Default|1.234.0 -Node20_229_3|1.234.1 +Default|1.235.0 +Node20_229_3|1.235.1 diff --git a/_generated/DotNetCoreInstallerV1_Node20/Strings/resources.resjson/en-US/resources.resjson b/_generated/DotNetCoreInstallerV1_Node20/Strings/resources.resjson/en-US/resources.resjson index 706457fda6d3..25a049565f25 100644 --- a/_generated/DotNetCoreInstallerV1_Node20/Strings/resources.resjson/en-US/resources.resjson +++ b/_generated/DotNetCoreInstallerV1_Node20/Strings/resources.resjson/en-US/resources.resjson @@ -78,5 +78,6 @@ "loc.messages.FilesDataIsIncorrectInVersion": "In release %s for version %s, File data is incorrect (might have missing required fields, such as name, rid and url): %s", "loc.messages.VersionFilesDataIncorrect": "Version's files data is missing or has missing required fields.", "loc.messages.VersionInformationNotComplete": "Version: %s required information is not complete in releases.json file. Error: %s", - "loc.messages.FailedWhileExtractingPacakge": "Failed while extracting downloaded package with error: %s" + "loc.messages.FailedWhileExtractingPacakge": "Failed while extracting downloaded package with error: %s", + "loc.messages.DeprecatedTask": "The DotNetCoreInstaller@1 (.NET Core SDK/runtime installer) task has been deprecated since August 22, 2019 and will soon be retired. Use the UseDotNet@2 task instead." } \ No newline at end of file diff --git a/_generated/DotNetCoreInstallerV1_Node20/dotnetcoreinstaller.ts b/_generated/DotNetCoreInstallerV1_Node20/dotnetcoreinstaller.ts index b3989d54e119..8bee770098ed 100644 --- a/_generated/DotNetCoreInstallerV1_Node20/dotnetcoreinstaller.ts +++ b/_generated/DotNetCoreInstallerV1_Node20/dotnetcoreinstaller.ts @@ -41,6 +41,12 @@ async function run() { // Set DOTNET_ROOT for dotnet core Apphost to find runtime since it is installed to a non well-known location. tl.setVariable('DOTNET_ROOT', installationPath); + + let shouldFail = tl.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + + if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(tl.loc("DeprecatedTask")); + } } function addDotNetCoreToolPath() { diff --git a/_generated/DotNetCoreInstallerV1_Node20/task.json b/_generated/DotNetCoreInstallerV1_Node20/task.json index 59313f846bb5..333102c00f70 100644 --- a/_generated/DotNetCoreInstallerV1_Node20/task.json +++ b/_generated/DotNetCoreInstallerV1_Node20/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 1 }, "deprecated": true, @@ -157,10 +157,11 @@ "FilesDataIsIncorrectInVersion": "In release %s for version %s, File data is incorrect (might have missing required fields, such as name, rid and url): %s", "VersionFilesDataIncorrect": "Version's files data is missing or has missing required fields.", "VersionInformationNotComplete": "Version: %s required information is not complete in releases.json file. Error: %s", - "FailedWhileExtractingPacakge": "Failed while extracting downloaded package with error: %s" + "FailedWhileExtractingPacakge": "Failed while extracting downloaded package with error: %s", + "DeprecatedTask": "The DotNetCoreInstaller@1 (.NET Core SDK/runtime installer) task has been deprecated since August 22, 2019 and will soon be retired. Use the UseDotNet@2 task instead." }, "_buildConfigMapping": { - "Default": "1.234.0", - "Node20_229_3": "1.234.1" + "Default": "1.235.0", + "Node20_229_3": "1.235.1" } } \ No newline at end of file diff --git a/_generated/DotNetCoreInstallerV1_Node20/task.loc.json b/_generated/DotNetCoreInstallerV1_Node20/task.loc.json index 7fd2fffa6a87..b370b92b7d74 100644 --- a/_generated/DotNetCoreInstallerV1_Node20/task.loc.json +++ b/_generated/DotNetCoreInstallerV1_Node20/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, + "Minor": 235, "Patch": 1 }, "deprecated": true, @@ -157,10 +157,11 @@ "FilesDataIsIncorrectInVersion": "ms-resource:loc.messages.FilesDataIsIncorrectInVersion", "VersionFilesDataIncorrect": "ms-resource:loc.messages.VersionFilesDataIncorrect", "VersionInformationNotComplete": "ms-resource:loc.messages.VersionInformationNotComplete", - "FailedWhileExtractingPacakge": "ms-resource:loc.messages.FailedWhileExtractingPacakge" + "FailedWhileExtractingPacakge": "ms-resource:loc.messages.FailedWhileExtractingPacakge", + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" }, "_buildConfigMapping": { - "Default": "1.234.0", - "Node20_229_3": "1.234.1" + "Default": "1.235.0", + "Node20_229_3": "1.235.1" } } \ No newline at end of file diff --git a/_generated/DownloadPackageV0.versionmap.txt b/_generated/DownloadPackageV0.versionmap.txt index 110a5080e78f..b974e5158e6e 100644 --- a/_generated/DownloadPackageV0.versionmap.txt +++ b/_generated/DownloadPackageV0.versionmap.txt @@ -1,2 +1,2 @@ -Default|0.233.0 -Node20_229_1|0.233.1 +Default|0.234.0 +Node20_229_1|0.234.1 diff --git a/_generated/DownloadPackageV0/download.ts b/_generated/DownloadPackageV0/download.ts index 238495e54688..76f2dfb0dc87 100644 --- a/_generated/DownloadPackageV0/download.ts +++ b/_generated/DownloadPackageV0/download.ts @@ -234,5 +234,5 @@ export async function unzip(zipLocation: string, unzipLocation: string): Promise } main() - .then(() => tl.setResult(tl.TaskResult.Succeeded, "")) + .then(() => tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("DeprecatedTask"))) .catch((error) => tl.setResult(tl.TaskResult.Failed, error)); diff --git a/_generated/DownloadPackageV0/task.json b/_generated/DownloadPackageV0/task.json index 14921dfdaf81..ceede813fd84 100644 --- a/_generated/DownloadPackageV0/task.json +++ b/_generated/DownloadPackageV0/task.json @@ -9,7 +9,7 @@ "author": "ms-vscs-rm", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 0 }, "demands": [], @@ -116,7 +116,7 @@ "DeprecatedTask": "This task is deprecated. Please switch to using DownloadPackage@1 https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/download-package-v1" }, "_buildConfigMapping": { - "Default": "0.233.0", - "Node20_229_1": "0.233.1" + "Default": "0.234.0", + "Node20_229_1": "0.234.1" } } \ No newline at end of file diff --git a/_generated/DownloadPackageV0/task.loc.json b/_generated/DownloadPackageV0/task.loc.json index 2f4de5c033ab..ed5c1e9369a6 100644 --- a/_generated/DownloadPackageV0/task.loc.json +++ b/_generated/DownloadPackageV0/task.loc.json @@ -9,7 +9,7 @@ "author": "ms-vscs-rm", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 0 }, "demands": [], @@ -116,7 +116,7 @@ "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" }, "_buildConfigMapping": { - "Default": "0.233.0", - "Node20_229_1": "0.233.1" + "Default": "0.234.0", + "Node20_229_1": "0.234.1" } } \ No newline at end of file diff --git a/_generated/DownloadPackageV0_Node20/download.ts b/_generated/DownloadPackageV0_Node20/download.ts index 3d3d941c2ad1..b9c01c6510eb 100644 --- a/_generated/DownloadPackageV0_Node20/download.ts +++ b/_generated/DownloadPackageV0_Node20/download.ts @@ -234,5 +234,5 @@ export async function unzip(zipLocation: string, unzipLocation: string): Promise } main() - .then(() => tl.setResult(tl.TaskResult.Succeeded, "")) + .then(() => tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("DeprecatedTask"))) .catch((error) => tl.setResult(tl.TaskResult.Failed, error)); diff --git a/_generated/DownloadPackageV0_Node20/task.json b/_generated/DownloadPackageV0_Node20/task.json index db91f0beae96..00041fba46ed 100644 --- a/_generated/DownloadPackageV0_Node20/task.json +++ b/_generated/DownloadPackageV0_Node20/task.json @@ -9,7 +9,7 @@ "author": "ms-vscs-rm", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 1 }, "demands": [], @@ -120,7 +120,7 @@ "DeprecatedTask": "This task is deprecated. Please switch to using DownloadPackage@1 https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/download-package-v1" }, "_buildConfigMapping": { - "Default": "0.233.0", - "Node20_229_1": "0.233.1" + "Default": "0.234.0", + "Node20_229_1": "0.234.1" } } \ No newline at end of file diff --git a/_generated/DownloadPackageV0_Node20/task.loc.json b/_generated/DownloadPackageV0_Node20/task.loc.json index c0df9d27ecdc..d30d45037dcd 100644 --- a/_generated/DownloadPackageV0_Node20/task.loc.json +++ b/_generated/DownloadPackageV0_Node20/task.loc.json @@ -9,7 +9,7 @@ "author": "ms-vscs-rm", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 1 }, "demands": [], @@ -120,7 +120,7 @@ "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" }, "_buildConfigMapping": { - "Default": "0.233.0", - "Node20_229_1": "0.233.1" + "Default": "0.234.0", + "Node20_229_1": "0.234.1" } } \ No newline at end of file diff --git a/_generated/NuGetInstallerV0.versionmap.txt b/_generated/NuGetInstallerV0.versionmap.txt index 110a5080e78f..b974e5158e6e 100644 --- a/_generated/NuGetInstallerV0.versionmap.txt +++ b/_generated/NuGetInstallerV0.versionmap.txt @@ -1,2 +1,2 @@ -Default|0.233.0 -Node20_229_1|0.233.1 +Default|0.234.0 +Node20_229_1|0.234.1 diff --git a/_generated/NuGetInstallerV0/nugetinstaller.ts b/_generated/NuGetInstallerV0/nugetinstaller.ts index 962fdb205b97..48e0d8898831 100644 --- a/_generated/NuGetInstallerV0/nugetinstaller.ts +++ b/_generated/NuGetInstallerV0/nugetinstaller.ts @@ -194,7 +194,7 @@ async function main(): Promise { throw new Error(tl.loc("DeprecatedTask")); } - tl.setResult(tl.TaskResult.Succeeded, tl.loc("PackagesInstalledSuccessfully")); + tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("DeprecatedTask")); } catch (err) { tl.error(err); diff --git a/_generated/NuGetInstallerV0/task.json b/_generated/NuGetInstallerV0/task.json index 7275064e8ff3..ababca844af9 100644 --- a/_generated/NuGetInstallerV0/task.json +++ b/_generated/NuGetInstallerV0/task.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 0 }, "runsOn": [ @@ -149,7 +149,7 @@ "DeprecatedTask": "This task is deprecated. Please switch to using NuGetCommand@2's 'restore' or 'custom' option https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/nuget-command-v2" }, "_buildConfigMapping": { - "Default": "0.233.0", - "Node20_229_1": "0.233.1" + "Default": "0.234.0", + "Node20_229_1": "0.234.1" } } \ No newline at end of file diff --git a/_generated/NuGetInstallerV0/task.loc.json b/_generated/NuGetInstallerV0/task.loc.json index 30b3b8dc096c..91cffc45df60 100644 --- a/_generated/NuGetInstallerV0/task.loc.json +++ b/_generated/NuGetInstallerV0/task.loc.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 0 }, "runsOn": [ @@ -149,7 +149,7 @@ "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" }, "_buildConfigMapping": { - "Default": "0.233.0", - "Node20_229_1": "0.233.1" + "Default": "0.234.0", + "Node20_229_1": "0.234.1" } } \ No newline at end of file diff --git a/_generated/NuGetInstallerV0_Node20/nugetinstaller.ts b/_generated/NuGetInstallerV0_Node20/nugetinstaller.ts index 962fdb205b97..48e0d8898831 100644 --- a/_generated/NuGetInstallerV0_Node20/nugetinstaller.ts +++ b/_generated/NuGetInstallerV0_Node20/nugetinstaller.ts @@ -194,7 +194,7 @@ async function main(): Promise { throw new Error(tl.loc("DeprecatedTask")); } - tl.setResult(tl.TaskResult.Succeeded, tl.loc("PackagesInstalledSuccessfully")); + tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("DeprecatedTask")); } catch (err) { tl.error(err); diff --git a/_generated/NuGetInstallerV0_Node20/task.json b/_generated/NuGetInstallerV0_Node20/task.json index 48d09415316e..bffed1cb6bdf 100644 --- a/_generated/NuGetInstallerV0_Node20/task.json +++ b/_generated/NuGetInstallerV0_Node20/task.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 1 }, "runsOn": [ @@ -153,7 +153,7 @@ "DeprecatedTask": "This task is deprecated. Please switch to using NuGetCommand@2's 'restore' or 'custom' option https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/nuget-command-v2" }, "_buildConfigMapping": { - "Default": "0.233.0", - "Node20_229_1": "0.233.1" + "Default": "0.234.0", + "Node20_229_1": "0.234.1" } } \ No newline at end of file diff --git a/_generated/NuGetInstallerV0_Node20/task.loc.json b/_generated/NuGetInstallerV0_Node20/task.loc.json index c8d1c062bca1..d61f87d11101 100644 --- a/_generated/NuGetInstallerV0_Node20/task.loc.json +++ b/_generated/NuGetInstallerV0_Node20/task.loc.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 0, - "Minor": 233, + "Minor": 234, "Patch": 1 }, "runsOn": [ @@ -153,7 +153,7 @@ "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" }, "_buildConfigMapping": { - "Default": "0.233.0", - "Node20_229_1": "0.233.1" + "Default": "0.234.0", + "Node20_229_1": "0.234.1" } } \ No newline at end of file diff --git a/_generated/NuGetRestoreV1/nugetinstaller.ts b/_generated/NuGetRestoreV1/nugetinstaller.ts index 11d345e6159f..0526cddcd298 100644 --- a/_generated/NuGetRestoreV1/nugetinstaller.ts +++ b/_generated/NuGetRestoreV1/nugetinstaller.ts @@ -240,7 +240,7 @@ async function main(): Promise { isNugetOrgBehaviorWarn ? tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("Warning_IncludeNuGetOrgEnabled")) - : tl.setResult(tl.TaskResult.Succeeded, tl.loc("PackagesInstalledSuccessfully")); + : tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("DeprecatedTask")); } catch (err) { diff --git a/_generated/NuGetRestoreV1/task.json b/_generated/NuGetRestoreV1/task.json index 7af8cd599fbb..3a572a19934c 100644 --- a/_generated/NuGetRestoreV1/task.json +++ b/_generated/NuGetRestoreV1/task.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "runsOn": [ @@ -169,9 +169,5 @@ "Warning_IncludeNuGetOrgEnabled": "IncludeNugetOrg is currently enabled for this task. To resolve this warning, edit your build task and set 'includeNuGetOrg' to 'false' or deselect 'Use packages from NuGet.org'.", "Error_IncludeNuGetOrgEnabled": "Packages failed to restore. Edit your build task and set 'includeNuGetOrg' to 'false' or deselect 'Use packages from NuGet.org'.", "DeprecatedTask": "This task is deprecated. Please switch to using NuGetCommand@2's 'restore' option https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/nuget-command-v2" - }, - "_buildConfigMapping": { - "Default": "1.232.0", - "Node20_229_1": "1.232.1" } } \ No newline at end of file diff --git a/_generated/NuGetRestoreV1/task.loc.json b/_generated/NuGetRestoreV1/task.loc.json index ca31f8b15a22..7501d6e5b95b 100644 --- a/_generated/NuGetRestoreV1/task.loc.json +++ b/_generated/NuGetRestoreV1/task.loc.json @@ -9,7 +9,7 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "runsOn": [ @@ -169,9 +169,5 @@ "Warning_IncludeNuGetOrgEnabled": "ms-resource:loc.messages.Warning_IncludeNuGetOrgEnabled", "Error_IncludeNuGetOrgEnabled": "ms-resource:loc.messages.Error_IncludeNuGetOrgEnabled", "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" - }, - "_buildConfigMapping": { - "Default": "1.232.0", - "Node20_229_1": "1.232.1" } } \ No newline at end of file diff --git a/_generated/NuGetRestoreV1_Node20/nugetinstaller.ts b/_generated/NuGetRestoreV1_Node20/nugetinstaller.ts index 11d345e6159f..0526cddcd298 100644 --- a/_generated/NuGetRestoreV1_Node20/nugetinstaller.ts +++ b/_generated/NuGetRestoreV1_Node20/nugetinstaller.ts @@ -240,7 +240,7 @@ async function main(): Promise { isNugetOrgBehaviorWarn ? tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("Warning_IncludeNuGetOrgEnabled")) - : tl.setResult(tl.TaskResult.Succeeded, tl.loc("PackagesInstalledSuccessfully")); + : tl.setResult(tl.TaskResult.SucceededWithIssues, tl.loc("DeprecatedTask")); } catch (err) { diff --git a/_generated/NuGetRestoreV1_Node20/task.json b/_generated/NuGetRestoreV1_Node20/task.json index 6b792820785e..3a572a19934c 100644 --- a/_generated/NuGetRestoreV1_Node20/task.json +++ b/_generated/NuGetRestoreV1_Node20/task.json @@ -9,8 +9,8 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 232, - "Patch": 1 + "Minor": 234, + "Patch": 0 }, "runsOn": [ "Agent", @@ -129,10 +129,6 @@ "Node16": { "target": "nugetinstaller.js", "argumentFormat": "" - }, - "Node20_1": { - "target": "nugetinstaller.js", - "argumentFormat": "" } }, "messages": { @@ -173,9 +169,5 @@ "Warning_IncludeNuGetOrgEnabled": "IncludeNugetOrg is currently enabled for this task. To resolve this warning, edit your build task and set 'includeNuGetOrg' to 'false' or deselect 'Use packages from NuGet.org'.", "Error_IncludeNuGetOrgEnabled": "Packages failed to restore. Edit your build task and set 'includeNuGetOrg' to 'false' or deselect 'Use packages from NuGet.org'.", "DeprecatedTask": "This task is deprecated. Please switch to using NuGetCommand@2's 'restore' option https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/nuget-command-v2" - }, - "_buildConfigMapping": { - "Default": "1.232.0", - "Node20_229_1": "1.232.1" } } \ No newline at end of file diff --git a/_generated/NuGetRestoreV1_Node20/task.loc.json b/_generated/NuGetRestoreV1_Node20/task.loc.json index 2130205fb3c3..7501d6e5b95b 100644 --- a/_generated/NuGetRestoreV1_Node20/task.loc.json +++ b/_generated/NuGetRestoreV1_Node20/task.loc.json @@ -9,8 +9,8 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 232, - "Patch": 1 + "Minor": 234, + "Patch": 0 }, "runsOn": [ "Agent", @@ -129,10 +129,6 @@ "Node16": { "target": "nugetinstaller.js", "argumentFormat": "" - }, - "Node20_1": { - "target": "nugetinstaller.js", - "argumentFormat": "" } }, "messages": { @@ -173,9 +169,5 @@ "Warning_IncludeNuGetOrgEnabled": "ms-resource:loc.messages.Warning_IncludeNuGetOrgEnabled", "Error_IncludeNuGetOrgEnabled": "ms-resource:loc.messages.Error_IncludeNuGetOrgEnabled", "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" - }, - "_buildConfigMapping": { - "Default": "1.232.0", - "Node20_229_1": "1.232.1" } } \ No newline at end of file diff --git a/_generated/UseDotNetV2.versionmap.txt b/_generated/UseDotNetV2.versionmap.txt index dfe21278a68a..bf4b899dc238 100644 --- a/_generated/UseDotNetV2.versionmap.txt +++ b/_generated/UseDotNetV2.versionmap.txt @@ -1,2 +1,2 @@ -Default|2.232.0 -Node20_229_3|2.232.1 +Default|2.234.0 +Node20_229_3|2.234.1 diff --git a/_generated/UseDotNetV2/externals/get-os-distro.sh b/_generated/UseDotNetV2/externals/get-os-distro.sh index 689da6d682cb..73000e7b5f10 100644 --- a/_generated/UseDotNetV2/externals/get-os-distro.sh +++ b/_generated/UseDotNetV2/externals/get-os-distro.sh @@ -159,6 +159,7 @@ get_legacy_os_name() { get_machine_architecture() { if command -v uname > /dev/null; then + local osn=$(get_current_os_name || echo "") CPUName=$(uname -m) case $CPUName in armv7l) @@ -169,6 +170,20 @@ get_machine_architecture() { echo "arm64" return 0 ;; + arm64) + echo "arm64" + return 0 + ;; + x86_64) + if [ "$osn" = "osx" ]; then + if [ "$(sysctl -in sysctl.proc_translated)" = "1" ]; then + echo "arm64" + else + echo "x64" + fi + return 0 + fi + ;; esac fi diff --git a/_generated/UseDotNetV2/task.json b/_generated/UseDotNetV2/task.json index b62e8b384530..3109a4a58eee 100644 --- a/_generated/UseDotNetV2/task.json +++ b/_generated/UseDotNetV2/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "satisfies": [ @@ -195,7 +195,7 @@ "DepricatedVersionNetCore": "NET Core version you specfied %s is out of support and will be removed from hosted agents soon. Please refer to https://aka.ms/dotnet-core-support for more information about the .NET support policy." }, "_buildConfigMapping": { - "Default": "2.232.0", - "Node20_229_3": "2.232.1" + "Default": "2.234.0", + "Node20_229_3": "2.234.1" } } \ No newline at end of file diff --git a/_generated/UseDotNetV2/task.loc.json b/_generated/UseDotNetV2/task.loc.json index a5fc62a47482..572f6439dfef 100644 --- a/_generated/UseDotNetV2/task.loc.json +++ b/_generated/UseDotNetV2/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 232, + "Minor": 234, "Patch": 0 }, "satisfies": [ @@ -195,7 +195,7 @@ "DepricatedVersionNetCore": "ms-resource:loc.messages.DepricatedVersionNetCore" }, "_buildConfigMapping": { - "Default": "2.232.0", - "Node20_229_3": "2.232.1" + "Default": "2.234.0", + "Node20_229_3": "2.234.1" } } \ No newline at end of file diff --git a/_generated/UseDotNetV2_Node20/externals/get-os-distro.sh b/_generated/UseDotNetV2_Node20/externals/get-os-distro.sh index 689da6d682cb..73000e7b5f10 100644 --- a/_generated/UseDotNetV2_Node20/externals/get-os-distro.sh +++ b/_generated/UseDotNetV2_Node20/externals/get-os-distro.sh @@ -159,6 +159,7 @@ get_legacy_os_name() { get_machine_architecture() { if command -v uname > /dev/null; then + local osn=$(get_current_os_name || echo "") CPUName=$(uname -m) case $CPUName in armv7l) @@ -169,6 +170,20 @@ get_machine_architecture() { echo "arm64" return 0 ;; + arm64) + echo "arm64" + return 0 + ;; + x86_64) + if [ "$osn" = "osx" ]; then + if [ "$(sysctl -in sysctl.proc_translated)" = "1" ]; then + echo "arm64" + else + echo "x64" + fi + return 0 + fi + ;; esac fi diff --git a/_generated/UseDotNetV2_Node20/task.json b/_generated/UseDotNetV2_Node20/task.json index 6f3762ee18c0..6339eb204ee5 100644 --- a/_generated/UseDotNetV2_Node20/task.json +++ b/_generated/UseDotNetV2_Node20/task.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 232, + "Minor": 234, "Patch": 1 }, "satisfies": [ @@ -199,7 +199,7 @@ "DepricatedVersionNetCore": "NET Core version you specfied %s is out of support and will be removed from hosted agents soon. Please refer to https://aka.ms/dotnet-core-support for more information about the .NET support policy." }, "_buildConfigMapping": { - "Default": "2.232.0", - "Node20_229_3": "2.232.1" + "Default": "2.234.0", + "Node20_229_3": "2.234.1" } } \ No newline at end of file diff --git a/_generated/UseDotNetV2_Node20/task.loc.json b/_generated/UseDotNetV2_Node20/task.loc.json index ff14c2a2911e..f0ea36b27e3e 100644 --- a/_generated/UseDotNetV2_Node20/task.loc.json +++ b/_generated/UseDotNetV2_Node20/task.loc.json @@ -13,7 +13,7 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 232, + "Minor": 234, "Patch": 1 }, "satisfies": [ @@ -199,7 +199,7 @@ "DepricatedVersionNetCore": "ms-resource:loc.messages.DepricatedVersionNetCore" }, "_buildConfigMapping": { - "Default": "2.232.0", - "Node20_229_3": "2.232.1" + "Default": "2.234.0", + "Node20_229_3": "2.234.1" } } \ No newline at end of file diff --git a/_generated/VsTestV2.versionmap.txt b/_generated/VsTestV2.versionmap.txt index f93f88cc73d8..e2aa7939be81 100644 --- a/_generated/VsTestV2.versionmap.txt +++ b/_generated/VsTestV2.versionmap.txt @@ -1,2 +1,2 @@ -Default|2.229.0 -Node20_229_4|2.231.0 +Default|2.234.0 +Node20_229_4|2.234.1 diff --git a/_generated/VsTestV2/README.md b/_generated/VsTestV2/README.md new file mode 100644 index 000000000000..a696d2048c31 --- /dev/null +++ b/_generated/VsTestV2/README.md @@ -0,0 +1,113 @@ +# Run Tests using Visual Studio task + +### Overview + +VSTest task can be used to run tests on Build agent machines. Apart from MSTest based tests, you can also run tests written using test frameworks like NUnit, xUnit, Mocha, Jasmine, etc. using the appropriate test adapters to Visual Studio. The task uses vstest.console.exe to execute tests and the command-line options available are documented [here](https://msdn.microsoft.com/en-us/library/jj155796.aspx) + +#### Execution Options + +Use the following options to select tests and control how the tests are run + +- **Test Assembly:** This is a required field. Use this to specify one or more test file names from which the tests should be picked. + * Paths are relative to the 'Search Folder' input. + * Multiple paths can be specified, one on each line. + * Uses the minimatch patterns. Learn more about minimatch [here](https://aka.ms/minimatchexamples) + + Example 1: + Most commonly your test projects follow a naming pattern such as `Product.Tests.dll`, `ProductTests.dll`, `Product.Test.dll`, `Product.UnitTests.dll` or similar. These dlls reside in your `bin` directory. To include all such test dlls use this pattern: + + ``` + **\bin\**\*test.dll + **\bin\**\*tests.dll + ``` + + Example 2: + When it is impossible to determine a naming convention for the tested dlls a wide include pattern can be used (notice the * before .dll). Such pattern can be followed by exclude patterns (starting with `!`) that excludes additional dlls. + This pattern includes all dlls that have `test` in their name, and excludes all dlls from intermediate build `obj` directory: + + ``` + **\*test*.dll + !**\obj\** + ``` + + This pattern is likely to include more dlls than you expect as many other dll names include *test* in their name, such as `MSTest.TestFramework.dll`, `Microsoft.VisualStudio.TestPlatform.ObjectModel.dll` etc. Please review your test log to see which dlls are included, and add appropriate excludes, such as: + + ``` + **\*test*.dll + !**\obj\** + !**\*.resources.dll + !**\*TestAdapter.dll + !**\*Microsoft.*TestPlatform*.dll + !**\*testhost*.dll + !**\testcentric.engine.metadata.dll + ``` + + +- **Search Folder:** Use this to specify the folder to search for the test files. Defaults to `$(System.DefaultWorkingDirectory)` + +- **Test Filter Criteria:** Filters tests from within the test assembly files. For example, “Priority=1 | Name=MyTestMethod”. This option works the same way as the console option /TestCaseFilter of vstest.console.exe + +- **Run Settings File:** Path to a runsettings or testsettings file can be specified here. The path can be to a file in the repository or a path to file on disk. Use $(Build.SourcesDirectory) to access the root project folder. [Click here](https://msdn.microsoft.com/library/jj635153.aspx) for more information on these files. + +- **Override TestRun Parameters:** Override parameters defined in the TestRunParameters section of the runsettings file. For example: Platform=$(platform);Port=8080 +[Click here](https://blogs.msdn.com/b/visualstudioalm/archive/2015/09/04/supplying-run-time-parameters-to-tests.aspx) for more information on overriding parameters. + +- **Code Coverage Enabled:** If set, this will collect code coverage information during the run and upload the results to the server. This is supported for .Net and C++ projects only. [Click here](https://msdn.microsoft.com/library/jj159530.aspx) to learn more about how to customize code coverage and manage inclusions and exclusions. + +- **Run in Parallel:** If set, tests will run in parallel leveraging available cores of the machine. [Click here](https://aka.ms/paralleltestexecution) to learn more about how tests are run in parallel. + +- **VSTest version:** Choose which version of Visual Studio (vstest.console.exe) to run tests with. + +- **Path to Custom Test Adapters:** Path to the testadapter for the framework in which the specified tests are written. Provided directory and all subdirectories are checked for testadapters. If there is a packages folder in the sources directory, it is automatically searched for testadapters. As a result, any testadapter downloaded as a Nuget package will be used without any input. For example, ‘$(Build.SourcesDirectory)\Fabrikam\packages’ + +- **Other console options:** Other options that can be provided to vstest.console.exe. For example, if you are using VSIX extensions, you can provide “/UseVsixExtensions:true”. These options are not supported and will be ignored when running tests using the ‘Multi agent’ parallel setting of an agent job or when running tests using ‘Test plan’ or 'Test run' option or when a custom batching option is selected. In these cases, the options can be specified using a runsettings file instead. + +#### Test Impact Analysis + +- **Run Only Impacted Tests:** If set, then only the relevant set of managed automated tests that need to be run to validate a given code change will be run. + +- **Number Of Builds After Which To Run All Tests:** This is an override that can be used to set the periodicity at which to automatically run the complete automated test suite. + +The Test Impact Analysis feature is available through the v2.\* (preview) version of the task. + +The feature is presently scoped to the following: +- Dependencies + - **Requires use of the v2.\* (preview) of the VSTest task in the build definition.** + - **Requires VS 2015 Update 3 or VS 2017 RC and above on the build agent** +- Supported + - Managed code + - CI and in PR workflows + - IIS interactions + - Automated Tests (unit tests, functional tests) - the tests and the application must be running on the same machine. + - Build vNext, with multiple Test Tasks + - Local and Hosted build agents (you will need VS 2015 Update 3 or VS2017 RC and above – please see “Dependencies”) + - Git, GitHub, External Git, TFVC repos +- Not yet supported + - Remote testing (where the test is exercising an app deployed to a different machine) + - No xplat support (Windows only). + - No UWP support. + + Learn more about Test Impact [here](https://aka.ms/tialearnmore) + + +#### Advanced Execution Options + +- **Batch tests:** A batch is a group of tests. A batch of tests runs at a time and results are published for that batch. If the phase in which the task runs is set to use multiple agents, each agent picks up any available batches of tests to run in parallel. Choose one of the below mentioned options for batching. + - **Based on number of tests and agents:** Simple batching based on the number of tests and agents participating in the test run. + - **Based on past running time of tests:** This batching considers past running time to create batches of tests such that each batch has approximately equal running time. + - **Based on test assemblies:** Tests from an assembly are batched together. + + Learn more about batching options [here](https://aka.ms/vstestbatchingoptions) + +- **Do not distribute tests and replicate instead when multiple agents are used in the phase:** Choosing this option will not distribute tests across agents when the task is running in a multi-agent phase. Each of the selected test(s) will be repeated on each agent. The option is not applicable when the agent phase is configured to run with no parallelism or with the multi-config option. + +#### Reporting Options +Use the following options to report desired information for the test run that can be used when analyzing runs. + +- **Test Run Title:** Provide a name for the test run. + +- **Platform:** Build platform against which the test run should be reported. This field is used for reporting purposes only. If you are using the Build – Visual Studio template, this is already defined for you. For example, x64 or x86. If you have defined a variable for platform in your build task, use that here. + +- **Configuration:** Build configuration against which the Test Run should be reported. Field is used for reporting purposes only. If you are using the Build – Visual Studio template, this is already defined for you. For example, Debug or Release. If you have defined a variable for configuration in your build task, use that here. + +- **Upload test attachments:** If set, any test run level attachments such as the TRX file will be uploaded. diff --git a/_generated/VsTestV2/Strings/resources.resjson/de-DE/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/de-DE/resources.resjson new file mode 100644 index 000000000000..845507c8d95e --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/de-DE/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Visual Studio Test", + "loc.helpMarkDown": "[Weitere Informationen zu dieser Aufgabe](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "Führen Sie mit dem Visual Studio Test-Runner (VSTest) Komponenten- und Funktionstests aus (Selenium, Appium, Test der programmierten UI usw.). Testframeworks mit Visual Studio Test-Adapter, wie z. B. MsTest, xUnit, NUnit, Chutzpah (für JavaScript-Tests unter Verwendung von QUnit, Mocha und Jasmine) usw. können ausgeführt werden. Tests können mit dieser Aufgabe (Version 2) auf verschiedene Agents verteilt werden.", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
          • Führen Sie Tests mit einem Agent-Auftrag aus: Einheitliche Agents in Build, Release und Test ermöglichen die Verwendung von Automation-Agents auch für das Testen. Mithilfe der Multi-Agent-Auftragseinstellung können Sie Tests verteilen. Die Auftragseinstellung für mehrere Konfigurationen kann verwendet werden, um Tests in unterschiedlichen Konfigurationen zu replizieren. Weitere Informationen
          • Analyse der Testwirkung: Es werden automatisch nur die Tests ausgewählt und ausgeführt, die zum Validieren der Codeänderung benötigt werden.
          • Verwenden Sie die Aufgabe Installer für Visual Studio Test-Plattform, um Tests auszuführen, ohne eine vollständige Visual Studio-Installation zu benötigen.
          ", + "loc.group.displayName.testSelection": "Testauswahl", + "loc.group.displayName.executionOptions": "Ausführungsoptionen", + "loc.group.displayName.advancedExecutionOptions": "Erweiterte Ausführungsoptionen", + "loc.group.displayName.reportingOptions": "Berichtoptionen", + "loc.input.label.testSelector": "Tests auswählen mithilfe von", + "loc.input.help.testSelector": "
          • Testassembly: Verwenden Sie diese Option, um Testassemblys festzulegen, die Ihre Tests enthalten. Optional können Sie Filterkriterien festlegen, um nur spezifische Tests auszuwählen.
          • Testplan: Verwenden Sie diese Option, um Tests aus Ihrem Testplan auszuführen, denen eine automatisierte Testmethode zugeordnet ist.
          • Testlauf: Verwenden Sie diese Option, wenn Sie eine Umgebung einrichten, um Tests aus dem Testhub auszuführen. Diese Option darf beim Ausführen von Tests in einer CI/CD-Pipeline (Continuous Integration/Continuous Deployment) nicht verwendet werden.
          • ", + "loc.input.label.testAssemblyVer2": "Testdateien", + "loc.input.help.testAssemblyVer2": "Hiermit werden Tests anhand der angegebenen Dateien ausgeführt.
            Testreihen und Webtests können ausgeführt werden, indem .orderedtest- und .webtest-Dateien angegeben werden. Zum Ausführen von .webtest-Dateien wird Visual Studio 2017 Update 4 oder höher benötigt.

            Die Dateipfade sind relativ zum Suchordner angegeben. Es werden mehrzeilige Minimatch-Muster unterstützt. [Weitere Informationen](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "Testplan", + "loc.input.help.testPlan": "Wählen Sie einen Testplan aus, der Testsuiten mit automatisierten Testfällen enthält.", + "loc.input.label.testSuite": "Testsammlung", + "loc.input.help.testSuite": "Wählen Sie mindestens eine Testsuite aus, die automatisierte Testfälle enthält. Arbeitsaufgaben von Testfällen müssen einer automatisierten Testmethode zugeordnet sein. [Weitere Informationen](https://go.microsoft.com/fwlink/?linkid=847773)", + "loc.input.label.testConfiguration": "Testkonfiguration", + "loc.input.help.testConfiguration": "Wählen Sie die Testkonfiguration aus.", + "loc.input.label.tcmTestRun": "Testlauf", + "loc.input.help.tcmTestRun": "Die testlaufbasierte Auswahl wird verwendet, wenn automatisierte Testläufe vom Testhub ausgelöst werden. Diese Option kann nicht zum Ausführen von Tests in der CI/CD-Pipeline verwendet werden.", + "loc.input.label.searchFolder": "Suchordner", + "loc.input.help.searchFolder": "Ordner für die Suche nach den Testassemblys.", + "loc.input.label.resultsFolder": "Ordner mit Testergebnissen", + "loc.input.help.resultsFolder": "Ordner zum Speichern der Testergebnisse. Erfolgt keine Eingabe, werden die Ergebnisse standardmäßig in \"$(Agent.TempDirectory)/TestResults\" gespeichert und am Ende einer Pipelineausführung bereinigt. Das Verzeichnis für die Ergebnisse wird immer zu Beginn der vstest-Aufgabe bereinigt, bevor die Tests ausgeführt werden. Der relative Ordnerpfad wird (sofern angegeben) als relativ zu \"$(Agent.TempDirectory)\" betrachtet.", + "loc.input.label.testFiltercriteria": "Testfilterkriterien", + "loc.input.help.testFiltercriteria": "Zusätzliche Kriterien zum Filtern von Tests aus Testassemblys. Beispiel: \"Priority=1|Name=MyTestMethod\". [Weitere Informationen](https://msdn.microsoft.com/de-de/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "Nur betroffene Tests ausführen", + "loc.input.help.runOnlyImpactedTests": "Wählen Sie automatisch nur die Tests aus, die Sie zum Validieren der Codeänderung benötigen, und führen Sie diese aus. [Weitere Informationen](https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "Anzahl von Builds, nach der alle Tests ausgeführt werden sollen", + "loc.input.help.runAllTestsAfterXBuilds": "Anzahl von Builds, nach der alle Tests automatisch ausgeführt werden sollen. Bei einer Testwirkungsanalyse wird die Zuordnung zwischen Testfällen und Quellcode gespeichert. Es wird empfohlen, die Zuordnung erneut zu generieren, indem in regelmäßigen Abständen alle Tests ausgeführt werden.", + "loc.input.label.uiTests": "Die Testmischung enthält UI-Tests.", + "loc.input.help.uiTests": "Um UI-Tests durchzuführen, müssen Sie sicherstellen, dass der Agent zur Ausführung im interaktiven Modus festgelegt ist. Die Einrichtung eines Agents zur Ausführung im interaktiven Modus muss erfolgen, bevor der Build/das Release in die Warteschlange eingereiht wird. Wenn Sie dieses Kontrollkästchen aktivieren, wird der Agent nicht automatisch zur Ausführung im interaktiven Modus konfiguriert. Diese Option in der Aufgabe dient nur als Erinnerung, den Agent zur Vermeidung von Fehlern ordnungsgemäß zu konfigurieren.

            Gehostete Windows-Agents aus VS 2015- und VS 2017-Pools können zum Ausführen von UI-Tests verwendet werden.
            [Weitere Informationen](https://aka.ms/uitestmoreinfo).", + "loc.input.label.vstestLocationMethod": "Testplattform auswählen mithilfe von", + "loc.input.label.vsTestVersion": "Version der Testplattform", + "loc.input.help.vsTestVersion": "Die zu verwendende Testversion von Visual Studio. Wenn \"Neueste\" angegeben ist, wird die neueste Visual Studio Version ab VS2022 gefolgt von VS2019, VS2017 und VS2015 ausgewählt, je nachdem, was installiert ist. Visual Studio 2013 wird nicht unterstützt. Um Tests auszuführen, ohne Visual Studio auf dem Agent zu benötigen, verwenden Sie die Option \"Von Tools-Installationsprogramm installiert\". Stellen Sie sicher, dass Sie die Aufgabe \"Installer für Visual Studio Test-Plattform\" einschließen, um die Testplattform von NuGet zu erhalten.", + "loc.input.label.vstestLocation": "Der Pfad zu \"vstest.console.exe\".", + "loc.input.help.vstestLocation": "Geben Sie optional den Pfad zu VSTest an.", + "loc.input.label.runSettingsFile": "Einstellungsdatei", + "loc.input.help.runSettingsFile": "Pfad zur Ausführungs- oder Testeinstellungsdatei, die bei den Tests verwendet werden soll.", + "loc.input.label.overrideTestrunParameters": "Testlaufparameter überschreiben", + "loc.input.help.overrideTestrunParameters": "Überschreiben Sie Parameter, die im Abschnitt \"TestRunParameters\" der Datei mit Laufzeiteinstellungen oder im Abschnitt \"Properties\" der Datei mit Testeinstellungen definiert sind. Beispiel: -key1 value1 -key2 value2. Hinweis: Auf Eigenschaften in der Datei mit den Testeinstellungen kann über TestContext unter Verwendung von Visual Studio 2017 Update 4 oder höher zugegriffen werden.", + "loc.input.label.pathtoCustomTestAdapters": "Pfad zu benutzerdefinierten Testadaptern", + "loc.input.help.pathtoCustomTestAdapters": "Der Verzeichnispfad für benutzerdefinierte Testadapter. Adapter, die sich im selben Verzeichnis befinden wie die Testassemblys, werden automatisch erkannt.", + "loc.input.label.runInParallel": "Tests parallel auf Multi-Core-Computern ausführen", + "loc.input.help.runInParallel": "Ist dies festgelegt, werden Tests parallel unter Verwendung der verfügbaren Kerne des Computers ausgeführt. Dadurch wird \"MaxCpuCount\" überschrieben, sofern dies in Ihrer Laufzeiteinstellungsdatei festgelegt ist. [Hier](https://aka.ms/paralleltestexecution) finden Sie weitere Informationen zur parallelen Testausführung.", + "loc.input.label.runTestsInIsolation": "Tests isoliert ausführen", + "loc.input.help.runTestsInIsolation": "Führt Tests in einem isolierten Prozess aus. Dies verringert die Wahrscheinlichkeit, dass \"vstest.console.exe\" bei Fehlern in Tests angehalten wird, aber die Tests werden möglicherweise langsamer ausgeführt. Diese Option kann bei Ausführung mit der Multi-Agent-Auftragseinstellung nicht verwendet werden.", + "loc.input.label.codeCoverageEnabled": "Code Coverage aktiviert", + "loc.input.help.codeCoverageEnabled": "Erfassen Sie Code Coverage-Informationen aus dem Testlauf.", + "loc.input.label.otherConsoleOptions": "Andere Konsolenoptionen", + "loc.input.help.otherConsoleOptions": "Weitere Konsolenoptionen, die an \"vstest.console.exe\" übergeben werden können, wie hier dokumentiert.

            Diese Optionen werden nicht unterstützt und werden beim Ausführen von Tests mithilfe der parallelen Multi-Agent-Einstellung eines Agent-Auftrags oder beim Ausführen von Tests mithilfe der Option \"Testplan\" oder \"Testausführung\" oder bei Auswahl einer Option für eine benutzerdefinierte Batchverarbeitung ignoriert. Diese Optionen können stattdessen mit einer Einstellungsdatei festgelegt werden.

            ", + "loc.input.label.distributionBatchType": "Batchtests", + "loc.input.help.distributionBatchType": "Ein Batch ist eine Gruppe von Tests. Für einen Batch von Tests werden die Tests gleichzeitig ausgeführt, und die Ergebnisse werden für den Batch veröffentlicht. Wenn der Auftrag, in dem die Aufgabe ausgeführt wird, für die Verwendung mehrerer Agents konfiguriert ist, wählt jeder Agent alle verfügbaren Testbatches aus, die parallel ausgeführt werden sollen.

            Basierend auf der Anzahl von Tests und Agents: Einfache Batchverarbeitung basierend auf der Anzahl von Tests und Agents, die am Testlauf beteiligt sind.

            Basierend auf der Laufzeit vergangener Tests: Diese Batchverarbeitung berücksichtigt die Laufzeit vergangener Tests, um Testbatches so zu erstellen, dass jeder Batch in etwa die gleiche Laufzeit aufweist.

            Basierend auf Testassemblys: Tests aus einer Assembly werden in einem Batch zusammengefasst.", + "loc.input.label.batchingBasedOnAgentsOption": "Batchoptionen", + "loc.input.help.batchingBasedOnAgentsOption": "Einfache Batchverarbeitung auf Grundlage der Anzahl von Tests und Agents, die am Testlauf beteiligt sind. Wenn die Batchgröße automatisch bestimmt wird, enthält jeder Batch eine Anzahl von Tests, die der Gesamtanzahl der Tests geteilt durch die Anzahl von Agents entspricht. Wenn eine Batchgröße angegeben ist, enthält jeder Batch die angegebene Anzahl von Tests.", + "loc.input.label.customBatchSizeValue": "Anzahl von Tests pro Batch", + "loc.input.help.customBatchSizeValue": "Batchgröße angeben", + "loc.input.label.batchingBasedOnExecutionTimeOption": "Batchoptionen", + "loc.input.help.batchingBasedOnExecutionTimeOption": "Bei dieser Batchverarbeitung wird die bisherige Ausführungszeit beim Erstellen von Testbatches berücksichtigt, sodass jeder Batch ungefähr die gleiche Ausführungszeit aufweist. Tests mit kurzer Ausführungszeit werden als Batch zusammengefasst, während Tests mit längerer Ausführungszeit einem separaten Batch angehören können. Wenn diese Option mit der Multi-Agent-Auftragseinstellung verwendet wird, wird die gesamte Testzeit auf ein Minimum reduziert.", + "loc.input.label.customRunTimePerBatchValue": "Ausführungszeit (Sekunden) pro Batch", + "loc.input.help.customRunTimePerBatchValue": "Ausführungszeit (Sekunden) pro Batch angeben", + "loc.input.label.dontDistribute": "Tests nicht verteilen und stattdessen replizieren, wenn mehrere Agents im Auftrag verwendet werden", + "loc.input.help.dontDistribute": "Bei Auswahl dieser Option werden Tests nicht auf Agents verteilt, wenn die Aufgabe in einem Auftrag mit mehreren Agents ausgeführt wird.
            Jeder ausgewählte Test wird auf jedem Agent wiederholt.
            Die Option ist nicht anwendbar, wenn der Agent-Auftrag zur Ausführung ohne Parallelität oder mit der Multikonfigurationsoption konfiguriert ist.", + "loc.input.label.testRunTitle": "Testlauftitel", + "loc.input.help.testRunTitle": "Geben Sie einen Namen für den Testlauf an.", + "loc.input.label.platform": "Buildplattform", + "loc.input.help.platform": "Buildplattform, für die Testberichte erstellt werden sollen. Wenn Sie eine Variable für die Plattform in Ihrer Buildaufgabe erstellt haben, verwenden Sie diese hier.", + "loc.input.label.configuration": "Buildkonfiguration", + "loc.input.help.configuration": "Buildkonfiguration, für die Testberichte erstellt werden sollen. Wenn Sie eine Variable für die Konfiguration in Ihrer Buildaufgabe erstellt haben, verwenden Sie diese hier.", + "loc.input.label.publishRunAttachments": "Testanlagen hochladen", + "loc.input.help.publishRunAttachments": "Veröffentlichen von Anlagen auf Ausführungsebene abonnieren oder kündigen.", + "loc.input.label.failOnMinTestsNotRun": "Aufgabe als fehlerhaft markieren, wenn eine Mindestanzahl von Tests nicht ausgeführt wird", + "loc.input.help.failOnMinTestsNotRun": "Bei Auswahl dieser Option wird die Aufgabe als fehlerhaft markiert, wenn nicht die angegebene Mindestanzahl von Tests ausgeführt wird.", + "loc.input.label.minimumExpectedTests": "Mindestanzahl von Tests", + "loc.input.help.minimumExpectedTests": "Geben Sie die Mindestanzahl von Tests an, die ausgeführt werden müssen, damit die Aufgabe erfolgreich ist. Die Gesamtzahl der ausgeführten Tests wird als Summe der bestandenen, fehlerhaften und abgebrochenen Tests berechnet.", + "loc.input.label.diagnosticsEnabled": "Bei schwerwiegenden Fehlern erweiterte Diagnosedaten erfassen", + "loc.input.help.diagnosticsEnabled": "Erfassen Sie bei schwerwiegenden Fehlern erweiterte Diagnosedaten.", + "loc.input.label.collectDumpOn": "Speicherabbild des Prozesses erfassen und an Testlaufbericht anfügen", + "loc.input.help.collectDumpOn": "Erfassen Sie ein Speicherabbild für den Prozess, und fügen Sie Ihn an den Testlaufbericht an.", + "loc.input.label.rerunFailedTests": "Fehlerhafte Tests erneut ausführen", + "loc.input.help.rerunFailedTests": "Durch Auswahl dieser Option werden fehlerhafte Tests erneut ausgeführt, bis sie erfolgreich sind oder die maximal zulässige Anzahl von Versuchen erreicht wird.", + "loc.input.label.rerunType": "Nicht erneut ausführen, wenn Testfehler den angegebenen Schwellenwert überschreiten", + "loc.input.help.rerunType": "Verwenden Sie diese Option, um das erneute Ausführen von Tests zu verhindern, wenn die Fehlerrate ein bestimmtes Limit überschreitet. Dies kann vorkommen, wenn Umgebungsprobleme zu massiven Fehlern führen.
            Sie können als Schwellenwert den Prozentsatz an Fehlern oder die Anzahl von Fehlern angeben.", + "loc.input.label.rerunFailedThreshold": "Fehler in %", + "loc.input.help.rerunFailedThreshold": "Verwenden Sie diese Option, um das erneute Ausführen von Tests zu verhindern, wenn die Fehlerrate ein bestimmtes Limit überschreitet. Dies kann vorkommen, wenn Umgebungsprobleme zu massiven Fehlern führen.", + "loc.input.label.rerunFailedTestCasesMaxLimit": "Anzahl von Tests mit Fehlern", + "loc.input.help.rerunFailedTestCasesMaxLimit": "Verwenden Sie diese Option, um das erneute Ausführen von Tests zu verhindern, wenn die Anzahl fehlerhafter Testfälle ein bestimmtes Limit überschreitet. Dies kann vorkommen, wenn Umgebungsprobleme zu massiven Fehlern führen.", + "loc.input.label.rerunMaxAttempts": "Maximale Anzahl von Versuchen", + "loc.input.help.rerunMaxAttempts": "Geben Sie die maximal zulässige Anzahl von Wiederholungsversuchen für einen fehlerhaften Test an. Wenn ein Test erfolgreich ausgeführt werden kann, bevor die maximal zulässige Anzahl von Versuchen erreicht wurde, wird er nicht erneut ausgeführt.", + "loc.messages.VstestLocationDoesNotExist": "Der als \"%s\" angegebene Speicherort von \"vstest.console.exe\" existiert nicht.", + "loc.messages.VstestFailedReturnCode": "Fehler bei VsTest-Aufgabe.", + "loc.messages.VstestPassedReturnCode": "VsTest-Aufgabe war erfolgreich.", + "loc.messages.NoMatchingTestAssemblies": "Es wurden keine Testassemblys gefunden, die mit dem Muster übereinstimmen: %s.", + "loc.messages.VstestNotFound": "Visual Studio %d wurde nicht gefunden. Versuchen Sie es noch mal mit einer Version, die auf Ihrem Build-Agent-Computer vorhanden ist.", + "loc.messages.NoVstestFound": "Die Testplattform wurde nicht gefunden. Versuchen Sie es nach der Installation auf Ihrem Build-Agent-Computer nochmal.", + "loc.messages.VstestFailed": "VSTest-Fehler. Überprüfen Sie die Protokolle auf Fehler. Möglicherweise sind Testfehler vorhanden.", + "loc.messages.VstestTIANotSupported": "Installieren Sie Visual Studio 2015 Update 3 oder Visual Studio 2017 RC oder höher, um eine Testwirkungsanalyse auszuführen.", + "loc.messages.NoResultsToPublish": "Es wurden keine Ergebnisse zum Veröffentlichen gefunden.", + "loc.messages.ErrorWhileReadingRunSettings": "Fehler beim Lesen der Datei mit den Ausführungseinstellungen. Fehler: %s.", + "loc.messages.ErrorWhileReadingTestSettings": "Fehler beim Lesen der Datei mit den Testeinstellungen. Fehler: %s.", + "loc.messages.RunInParallelNotSupported": "Das parallele Ausführen von Tests auf Multi-Core-Computern wird mit der Testeinstellungsdatei nicht unterstützt. Diese Option wird ignoriert.", + "loc.messages.InvalidSettingsFile": "Die angegebene Einstellungsdatei %s ist ungültig oder nicht vorhanden. Geben Sie eine gültige Einstellungsdatei an, oder löschen Sie das Feld.", + "loc.messages.UpdateThreeOrHigherRequired": "Installieren Sie Visual Studio 2015 Update 3 oder höher auf Ihrem Build-Agent-Computer, um die Tests parallel auszuführen.", + "loc.messages.ErrorOccuredWhileSettingRegistry": "Fehler beim Festlegen des Registrierungsschlüssels. Fehler: %s.", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "Fehler beim Festlegen des Testwirkungssammlers in der Datei mit den Testeinstellungen.", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "Fehler beim Festlegen des Testwirkungssammlers in der Datei mit den Ausführungseinstellungen.", + "loc.messages.ErrorWhileCreatingResponseFile": "Fehler beim Erstellen der Antwortdatei. Für diesen Lauf werden alle Tests ausgeführt.", + "loc.messages.ErrorWhileUpdatingResponseFile": "Fehler beim Aktualisieren der Antwortdatei \"%s\". Für diesen Lauf werden alle Tests ausgeführt.", + "loc.messages.ErrorWhilePublishingCodeChanges": "Fehler beim Veröffentlichen der Codeänderungen. Für diesen Lauf werden alle Tests ausgeführt.", + "loc.messages.ErrorWhileListingDiscoveredTests": "Fehler beim Ermitteln der Tests. Für diese Ausführung werden alle Tests ausgeführt.", + "loc.messages.PublishCodeChangesPerfTime": "Gesamtzeit für das Veröffentlichen von Änderungen: %d Millisekunden.", + "loc.messages.GenerateResponseFilePerfTime": "Gesamtzeit für das Abrufen der Antwortdatei: %d Millisekunden", + "loc.messages.UploadTestResultsPerfTime": "Gesamtzeit für das Hochladen der Testergebnisse: %d Millisekunden.", + "loc.messages.ErrorReadingVstestVersion": "Fehler beim Lesen der Version von \"vstest.console.exe\".", + "loc.messages.UnexpectedVersionString": "Unerwartete Versionszeichenfolge für \"vstest.console.exe\" erkannt: %s.", + "loc.messages.UnexpectedVersionNumber": "Unerwartete Versionsnummer für \"vstest.console.exe\" erkannt: %s.", + "loc.messages.VstestDiagNotSupported": "Die vstest.console.exe-Version bietet keine Unterstützung für das Flag \"/diag\". Aktivieren Sie die Diagnose über die exe.config-Dateien.", + "loc.messages.NoIncludePatternFound": "Kein Einschlussmuster gefunden. Geben Sie mindestens ein Einschlussmuster an, um nach Testassemblys zu suchen.", + "loc.messages.ErrorWhileUpdatingSettings": "Beim Aktualisieren der Einstellungsdatei ist ein Fehler aufgetreten. Die angegebene Einstellungsdatei wird verwendet.", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "Video collector wird mit Laufzeiteinstellungen nicht unterstützt.", + "loc.messages.runTestInIsolationNotSupported": "Das Ausführen von Tests in einem isolierten Prozess wird nicht unterstützt, wenn die Multi-Agent-Auftragseinstellung verwendet wird. Diese Option wird ignoriert.", + "loc.messages.overrideNotSupported": "Das Überschreiben von Testlaufparametern wird nur für eine Datei mit gültigen Laufzeit- oder Testeinstellungen unterstützt. Diese Option wird ignoriert.", + "loc.messages.testSettingPropertiesNotSupported": "Auf Eigenschaften in der Datei mit den Testeinstellungen kann über TestContext unter Verwendung von Visual Studio 2017 Update 4 oder höher zugegriffen werden.", + "loc.messages.vstestVersionInvalid": "Die angegebene Plattform \"%s\" wird nicht unterstützt.", + "loc.messages.configureDtaAgentFailed": "Fehler beim Konfigurieren des Test-Agents mit dem Server auch nach %d Versuchen: %s.", + "loc.messages.otherConsoleOptionsNotSupported": "Andere Konsolenoptionen werden für diese Aufgabenkonfiguration nicht unterstützt. Diese Option wird ignoriert.", + "loc.messages.distributedTestWorkflow": "In verteiltem Testflow", + "loc.messages.nonDistributedTestWorkflow": "Tests werden mit dem Runner \"vstest.console.exe\" ausgeführt.", + "loc.messages.dtaNumberOfAgents": "Verteilte Testausführung, Anzahl von Agents im Auftrag: %s", + "loc.messages.testSelectorInput": "Testauswahl: %s", + "loc.messages.searchFolderInput": "Suchordner: %s", + "loc.messages.testFilterCriteriaInput": "Testfilterkriterien: %s", + "loc.messages.runSettingsFileInput": "Laufzeiteinstellungsdatei: %s", + "loc.messages.runInParallelInput": "Parallel ausführen: %s", + "loc.messages.runInIsolationInput": "Separat ausführen: %s", + "loc.messages.pathToCustomAdaptersInput": "Pfad zu benutzerdefinierten Adaptern: %s", + "loc.messages.otherConsoleOptionsInput": "Andere Konsolenoptionen: %s", + "loc.messages.codeCoverageInput": "Code Coverage aktiviert: %s", + "loc.messages.testPlanInput": "Testplan-ID: %s", + "loc.messages.testplanConfigInput": "Testplankonfigurations-ID: %s", + "loc.messages.testSuiteSelected": "Ausgewählte Testsuite-ID: %s", + "loc.messages.testAssemblyFilterInput": "Testassemblys: %s", + "loc.messages.vsVersionSelected": "Die für die Testausführung ausgewählte Version von Visual Studio: %s", + "loc.messages.runTestsLocally": "Tests lokal mithilfe von %s ausführen", + "loc.messages.vstestLocationSpecified": "%s, angegebener Speicherort: %s", + "loc.messages.uitestsparallel": "Wenn Sie UI-Tests parallel auf dem gleichen Computer ausführen, treten unter Umständen Fehler auf. Deaktivieren Sie die Option \"Parallel ausführen\", oder führen Sie UI-Tests mithilfe einer separaten Aufgabe aus. Weitere Informationen finden Sie unter: https://aka.ms/paralleltestexecution", + "loc.messages.pathToCustomAdaptersInvalid": "Der Pfad zu den benutzerdefinierten Adaptern \"%s\" muss ein Verzeichnis sein und muss vorhanden sein.", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "Der Pfad zu den benutzerdefinierten Adaptern \"%s\" enthält keine Testadapter. Geben Sie einen gültigen Pfad an.", + "loc.messages.testAssembliesSelector": "Testassemblys", + "loc.messages.testPlanSelector": "Testplan", + "loc.messages.testRunSelector": "Testlauf", + "loc.messages.testRunIdInvalid": "Die Testauswahl lautet \"Testlauf\", aber die angegebene Testlauf-ID %s ist ungültig.", + "loc.messages.testRunIdInput": "Testlauf-ID: \"%s\"", + "loc.messages.testSourcesFilteringFailed": "Fehler beim Vorbereiten der Testquellendatei. Fehler: %s", + "loc.messages.noTestSourcesFound": "Es wurden keine Testquellen gefunden, die dem angegebenen Filter \"%s\" entsprechen.", + "loc.messages.DontShowWERUIDisabledWarning": "Die Registrierungseinstellung DontShowUI der Windows-Fehlerberichterstattung ist nicht festgelegt. Wenn das Windows-Fehlerdialogfeld während der Ausführung des UI-Tests angezeigt wird, reagiert der Test nicht mehr.", + "loc.messages.noVstestConsole": "Tests werden nicht mit der VSTest-Konsole ausgeführt. Installieren Sie Visual Studio 2017 RC oder höher, um Tests über die VSTest-Konsole auszuführen.", + "loc.messages.numberOfTestCasesPerSlice": "Anzahl von Testfällen pro Batch: %s", + "loc.messages.invalidTestBatchSize": "Eine ungültige Batchgröße wurde angegeben: %s.", + "loc.messages.invalidRunTimePerBatch": "Ungültige \"Ausführungszeit (Sekunden) pro Batch\": %s", + "loc.messages.minimumRunTimePerBatchWarning": "Der Wert von \"Ausführungszeit (Sekunden) pro Batch\" muss mindestens %s Sekunden betragen. Standardmäßig wird daher der unterstützte Mindestwert verwendet.", + "loc.messages.RunTimePerBatch": "Ausführungszeit pro Batch (Sekunden): %s", + "loc.messages.searchLocationNotDirectory": "Der Suchordner \"%s\" muss ein Verzeichnis und vorhanden sein.", + "loc.messages.rerunFailedTests": "Erneute Ausführung fehlerhafter Tests: %s", + "loc.messages.rerunFailedThreshold": "Schwellenwert für erneute Ausführung fehlerhafter Tests: %s", + "loc.messages.invalidRerunFailedThreshold": "Ungültiger Schwellenwert für die erneute Ausführung von fehlerhaften Tests, es wird der Standardwert 30 % verwendet.", + "loc.messages.rerunFailedTestCasesMaxLimit": "Wiederholungslimit für fehlerhafte Testfälle: %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "Ungültiges Limit für die erneute Ausführung von fehlerhaften Testfällen, es wird der Standardwert 5 verwendet.", + "loc.messages.rerunMaxAttempts": "Maximal zulässige Versuche für erneute Ausführung: %s", + "loc.messages.invalidRerunMaxAttempts": "Ungültige/zu hohe Anzahl maximal zulässiger Versuche für die erneute Ausführung, es wird der Standardwert 3 verwendet.", + "loc.messages.rerunNotSupported": "Installieren Sie Visual Studio 2015 Update 3 oder Visual Studio 2017, um fehlerhafte Tests erneut auszuführen.", + "loc.messages.toolsInstallerPathNotSet": "Der Ordner für die VsTest-Testplattform wurde nicht im Cache gefunden.", + "loc.messages.testImpactAndCCWontWork": "Testwirkung (Nur betroffene Tests ausführen) und Code Coverage-Datensammler funktionieren nicht.", + "loc.messages.ToolsInstallerInstallationError": "Der Toolinstaller für die Visual Studio-Testplattform wurde nicht ausgeführt, oder die Installation wurde nicht erfolgreich abgeschlossen. Informationen zur Verwendung des Toolinstallers finden Sie in diesem Blog: https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "Das Feld \"UseVerifiableInstrumentation\" in der runsettings-Datei wird mit dem Wert FALSE überschrieben.", + "loc.messages.NoTestResultsDirectoryFound": "Das Verzeichnis mit Testergebnissen wurde nicht gefunden.", + "loc.messages.OnlyWindowsOsSupported": "Diese Aufgabe wird nur auf Windows-Agenten unterstützt und kann auf anderen Plattformen nicht verwendet werden.", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "Bedarfsorientierte Ausführungen werden mit der Multikonfigurationsoption nicht unterstützt. Verwenden Sie die Parallelitätsoption \"Keine\" oder \"Multi-Agent\".", + "loc.messages.disabledRerun": "Die erneute Ausführung fehlerhafter Tests wird deaktiviert, weil der angegebene Schwellenwert für die erneute Ausführung \"%s\" lautet.", + "loc.messages.UpgradeAgentMessage": "Führen Sie ein Upgrade Ihrer Agent-Version durch. https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "VsTestVersion ist NULL oder leer.", + "loc.messages.UserProvidedSourceFilter": "Quellfilter: %s", + "loc.messages.UnableToGetFeatureFlag": "Featureflag kann nicht abgerufen werden: %s", + "loc.messages.diagnosticsInput": "Diagnose aktiviert: %s", + "loc.messages.UncPathNotSupported": "Der Pfad zum Testquellen-Suchordner darf kein UNC-Pfad sein. Geben Sie einen Stammpfad oder einen Pfad relativ zu \"$(System.DefaultWorkingDirectory)\" an.", + "loc.messages.LookingForBuildToolsInstalltion": "Es wird versucht, \"vstest.console\" in einer Installation der Visual Studio-Buildtools mit Version %s zu ermitteln.", + "loc.messages.LookingForVsInstalltion": "Es wird versucht, \"vstest.console\" in einer Visual Studio-Installation mit Version %s zu ermitteln.", + "loc.messages.minTestsNotExecuted": "Die angegebene Mindestanzahl von Tests (%d) wurde nicht im Testlauf ausgeführt.", + "loc.messages.actionOnThresholdNotMet": "Aktion, wenn der Schwellenwert für die Mindestanzahl von Tests nicht erfüllt ist: %s", + "loc.messages.minimumExpectedTests": "Mindestanzahl von Tests, die ausgeführt werden müssen: %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Strings/resources.resjson/en-US/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/en-US/resources.resjson new file mode 100644 index 000000000000..0d26a5e9f0c9 --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/en-US/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Visual Studio Test", + "loc.helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "Run unit and functional tests (Selenium, Appium, Coded UI test, etc.) using the Visual Studio Test (VsTest) runner. Test frameworks that have a Visual Studio test adapter such as MsTest, xUnit, NUnit, Chutzpah (for JavaScript tests using QUnit, Mocha and Jasmine), etc. can be run. Tests can be distributed on multiple agents using this task (version 2).", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
            • Run tests using an agent job: Unified agent across Build, Release and Test allows for automation agents to be used for testing purposes as well. You can distribute tests using the multi-agent job setting. The multi-config job setting can be used to replicate tests in different configurations. More information
            • Test Impact Analysis: Automatically select and run only the tests needed to validate the code change.
            • Use the Visual Studio Test Platform Installer task to run tests without needing a full Visual Studio installation.
            ", + "loc.group.displayName.testSelection": "Test selection", + "loc.group.displayName.executionOptions": "Execution options", + "loc.group.displayName.advancedExecutionOptions": "Advanced execution options", + "loc.group.displayName.reportingOptions": "Reporting options", + "loc.input.label.testSelector": "Select tests using", + "loc.input.help.testSelector": "
            • Test assembly: Use this option to specify one or more test assemblies that contain your tests. You can optionally specify a filter criteria to select only specific tests.
            • Test plan: Use this option to run tests from your test plan that have an automated test method associated with it.
            • Test run: Use this option when you are setting up an environment to run tests from the Test hub. This option should not be used when running tests in a continuous integration / continuous deployment (CI/CD) pipeline.
            • ", + "loc.input.label.testAssemblyVer2": "Test files", + "loc.input.help.testAssemblyVer2": "Run tests from the specified files.
              Ordered tests and webtests can be run by specifying the .orderedtest and .webtest files respectively. To run .webtest, Visual Studio 2017 Update 4 or higher is needed.

              The file paths are relative to the search folder. Supports multiple lines of minimatch patterns. [More information](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "Test plan", + "loc.input.help.testPlan": "Select a test plan containing test suites with automated test cases.", + "loc.input.label.testSuite": "Test suite", + "loc.input.help.testSuite": "Select one or more test suites containing automated test cases. Test case work items must be associated with an automated test method. [Learn more.](https://go.microsoft.com/fwlink/?linkid=847773", + "loc.input.label.testConfiguration": "Test configuration", + "loc.input.help.testConfiguration": "Select Test Configuration.", + "loc.input.label.tcmTestRun": "Test Run", + "loc.input.help.tcmTestRun": "Test run based selection is used when triggering automated test runs from the test hub. This option cannot be used for running tests in the CI/CD pipeline.", + "loc.input.label.searchFolder": "Search folder", + "loc.input.help.searchFolder": "Folder to search for the test assemblies.", + "loc.input.label.resultsFolder": "Test results folder", + "loc.input.help.resultsFolder": "Folder to store test results. When this input is not specified, results are stored in $(Agent.TempDirectory)/TestResults by default, which is cleaned at the end of a pipeline run. The results directory will always be cleaned up at the start of the vstest task before the tests are run. Relative folder path if provided will be considered relative to $(Agent.TempDirectory)", + "loc.input.label.testFiltercriteria": "Test filter criteria", + "loc.input.help.testFiltercriteria": "Additional criteria to filter tests from Test assemblies. For example: `Priority=1|Name=MyTestMethod`. [More information](https://msdn.microsoft.com/en-us/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "Run only impacted tests", + "loc.input.help.runOnlyImpactedTests": "Automatically select, and run only the tests needed to validate the code change. [More information](https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "Number of builds after which all tests should be run", + "loc.input.help.runAllTestsAfterXBuilds": "Number of builds after which to automatically run all tests. Test Impact Analysis stores the mapping between test cases and source code. It is recommended to regenerate the mapping by running all tests, on a regular basis.", + "loc.input.label.uiTests": "Test mix contains UI tests", + "loc.input.help.uiTests": "To run UI tests, ensure that the agent is set to run in interactive mode. Setting up an agent to run interactively must be done before queueing the build / release. Checking this box does not configure the agent in interactive mode automatically. This option in the task is to only serve as a reminder to configure agent appropriately to avoid failures.

              Hosted Windows agents from the VS 2015 and 2017 pools can be used to run UI tests.
              [More information](https://aka.ms/uitestmoreinfo).", + "loc.input.label.vstestLocationMethod": "Select test platform using", + "loc.input.label.vsTestVersion": "Test platform version", + "loc.input.help.vsTestVersion": "The version of Visual Studio test to use. If latest is specified it chooses latest Visual Studio version starting from VS2022 followed by VS2019, VS2017 and VS2015 depending on what is installed. Visual Studio 2013 is not supported. To run tests without needing Visual Studio on the agent, use the ‘Installed by tools installer’ option. Be sure to include the ‘Visual Studio Test Platform Installer’ task to acquire the test platform from nuget.", + "loc.input.label.vstestLocation": "Path to vstest.console.exe", + "loc.input.help.vstestLocation": "Optionally supply the path to VSTest.", + "loc.input.label.runSettingsFile": "Settings file", + "loc.input.help.runSettingsFile": "Path to runsettings or testsettings file to use with the tests.", + "loc.input.label.overrideTestrunParameters": "Override test run parameters", + "loc.input.help.overrideTestrunParameters": "Override parameters defined in the `TestRunParameters` section of runsettings file or `Properties` section of testsettings file. For example: `-key1 value1 -key2 value2`. Note: Properties specified in testsettings file can be accessed via the TestContext using Visual Studio 2017 Update 4 or higher ", + "loc.input.label.pathtoCustomTestAdapters": "Path to custom test adapters", + "loc.input.help.pathtoCustomTestAdapters": "Directory path to custom test adapters. Adapters residing in the same folder as the test assemblies are automatically discovered.", + "loc.input.label.runInParallel": "Run tests in parallel on multi-core machines", + "loc.input.help.runInParallel": "If set, tests will run in parallel leveraging available cores of the machine. This will override the MaxCpuCount if specified in your runsettings file. [Click here](https://aka.ms/paralleltestexecution) to learn more about how tests are run in parallel.", + "loc.input.label.runTestsInIsolation": "Run tests in isolation", + "loc.input.help.runTestsInIsolation": "Runs the tests in an isolated process. This makes vstest.console.exe process less likely to be stopped on an error in the tests, but tests might run slower. This option currently cannot be used when running with the multi-agent job setting.", + "loc.input.label.codeCoverageEnabled": "Code coverage enabled", + "loc.input.help.codeCoverageEnabled": "Collect code coverage information from the test run.", + "loc.input.label.otherConsoleOptions": "Other console options", + "loc.input.help.otherConsoleOptions": "Other console options that can be passed to vstest.console.exe, as documented here.

              These options are not supported and will be ignored when running tests using the ‘Multi agent’ parallel setting of an agent job or when running tests using ‘Test plan’ or 'Test run' option or when a custom batching option is selected. The options can be specified using a settings file instead.

              ", + "loc.input.label.distributionBatchType": "Batch tests", + "loc.input.help.distributionBatchType": "A batch is a group of tests. A batch of tests runs its tests at the same time and results are published for the batch. If the job in which the task runs is set to use multiple agents, each agent picks up any available batches of tests to run in parallel.

              Based on the number of tests and agents: Simple batching based on the number of tests and agents participating in the test run.

              Based on past running time of tests: This batching considers past running time to create batches of tests such that each batch has approximately equal running time.

              Based on test assemblies: Tests from an assembly are batched together.", + "loc.input.label.batchingBasedOnAgentsOption": "Batch options", + "loc.input.help.batchingBasedOnAgentsOption": "Simple batching based on the number of tests and agents participating in the test run. When the batch size is automatically determined, each batch contains `(total number of tests / number of agents)` tests. If a batch size is specified, each batch will contain the specified number of tests.", + "loc.input.label.customBatchSizeValue": "Number of tests per batch", + "loc.input.help.customBatchSizeValue": "Specify batch size", + "loc.input.label.batchingBasedOnExecutionTimeOption": "Batch options", + "loc.input.help.batchingBasedOnExecutionTimeOption": "This batching considers past running time to create batches of tests such that each batch has approximately equal running time. Quick running tests will be batched together, while longer running tests may belong to a separate batch. When this option is used with the multi-agent job setting, total test time is reduced to a minimum.", + "loc.input.label.customRunTimePerBatchValue": "Running time (sec) per batch", + "loc.input.help.customRunTimePerBatchValue": "Specify the running time (sec) per batch", + "loc.input.label.dontDistribute": "Replicate tests instead of distributing when multiple agents are used in the job", + "loc.input.help.dontDistribute": "Choosing this option will not distribute tests across agents when the task is running in a multi-agent job.
              Each of the selected test(s) will be repeated on each agent.
              The option is not applicable when the agent job is configured to run with no parallelism or with the multi-config option.", + "loc.input.label.testRunTitle": "Test run title", + "loc.input.help.testRunTitle": "Provide a name for the test run.", + "loc.input.label.platform": "Build platform", + "loc.input.help.platform": "Build platform against which the tests should be reported. If you have defined a variable for platform in your build task, use that here.", + "loc.input.label.configuration": "Build configuration", + "loc.input.help.configuration": "Build configuration against which the tests should be reported. If you have defined a variable for configuration in your build task, use that here.", + "loc.input.label.publishRunAttachments": "Upload test attachments", + "loc.input.help.publishRunAttachments": "Opt in/out of publishing run level attachments.", + "loc.input.label.failOnMinTestsNotRun": "Fail the task if a minimum number of tests are not run.", + "loc.input.help.failOnMinTestsNotRun": "Selecting this option will fail the task if specified minimum number of tests is not run.", + "loc.input.label.minimumExpectedTests": "Minimum # of tests", + "loc.input.help.minimumExpectedTests": "Specify the minimum # of tests that should be run for the task to succeed. Total tests executed is calculated as the sum of passed, failed and aborted tests.", + "loc.input.label.diagnosticsEnabled": "Collect advanced diagnostics in case of catastrophic failures", + "loc.input.help.diagnosticsEnabled": "Collect advanced diagnostics in case of catastrophic failures.", + "loc.input.label.collectDumpOn": "Collect process dump and attach to test run report", + "loc.input.help.collectDumpOn": "Collect process dump and attach to test run report.", + "loc.input.label.rerunFailedTests": "Rerun failed tests", + "loc.input.help.rerunFailedTests": "Selecting this option will rerun any failed tests until they pass or the maximum # of attempts is reached.", + "loc.input.label.rerunType": "Do not rerun if test failures exceed specified threshold", + "loc.input.help.rerunType": "Use this option to avoid rerunning tests when failure rate crosses the specified threshold. This is applicable if any environment issues leads to massive failures.
              You can specify % failures or # of failed tests as a threshold.", + "loc.input.label.rerunFailedThreshold": "% failure", + "loc.input.help.rerunFailedThreshold": "Use this option to avoid rerunning tests when failure rate crosses the specified threshold. This is applicable if any environment issues leads to massive failures.", + "loc.input.label.rerunFailedTestCasesMaxLimit": "# of failed tests", + "loc.input.help.rerunFailedTestCasesMaxLimit": "Use this option to avoid rerunning tests when number of failed test cases crosses specified limit. This is applicable if any environment issues leads to massive failures.", + "loc.input.label.rerunMaxAttempts": "Maximum # of attempts", + "loc.input.help.rerunMaxAttempts": "Specify the maximum # of times a failed test should be retried. If a test passes before the maximum # of attempts is reached, it will not be rerun further.", + "loc.messages.VstestLocationDoesNotExist": "The location of 'vstest.console.exe' specified '%s' does not exist.", + "loc.messages.VstestFailedReturnCode": "VsTest task failed.", + "loc.messages.VstestPassedReturnCode": "VsTest task succeeded.", + "loc.messages.NoMatchingTestAssemblies": "No test assemblies found matching the pattern: %s.", + "loc.messages.VstestNotFound": "Visual Studio %d is not found. Try again with a version that exists on your build agent machine.", + "loc.messages.NoVstestFound": "Test platform is not found. Try again after installing it on your build agent machine.", + "loc.messages.VstestFailed": "Vstest failed with error. Check logs for failures. There might be failed tests.", + "loc.messages.VstestTIANotSupported": "Install Visual Studio 2015 update 3 or Visual Studio 2017 RC or above to run Test Impact Analysis.", + "loc.messages.NoResultsToPublish": "No results found to publish.", + "loc.messages.ErrorWhileReadingRunSettings": "Error occurred while reading run settings file. Error : %s.", + "loc.messages.ErrorWhileReadingTestSettings": "Error occurred while reading test settings file. Error : %s.", + "loc.messages.RunInParallelNotSupported": "Running tests in parallel on multi-core machines is not supported with testsettings file. This option will be ignored.", + "loc.messages.InvalidSettingsFile": "The specified settings file %s is invalid or does not exist. Provide a valid settings file or clear the field.", + "loc.messages.UpdateThreeOrHigherRequired": "Install Visual Studio 2015 Update 3 or higher on your build agent machine to run the tests in parallel.", + "loc.messages.ErrorOccuredWhileSettingRegistry": "Error occurred while setting registry key, Error: %s.", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "Error occurred while setting Test Impact Collector in test settings file.", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "Error occurred while setting Test Impact Collector in run settings file.", + "loc.messages.ErrorWhileCreatingResponseFile": "Error occurred while creating the response file. All the tests will be executed for this run.", + "loc.messages.ErrorWhileUpdatingResponseFile": "Error occurred while updating the response file '%s'. All the tests will be executed for this run.", + "loc.messages.ErrorWhilePublishingCodeChanges": "Error occurred while publishing the code changes. All the tests will be executed for this run.", + "loc.messages.ErrorWhileListingDiscoveredTests": "Error occurred while discovering the tests. All the tests will be executed for this run.", + "loc.messages.PublishCodeChangesPerfTime": "Total time taken to publish code changes: %d milliseconds.", + "loc.messages.GenerateResponseFilePerfTime": "Total time taken to get response file: %d milliseconds.", + "loc.messages.UploadTestResultsPerfTime": "Total time taken to upload test results: %d milliseconds.", + "loc.messages.ErrorReadingVstestVersion": "Error reading the version of vstest.console.exe.", + "loc.messages.UnexpectedVersionString": "Unexpected version string detected for vstest.console.exe: %s.", + "loc.messages.UnexpectedVersionNumber": "Unexpected version number detected for vstest.console.exe: %s.", + "loc.messages.VstestDiagNotSupported": "vstest.console.exe version does not support the /diag flag. Enable diagnostics via the exe.config files", + "loc.messages.NoIncludePatternFound": "No include pattern found. Specify at least one include pattern to search test assemblies.", + "loc.messages.ErrorWhileUpdatingSettings": "Error occurred while updating the settings file. Using the specified settings file.", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "Video collector is not supported with run settings.", + "loc.messages.runTestInIsolationNotSupported": "Running tests in isolation is not supported when using the multi-agent job setting. This option will be ignored.", + "loc.messages.overrideNotSupported": "Overriding test run parameters is supported only with valid runsettings or testsettings file. This option will be ignored.", + "loc.messages.testSettingPropertiesNotSupported": "Properties specified in testsettings file can be accessed via the TestContext using Visual Studio 2017 Update 4 or higher", + "loc.messages.vstestVersionInvalid": "Given test platform version %s is not supported.", + "loc.messages.configureDtaAgentFailed": "Configuring the test agent with the server failed even after %d retries with error %s", + "loc.messages.otherConsoleOptionsNotSupported": "Other console options is not supported for this task configuration. This option will be ignored.", + "loc.messages.distributedTestWorkflow": "In distributed testing flow", + "loc.messages.nonDistributedTestWorkflow": "Running tests using vstest.console.exe runner.", + "loc.messages.dtaNumberOfAgents": "Distributed test execution, number of agents in job : %s", + "loc.messages.testSelectorInput": "Test selector : %s", + "loc.messages.searchFolderInput": "Search folder : %s", + "loc.messages.testFilterCriteriaInput": "Test filter criteria : %s", + "loc.messages.runSettingsFileInput": "Run settings file : %s", + "loc.messages.runInParallelInput": "Run in parallel : %s", + "loc.messages.runInIsolationInput": "Run in isolation : %s", + "loc.messages.pathToCustomAdaptersInput": "Path to custom adapters : %s", + "loc.messages.otherConsoleOptionsInput": "Other console options : %s", + "loc.messages.codeCoverageInput": "Code coverage enabled : %s", + "loc.messages.testPlanInput": "Test plan Id : %s", + "loc.messages.testplanConfigInput": "Test plan configuration Id : %s", + "loc.messages.testSuiteSelected": "Test suite Id selected: %s", + "loc.messages.testAssemblyFilterInput": "Test assemblies : %s", + "loc.messages.vsVersionSelected": "VisualStudio version selected for test execution : %s", + "loc.messages.runTestsLocally": "Run the tests locally using %s", + "loc.messages.vstestLocationSpecified": "%s, specified location : %s", + "loc.messages.uitestsparallel": "Running UI tests in parallel on the same machine can lead to errors. Consider disabling the ‘run in parallel’ option or run UI tests using a separate task. To learn more, see https://aka.ms/paralleltestexecution ", + "loc.messages.pathToCustomAdaptersInvalid": "Path to custom adapters '%s' should be a directory and it should exist.", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "Path to custom adapters '%s' does not contain any test adapters, provide a valid path.", + "loc.messages.testAssembliesSelector": "Test assemblies", + "loc.messages.testPlanSelector": "Test plan", + "loc.messages.testRunSelector": "Test run", + "loc.messages.testRunIdInvalid": "The test selection is 'Test run', but the test run ID '%s' given is invalid", + "loc.messages.testRunIdInput": "Test run Id : '%s'", + "loc.messages.testSourcesFilteringFailed": "Preparing the test sources file failed. Error : %s", + "loc.messages.noTestSourcesFound": "No test sources found matching the given filter '%s'", + "loc.messages.DontShowWERUIDisabledWarning": "Windows Error Reporting DontShowUI not set, if the windows error dialog pops-up in the middle of UI test execution than the test will hang", + "loc.messages.noVstestConsole": "Tests will not be executed with vstest console. Install Visual Studio 2017 RC or above to run tests via vstest console.", + "loc.messages.numberOfTestCasesPerSlice": "Number of test cases per batch : %s", + "loc.messages.invalidTestBatchSize": "Invalid batch size provided: %s", + "loc.messages.invalidRunTimePerBatch": "Invalid 'Running time (sec) per batch': %s", + "loc.messages.minimumRunTimePerBatchWarning": "'Running time (seconds) per batch' should be at least '%s' seconds. Defaulting to the minimum supported value.", + "loc.messages.RunTimePerBatch": "Run time per batch(sec) : %s", + "loc.messages.searchLocationNotDirectory": "Search folder: '%s' should be a directory and it should exist.", + "loc.messages.rerunFailedTests": "Rerun failed tests: %s", + "loc.messages.rerunFailedThreshold": "Rerun failed tests threshold: %s", + "loc.messages.invalidRerunFailedThreshold": "Invalid rerun failed tests threshold, defaulting to 30%", + "loc.messages.rerunFailedTestCasesMaxLimit": "Rerun maximum failed test case limit: %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "Invalid rerun failed tests case limit, defaulting to 5", + "loc.messages.rerunMaxAttempts": "Rerun maximum attempts: %s", + "loc.messages.invalidRerunMaxAttempts": "Invalid/Exceeded rerun maximum attempts, defaulting to 3", + "loc.messages.rerunNotSupported": "Install Visual Studio 2015 update 3 or Visual Studio 2017 to rerun failed tests.", + "loc.messages.toolsInstallerPathNotSet": "VsTest Test Platform folder was not found in cache.", + "loc.messages.testImpactAndCCWontWork": "Test Impact (Run only Impacted tests) and Code Coverage data collector will not work.", + "loc.messages.ToolsInstallerInstallationError": "The Visual Studio Test Platform tools installer did not run or did not complete the installation successfully, please refer to the following blog for information on how to use the tools installer: https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "Overriding UseVerifiableInstrumentation field to false in the runsettings file.", + "loc.messages.NoTestResultsDirectoryFound": "Test results directory not found.", + "loc.messages.OnlyWindowsOsSupported": "This task is supported only on Windows agents and cannot be used on other platforms.", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "On demand runs are not supported with Multi-Configuration option. Please use 'None' or 'Multi-agent' parallelism option.", + "loc.messages.disabledRerun": "Disabling the rerun of failed tests as the rerun threshold provided is %s", + "loc.messages.UpgradeAgentMessage": "Please upgrade your agent version. https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "VsTestVersion is null or empty", + "loc.messages.UserProvidedSourceFilter": "Source filter: %s", + "loc.messages.UnableToGetFeatureFlag": "Unable to get feature flag: %s", + "loc.messages.diagnosticsInput": "Diagnostics enabled : %s", + "loc.messages.UncPathNotSupported": "Path to test sources search folder cannot be a UNC path. Please provide a rooted path or a path relative to $(System.DefaultWorkingDirectory).", + "loc.messages.LookingForBuildToolsInstalltion": "Attempting to find vstest.console from a visual studio build tools installation with version %s.", + "loc.messages.LookingForVsInstalltion": "Attempting to find vstest.console from a visual studio installation with version %s.", + "loc.messages.minTestsNotExecuted": "The specified minimum number of tests %d were not executed in the test run.", + "loc.messages.actionOnThresholdNotMet": "Action when minimum tests threshold not met : %s", + "loc.messages.minimumExpectedTests": "Minimum tests expected to be run: %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Strings/resources.resjson/es-ES/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/es-ES/resources.resjson new file mode 100644 index 000000000000..cd47940694ce --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/es-ES/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Prueba de Visual Studio", + "loc.helpMarkDown": "[Obtener más información acerca de esta tarea](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "Ejecuta pruebas unitarias y funcionales (Selenium, Appium, prueba automatizada de IU, etc.) con el ejecutor de pruebas Visual Studio Test (VsTest). Los marcos de pruebas que tienen un adaptador de pruebas de Visual Studio, como MsTest, xUnit, NUnit, Chutzpah, etc. (para pruebas de JavaScript con QUnit, Mocha y Jasmine) pueden ejecutarse. Las pruebas se pueden distribuir en varios agentes con esta tarea (versión 2).", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
              • Ejecución de pruebas mediante el trabajo de agente: Un agente unificado en las fases de compilación, versión y prueba permite que también se usen agentes de automatización con fines de prueba. Puede distribuir las pruebas con la configuración de trabajo multiagente. Esta se puede usar para replicar las pruebas en distintas configuraciones. Más información
              • Análisis de impacto en pruebas: seleccione y ejecute automáticamente solo las pruebas necesarias para validar el cambio de código.
              • Use la tarea del instalador de Visual Studio Test Platform para ejecutar pruebas sin necesidad de una instalación completa de Visual Studio.
              ", + "loc.group.displayName.testSelection": "Selección de pruebas", + "loc.group.displayName.executionOptions": "Opciones de ejecución", + "loc.group.displayName.advancedExecutionOptions": "Opciones de ejecución avanzadas", + "loc.group.displayName.reportingOptions": "Opciones de informe", + "loc.input.label.testSelector": "Seleccionar las pruebas usando", + "loc.input.help.testSelector": "
              • Ensamblado de prueba: Use esta opción para especificar uno o varios ensmablados de prueba que contengan sus pruebas. También puede definir un criterio de filtro para seleccionar solo pruebas específicas.
              • Plan de pruebas: Use esta opción para ejecutar pruebas de su plan de pruebas que tengan un método de pruebas automatizado asociado.
              • Serie de pruebas: Use esta opción cuando configure un entorno para ejecutar pruebas de la central de pruebas. Esta opción no debe usarse cuando se ejecutan pruebas en una canalización de integración y entrega continuas (CI/CD).
              • ", + "loc.input.label.testAssemblyVer2": "Archivos de prueba", + "loc.input.help.testAssemblyVer2": "Ejecute pruebas desde los archivos especificados.
                Para ejecutar pruebas por orden y pruebas web, especifique los archivos .orderedtest y .webtest respectivamente. Para ejecutar .webtest, se requiere Visual Studio 2017 Update 4 o una versión posterior.

                Las rutas de acceso de los archivos son relativas a la carpeta de búsqueda. Admite varias líneas de patrones de minimatch. [Más información](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "Plan de pruebas", + "loc.input.help.testPlan": "Seleccione un plan de pruebas que contenga conjuntos de pruebas con casos de pruebas automatizadas.", + "loc.input.label.testSuite": "Conjunto de pruebas", + "loc.input.help.testSuite": "Seleccione uno o varios conjuntos de pruebas que contengan casos de pruebas automatizadas. Los elementos de trabajo de los casos de prueba deben estar asociados a un método de pruebas automatizadas. [Más información] (https://go.microsoft.com/fwlink/?linkid=847773)", + "loc.input.label.testConfiguration": "Configuración de prueba", + "loc.input.help.testConfiguration": "Seleccione la configuración de prueba.", + "loc.input.label.tcmTestRun": "Serie de pruebas", + "loc.input.help.tcmTestRun": "La selección basada en serie de pruebas se usa cuando se desencadenan series de pruebas automatizadas desde la central de pruebas. Esta opción no se puede usar para ejecutar pruebas en la canalización CI/CD.", + "loc.input.label.searchFolder": "Carpeta de búsqueda", + "loc.input.help.searchFolder": "La carpeta donde buscar los ensamblados de prueba.", + "loc.input.label.resultsFolder": "Carpeta de resultados de pruebas", + "loc.input.help.resultsFolder": "Carpeta para almacenar los resultados de las pruebas. Si no se especifica esta entrada, los resultados se almacenan en $(Agent.TempDirectory)/TestResults de forma predeterminada, que se limpia al final de una ejecución de canalización. El directorio de resultados se limpiará siempre al inicio de la tarea vstest antes de ejecutar las pruebas. Si se proporciona una ruta de acceso de carpeta relativa, se considerará relativa a $(Agent.TempDirectory)", + "loc.input.label.testFiltercriteria": "Criterios de filtro de la prueba", + "loc.input.help.testFiltercriteria": "Criterios adicionales para filtrar las pruebas de los ensamblados de prueba. Por ejemplo: \"Priority=1|Name=MyTestMethod\". [Más información](https://msdn.microsoft.com/en-us/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "Ejecutar solo las pruebas afectadas", + "loc.input.help.runOnlyImpactedTests": "Seleccione automáticamente y ejecute solo las pruebas necesarias para validar el cambio de código. [Más información] (https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "Número de compilaciones después del cual deben ejecutarse todas las pruebas", + "loc.input.help.runAllTestsAfterXBuilds": "Número de compilaciones transcurridas las cuales se ejecutan automáticamente todas las pruebas. El análisis de impacto en las pruebas almacena la asignación entre casos de prueba y código fuente. Se recomienda regenerar la asignación mediante la ejecución de todas las pruebas de manera periódica.", + "loc.input.label.uiTests": "La combinación de pruebas contiene pruebas de interfaz de usuario", + "loc.input.help.uiTests": "Para ejecutar pruebas de IU, asegúrese de que el agente está configurado para ejecutarse en modo interactivo. La configuración de un agente para su ejecución en modo interactivo debe hacerse antes de poner en cola la compilación o versión. La selección de esta casilla no configura el agente en modo interactivo de forma automática. Esta opción de la tarea solo sirve como recordatorio para configurar el agente de forma adecuada y evitar errores.

                Se pueden usar agentes Windows hospedados de los grupos de VS 2015 y 2017 para ejecutar pruebas de IU.
                [Más información](https://aka.ms/uitestmoreinfo).", + "loc.input.label.vstestLocationMethod": "Seleccionar la plataforma de pruebas usando", + "loc.input.label.vsTestVersion": "Versión de la plataforma de pruebas", + "loc.input.help.vsTestVersion": "La versión de prueba de Visual Studio que se utilizará. Si se especifica más reciente, se elige la última versión de Visual Studio, empezando por VS2022, seguida de VS2019, VS2017 y VS2015, en función de la versión instalada. Visual Studio 2013 no es compatible. Para ejecutar pruebas sin necesidad de Visual Studio en el agente, utilice la opción \"Instalado por el instalador de herramientas\". Asegúrese de incluir la tarea \"Instalador de la plataforma de pruebas de Visual Studio\" para adquirir la plataforma de pruebas de nuget.", + "loc.input.label.vstestLocation": "Ruta de acceso a vstest.console.exe", + "loc.input.help.vstestLocation": "Opcionalmente, puede proporcionar la ruta de acceso de VSTest.", + "loc.input.label.runSettingsFile": "Archivo de configuración", + "loc.input.help.runSettingsFile": "Ruta de acceso al archivo runsettings o testsettings que se va a usar en las pruebas.", + "loc.input.label.overrideTestrunParameters": "Reemplazar parámetros de serie de pruebas", + "loc.input.help.overrideTestrunParameters": "Reemplace los parámetros definidos en la sección de \"TestRunParameters\" del archivo runsettings o la sección \"Propiedades\" del archivo testsettings. Por ejemplo: \"- key1 value1 - key2 valor2\". Nota: Se puede acceder a las propiedades especificadas en el archivo testsettings a través de TestContext mediante Visual Studio 2017 Update 4 o superior ", + "loc.input.label.pathtoCustomTestAdapters": "Ruta de acceso de los adaptadores de pruebas personalizados", + "loc.input.help.pathtoCustomTestAdapters": "Ruta de acceso del directorio a los adaptadores de prueba personalizados. Los adaptadores que residen en la misma carpeta que los ensamblados de prueba se detectan automáticamente.", + "loc.input.label.runInParallel": "Ejecutar pruebas en paralelo en máquinas de varios núcleos", + "loc.input.help.runInParallel": "Si se establece esta opción, las pruebas se ejecutan en paralelo y aprovechan los núcleos disponibles en la máquina. Al hacerlo, se reemplaza el valor MaxCpuCount si se ha especificado en el archivo runsettings. [Haga clic aquí] (https://aka.ms/paralleltestexecution) para obtener más información sobre cómo se ejecutan pruebas en paralelo.", + "loc.input.label.runTestsInIsolation": "Ejecutar pruebas aisladas", + "loc.input.help.runTestsInIsolation": "Ejecuta las pruebas en un proceso aislado. De esta forma, es menos probable que se detenga el proceso vstest.console.exe si se produce un error en las pruebas, pero estas pueden ejecutarse con más lentitud. Actualmente, no se puede usar esta opción cuando se lleva a cabo la ejecución con la configuración de trabajo multiagente.", + "loc.input.label.codeCoverageEnabled": "Cobertura de código habilitada", + "loc.input.help.codeCoverageEnabled": "Recopilar información de cobertura de código de la serie de pruebas.", + "loc.input.label.otherConsoleOptions": "Otras opciones de la consola", + "loc.input.help.otherConsoleOptions": "Otras opciones de consola que se pueden pasar a vstest.console.exe, tal y como se documenta aquí.

                Estas opciones no se admiten y se ignorarán al ejecutar pruebas con la configuración paralela \"Multiagente\" de un trabajo de agente o al ejecutarlas con la opción \"Plan de pruebas\" o \"Serie de pruebas\" cuando se seleccione una opción de procesamiento por lotes personalizado. Para especificar las opciones, se puede usar un archivo de configuración en su lugar.

                ", + "loc.input.label.distributionBatchType": "Pruebas en lote", + "loc.input.help.distributionBatchType": "Un lote es un grupo de pruebas. Un lote de pruebas se ejecuta de una vez y los resultados se publican para ese lote. Si el trabajo en el que se ejecuta la tarea está establecido para usar varios agentes, cada agente selecciona los lotes de pruebas que haya disponibles para ejecutarlos en paralelo.

                En función del número de pruebas y de agentes: procesamiento por lotes sencillo basado en el número de pruebas y de agentes que participan en la serie de pruebas.

                En función del tiempo de ejecución transcurrido de las pruebas: este procesamiento por lotes considera el tiempo de ejecución transcurrido para crear lotes de pruebas de modo que cada lote tenga, aproximadamente, el mismo tiempo de ejecución.

                En función de los ensamblados de prueba: las pruebas de un ensamblado se procesan juntas en un lote.", + "loc.input.label.batchingBasedOnAgentsOption": "Opciones de lote", + "loc.input.help.batchingBasedOnAgentsOption": "Procesamiento por lotes sencillo basado en el número de pruebas y agentes que participan en la serie de pruebas. Cuando el tamaño de lote se determina automáticamente, cada lote contiene un número de pruebas que es el resultado de: \"número total de pruebas/número de agentes\". Si se especifica un tamaño de lote, cada lote contendrá el número de pruebas especificado.", + "loc.input.label.customBatchSizeValue": "Número de pruebas por lote", + "loc.input.help.customBatchSizeValue": "Especifique el tamaño de lote", + "loc.input.label.batchingBasedOnExecutionTimeOption": "Opciones de lote", + "loc.input.help.batchingBasedOnExecutionTimeOption": "Este procesamiento por lotes considera el tiempo de ejecución transcurrido para crear lotes de pruebas de modo que cada lote tenga, aproximadamente, el mismo tiempo de ejecución. Las pruebas de ejecución rápida se procesarán juntas en un lote, mientras que las de ejecución prolongada pueden pertenecer a lotes diferentes. Cuando esta opción se usa en un trabajo multiagente, el tiempo total de las pruebas se reduce al mínimo.", + "loc.input.label.customRunTimePerBatchValue": "Tiempo de ejecución por lote (en segundos)", + "loc.input.help.customRunTimePerBatchValue": "Especifique el tiempo de ejecución por lote (en segundos)", + "loc.input.label.dontDistribute": "Replicar pruebas en lugar de distribuirlas cuando se usen varios agentes en el trabajo", + "loc.input.help.dontDistribute": "Si elige esta opción, no se distribuirán pruebas entre agentes cuando la tarea se ejecute en un trabajo multiagente.
                Cada una de las pruebas seleccionadas se repetirá en cada agente.
                La opción no es aplicable cuando el trabajo de agente está configurado para ejecutarse sin paralelismo o con la opción de varias configuraciones.", + "loc.input.label.testRunTitle": "Título de la serie de pruebas", + "loc.input.help.testRunTitle": "Asigne un nombre a la serie de pruebas.", + "loc.input.label.platform": "Plataforma de compilación", + "loc.input.help.platform": "Plataforma de compilación en la que se deben evaluar las pruebas para los informes. Si tiene una variable de plataforma definida en la tarea de compilación, úsela aquí.", + "loc.input.label.configuration": "Configuración de compilación", + "loc.input.help.configuration": "Configuración de compilación con la que se deben evaluar las pruebas en los informes. Si tiene una variable de configuración definida en la tarea de compilación, úsela aquí.", + "loc.input.label.publishRunAttachments": "Cargar datos adjuntos de prueba", + "loc.input.help.publishRunAttachments": "Participar o no participar en la publicación de datos adjuntos en el nivel de ejecución.", + "loc.input.label.failOnMinTestsNotRun": "Genere un error de la tarea si no se ejecuta un número mínimo de pruebas.", + "loc.input.help.failOnMinTestsNotRun": "Al seleccionar esta opción, se producirá un error en la tarea si no se ejecuta el número mínimo de pruebas especificado.", + "loc.input.label.minimumExpectedTests": "Número mínimo de pruebas", + "loc.input.help.minimumExpectedTests": "Especifique el número mínimo de pruebas que deben ejecutarse para que la tarea se complete correctamente. El número total de pruebas ejecutadas se calcula como la suma de las pruebas superadas, con errores y anuladas.", + "loc.input.label.diagnosticsEnabled": "Recopilar diagnósticos avanzados en caso de errores graves", + "loc.input.help.diagnosticsEnabled": "Recopilar diagnósticos avanzados en caso de errores graves.", + "loc.input.label.collectDumpOn": "Recopilar volcado del proceso y asociarlo al informe de la serie de pruebas", + "loc.input.help.collectDumpOn": "Recopilar volcado del proceso y asociarlo al informe de la serie de pruebas.", + "loc.input.label.rerunFailedTests": "Volver a ejecutar las pruebas con errores", + "loc.input.help.rerunFailedTests": "Al seleccionar esta opción, se volverán a ejecutar las pruebas con errores hasta que se superen o se alcance el número máximo de intentos.", + "loc.input.label.rerunType": "No volver a ejecutar si los errores en las pruebas superan el umbral especificado", + "loc.input.help.rerunType": "Use esta opción para impedir que las pruebas vuelvan a ejecutarse cuando la tasa de errores supere el umbral especificado. Esto es aplicable si los problemas del entorno generan errores masivos.
                Puede especificar el porcentaje de errores o el número de pruebas con errores como umbral.", + "loc.input.label.rerunFailedThreshold": "Porcentaje de errores", + "loc.input.help.rerunFailedThreshold": "Use esta opción para impedir que las pruebas vuelvan a ejecutarse cuando la tasa de errores supere el umbral especificado. Esto es aplicable si los problemas del entorno generan errores masivos.", + "loc.input.label.rerunFailedTestCasesMaxLimit": "Número de pruebas con errores", + "loc.input.help.rerunFailedTestCasesMaxLimit": "Use esta opción para impedir que las pruebas vuelvan a ejecutarse cuando el número de casos de prueba con errores supere el límite especificado. Esto es aplicable si los problemas del entorno generan errores masivos.", + "loc.input.label.rerunMaxAttempts": "N.º máximo de intentos", + "loc.input.help.rerunMaxAttempts": "Especifique el número máximo de veces que debe reintentarse una prueba con errores. Si una prueba se supera antes de haberse alcanzado el número máximo de intentos, no volverá a ejecutarse.", + "loc.messages.VstestLocationDoesNotExist": "La ubicación de \"vstest.console.exe\" especificada \"%s\" no existe.", + "loc.messages.VstestFailedReturnCode": "Error de la tarea VsTest.", + "loc.messages.VstestPassedReturnCode": "La tarea VsTest se realizó correctamente.", + "loc.messages.NoMatchingTestAssemblies": "No se encontraron ensamblados de prueba que coincidan con el patrón: %s.", + "loc.messages.VstestNotFound": "No se encuentra Visual Studio %d. Vuelva a intentarlo con una versión que exista en la máquina del agente de compilación.", + "loc.messages.NoVstestFound": "La plataforma de prueba no se encuentra. Pruebe de nuevo tras instalarla en la máquina del agente de compilación.", + "loc.messages.VstestFailed": "Error de Vstest. Compruebe el informe para ver los errores. Podría haber pruebas con errores.", + "loc.messages.VstestTIANotSupported": "Instale Visual Studio 2015 update 3 o Visual Studio 2017 RC o posterior para ejecutar el análisis de impacto en las pruebas.", + "loc.messages.NoResultsToPublish": "No se encontraron resultados que publicar.", + "loc.messages.ErrorWhileReadingRunSettings": "Error al leer el archivo de parámetros de ejecución. Error : %s.", + "loc.messages.ErrorWhileReadingTestSettings": "Error al leer el archivo de configuración de pruebas. Error : %s.", + "loc.messages.RunInParallelNotSupported": "No se admite la ejecución de pruebas en paralelo en máquinas de varios núcleos con el archivo testsettings. Esta opción se omitirá.", + "loc.messages.InvalidSettingsFile": "El archivo de configuración especificado (%s) no es válido o no existe. Proporcione un archivo de configuración válido o borre el campo.", + "loc.messages.UpdateThreeOrHigherRequired": "Instale Visual Studio 2015 Update 3 o posterior en la máquina del agente de compilación para ejecutar las pruebas en paralelo.", + "loc.messages.ErrorOccuredWhileSettingRegistry": "Error al configurar la clave del Registro. Error: %s.", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "Error al configurar el recopilador de impacto en las pruebas en el archivo de configuración de pruebas.", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "Error al configurar el recopilador de impacto en las pruebas en el archivo de parámetros de ejecución.", + "loc.messages.ErrorWhileCreatingResponseFile": "Error al crear el archivo de respuesta. Todas las pruebas se ejecutarán para esta ejecución.", + "loc.messages.ErrorWhileUpdatingResponseFile": "Error al actualizar el archivo de respuesta '%s'. Todas las pruebas se ejecutarán para esta ejecución.", + "loc.messages.ErrorWhilePublishingCodeChanges": "Error al publicar los cambios de código. Se ejecutarán todas las pruebas de esta serie.", + "loc.messages.ErrorWhileListingDiscoveredTests": "Error al detectar las pruebas. Todas las pruebas se ejecutarán durante esta ejecución.", + "loc.messages.PublishCodeChangesPerfTime": "Tiempo total que se tarda en publicar los cambios de código: %d milisegundos.", + "loc.messages.GenerateResponseFilePerfTime": "Tiempo total que se tarda en obtener el archivo de respuesta: %d milisegundos.", + "loc.messages.UploadTestResultsPerfTime": "Tiempo total que se tarda en cargar los resultados de prueba: %d milisegundos.", + "loc.messages.ErrorReadingVstestVersion": "Error al leer la versión de vstest.console.exe.", + "loc.messages.UnexpectedVersionString": "Cadena de versión inesperada detectada para vstest.console.exe: %s.", + "loc.messages.UnexpectedVersionNumber": "Número de versión inesperado detectado para vstest.console.exe: %s.", + "loc.messages.VstestDiagNotSupported": "La versión de vstest.console.exe no admite la marca /diag. Habilite el diagnóstico con archivos exe.config", + "loc.messages.NoIncludePatternFound": "No se encuentra el patrón. Especifique al menos un patrón de inclusión para buscar los ensamblados de prueba.", + "loc.messages.ErrorWhileUpdatingSettings": "Error al actualizar el archivo de configuración. Usando el archivo de configuración especificado.", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "No se admite Video collector con parámetros de ejecución.", + "loc.messages.runTestInIsolationNotSupported": "La ejecución de pruebas aisladas no se admite cuando se usa la configuración de trabajo multiagente. Esta opción se omitirá.", + "loc.messages.overrideNotSupported": "Reemplazar parámetros de series de pruebas solo se admite con el archivo runsettings o testsettings. Esta opción se omitirá.", + "loc.messages.testSettingPropertiesNotSupported": "Se puede acceder a las propiedades especificadas en el archivo testsettings a través de TestContext mdiante Visual Studio 2017 Update 4 o superior", + "loc.messages.vstestVersionInvalid": "La versión de la plataforma de prueba determinada %s no existe.", + "loc.messages.configureDtaAgentFailed": "No se pudo configurar el agente de pruebas con el servidor, incluso después de %d reintentos. Error: %s", + "loc.messages.otherConsoleOptionsNotSupported": "No se admiten otras opciones de la consola para esta configuración de tarea. Esta opción se ignorará.", + "loc.messages.distributedTestWorkflow": "En flujo de pruebas distribuido", + "loc.messages.nonDistributedTestWorkflow": "Ejecutando pruebas con el ejecutor de vstest.console.exe.", + "loc.messages.dtaNumberOfAgents": "Ejecución de pruebas distribuidas, número de agentes en el trabajo: %s", + "loc.messages.testSelectorInput": "Selector de pruebas: %s", + "loc.messages.searchFolderInput": "Carpeta de búsqueda: %s", + "loc.messages.testFilterCriteriaInput": "Criterios de filtro de la prueba: %s", + "loc.messages.runSettingsFileInput": "Archivo de parámetros de ejecución: %s", + "loc.messages.runInParallelInput": "Ejecutar en paralelo: %s", + "loc.messages.runInIsolationInput": "Ejecutar de forma aislada: %s", + "loc.messages.pathToCustomAdaptersInput": "Ruta de acceso a los adaptadores personalizados: %s", + "loc.messages.otherConsoleOptionsInput": "Otras opciones de la consola: %s", + "loc.messages.codeCoverageInput": "Cobertura de código habilitada: %s", + "loc.messages.testPlanInput": "Id. del plan de pruebas: %s", + "loc.messages.testplanConfigInput": "Id. de configuración del plan de pruebas: %s", + "loc.messages.testSuiteSelected": "Id. de conjunto de pruebas seleccionado: %s", + "loc.messages.testAssemblyFilterInput": "Ensamblados de prueba: %s", + "loc.messages.vsVersionSelected": "Versión de Visual Studio seleccionada para la ejecución de pruebas: %s", + "loc.messages.runTestsLocally": "Ejecutar las pruebas localmente con %s", + "loc.messages.vstestLocationSpecified": "%s, ubicación especificada: %s", + "loc.messages.uitestsparallel": "Ejecutar pruebas de IU en paralelo en una misma máquina puede generar errores. Considere la posibilidad de deshabilitar la opción \"Ejecutar en paralelo\" o de ejecutar las pruebas de IU mediante una tarea independiente. Para obtener más información, consulte https://aka.ms/paralleltestexecution. ", + "loc.messages.pathToCustomAdaptersInvalid": "La ruta de acceso a los adaptadores personalizados \"%s\" debe ser un directorio y debe existir.", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "La ruta de acceso a los adaptadores personalizados \"%s\" no contiene adaptadores de prueba, proporcione una ruta de acceso válida.", + "loc.messages.testAssembliesSelector": "Ensamblados de prueba", + "loc.messages.testPlanSelector": "Plan de pruebas", + "loc.messages.testRunSelector": "Serie de pruebas", + "loc.messages.testRunIdInvalid": "La selección de pruebas es \"Serie de pruebas\", pero el identificador de serie de pruebas dado (%s) no es válido", + "loc.messages.testRunIdInput": "Id. de serie de pruebas: \"%s\"", + "loc.messages.testSourcesFilteringFailed": "No se pudo preparar el archivo de orígenes de pruebas. Error: %s", + "loc.messages.noTestSourcesFound": "No se encontraron orígenes de pruebas que coincidieran con el filtro \"%s\" proporcionado", + "loc.messages.DontShowWERUIDisabledWarning": "El valor DontShowUI de Informe de errores de Windows no se ha establecido. Si el cuadro de diálogo de error de Windows aparece en mitad de la ejecución de la prueba de IU, la prueba deja de responder.", + "loc.messages.noVstestConsole": "Las pruebas no se ejecutarán con la consola VSTest. Instale Visual Studio 2017 RC o posterior para ejecutar las pruebas con la consola VSTtest.", + "loc.messages.numberOfTestCasesPerSlice": "Número de casos de prueba por lote: %s", + "loc.messages.invalidTestBatchSize": "Tamaño de lote no válido: %s", + "loc.messages.invalidRunTimePerBatch": "\"Tiempo de ejecución por lote (en segundos)\" no válido: %s", + "loc.messages.minimumRunTimePerBatchWarning": "El valor de \"Tiempo de ejecución por lote (en segundos)\" debe ser al menos \"%s\" segundos. Se usará el valor mínimo admitido de forma predeterminada.", + "loc.messages.RunTimePerBatch": "Tiempo de ejecución por lote (en segundos): %s", + "loc.messages.searchLocationNotDirectory": "La carpeta de búsqueda \"%s\" debe ser un directorio y debe existir.", + "loc.messages.rerunFailedTests": "Volver a ejecutar las pruebas con errores: %s", + "loc.messages.rerunFailedThreshold": "Umbral de nuevas ejecuciones de las pruebas con errores: %s", + "loc.messages.invalidRerunFailedThreshold": "Umbral de nuevas ejecuciones de pruebas con errores no válido, con un valor predeterminado del 30 %.", + "loc.messages.rerunFailedTestCasesMaxLimit": "Límite de nuevas ejecuciones de los casos de pruebas con errores: %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "Límite de nuevas ejecuciones de casos de prueba con errores no válido, con un valor predeterminado de 5.", + "loc.messages.rerunMaxAttempts": "Máximo de intentos de nuevas ejecuciones: %s", + "loc.messages.invalidRerunMaxAttempts": "Se ha superado el número máximo de intentos para volver a ejecutar o la operación no es válida. El valor predeterminado es 3.", + "loc.messages.rerunNotSupported": "Instale Visual Studio 2015 Update 3 o Visual Studio 2017 para volver a ejecutar las pruebas con errores.", + "loc.messages.toolsInstallerPathNotSet": "No se encontró la carpeta VsTest Test Platform en la memoria caché.", + "loc.messages.testImpactAndCCWontWork": "El recopilador de impacto en las pruebas (Ejecutar solo las pruebas afectadas) y el de datos de cobertura de código no funcionarán.", + "loc.messages.ToolsInstallerInstallationError": "El instalador de herramientas de la plataforma de pruebas de Visual Studio no se ejecutó o no completó la instalación correctamente. Consulte el blog siguiente para obtener información sobre cómo usar el instalador de herramientas: https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "Reemplazando el campo UseVerifiableInstrumentation por false en el archivo runsettings.", + "loc.messages.NoTestResultsDirectoryFound": "No se encontró el directorio de resultados de pruebas.", + "loc.messages.OnlyWindowsOsSupported": "Esta tarea solo se admite en los agentes de Windows y no se puede usar en otras plataformas.", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "No se admiten ejecuciones a petición con la opción Multiconfiguración. Use la opción de paralelismo \"Ninguno\" o \"Multiagente\".", + "loc.messages.disabledRerun": "Se va a deshabilitar la repetición de la ejecución de las pruebas que han dado error porque el umbral de repeticiones de ejecución proporcionado es %s", + "loc.messages.UpgradeAgentMessage": "Actualice la versión del agente. https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "VsTestVersion es null o está vacío", + "loc.messages.UserProvidedSourceFilter": "Filtro de origen: %s", + "loc.messages.UnableToGetFeatureFlag": "No se puede obtener la marca de característica: %s", + "loc.messages.diagnosticsInput": "Diagnósticos habilitados: %s", + "loc.messages.UncPathNotSupported": "La ruta de acceso a la carpeta de búsqueda de orígenes de prueba no puede ser una ruta UNC. Proporcione una ruta de acceso raíz o una ruta de acceso relativa a $(System.DefaultWorkingDirectory).", + "loc.messages.LookingForBuildToolsInstalltion": "Se está intentando encontrar vstest.console desde una instalación de herramientas de compilación de Visual Studio con la versión %s.", + "loc.messages.LookingForVsInstalltion": "Se está intentando encontrar vstest.console desde una instalación de Visual Studio con la versión %s.", + "loc.messages.minTestsNotExecuted": "No se ejecutó el número mínimo de pruebas %d que se ha especificado en la serie de pruebas.", + "loc.messages.actionOnThresholdNotMet": "Acción cuando no se cumple el umbral de mínimo de pruebas: %s", + "loc.messages.minimumExpectedTests": "Mínimo de pruebas que se espera ejecutar: %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Strings/resources.resjson/fr-FR/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/fr-FR/resources.resjson new file mode 100644 index 000000000000..71c8f25e89d4 --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/fr-FR/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Visual Studio Test", + "loc.helpMarkDown": "[En savoir plus sur cette tâche](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "Exécutez des tests unitaires et des tests fonctionnels (Selenium, Appium, test codé de l'interface utilisateur, etc.) à l'aide de Visual Studio Test (VsTest) Runner. Les frameworks de tests disposant d'un adaptateur de test Visual Studio comme MsTest, xUnit, NUnit, Chutzpah (pour les tests JavaScript qui utilisent QUnit, Mocha et Jasmine), etc. peuvent être exécutés. Vous pouvez distribuer les tests sur plusieurs agents à l'aide de cette tâche (version 2).", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
                • Exécuter les tests à l'aide d'un travail d'agent : l'utilisation d'un agent unifié pour les phases de build, de mise en production et de test permet également d'utiliser les agents Automation à des fins de test. Vous pouvez distribuer les tests à l'aide du paramètre de travail multiagent. Le paramètre de travail multiconfiguration permet de répliquer les tests dans différentes configurations. Plus d'informations
                • Analyse de l'impact de test : sélection et exécution automatiques des tests nécessaires à la validation de la modification du code.
                • Utilisez la tâche Programme d'installation de Visual Studio Test Platform pour exécuter les tests sans avoir besoin d'une installation Visual Studio complète.
                ", + "loc.group.displayName.testSelection": "Sélection de test", + "loc.group.displayName.executionOptions": "Options d'exécution", + "loc.group.displayName.advancedExecutionOptions": "Options d'exécution avancées", + "loc.group.displayName.reportingOptions": "Options de signalement", + "loc.input.label.testSelector": "Sélectionner les tests avec", + "loc.input.help.testSelector": "
                • Assembly de test : utilisez cette option pour spécifier un ou plusieurs assemblys de tests contenant vos tests. Vous pouvez éventuellement spécifier des critères de filtre pour sélectionner uniquement des tests spécifiques.
                • Plan de test : utilisez cette option pour exécuter des tests à partir de votre plan de test associé à une méthode de test automatisé.
                • Série de tests : utilisez cette option quand vous configurez un environnement pour exécuter des tests à partir du hub de test. N'utilisez pas cette option durant l'exécution de tests dans un pipeline CI/CD.
                • ", + "loc.input.label.testAssemblyVer2": "Fichiers de test", + "loc.input.help.testAssemblyVer2": "Exécutez les tests à partir des fichiers spécifiés.
                  Vous pouvez exécuter les tests ordonnés et les tests web en spécifiant respectivement les fichiers .orderedtest et .webtest. Pour exécuter des fichiers .webtest, Visual Studio 2017 Update 4 (ou version ultérieure) est obligatoire.

                  Les chemins de fichiers sont relatifs au dossier de recherche. Prend en charge plusieurs lignes de modèles minimatch. [Plus d'informations](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "Plan de test", + "loc.input.help.testPlan": "Sélectionnez un plan de test contenant des suites de tests avec des cas de test automatisés.", + "loc.input.label.testSuite": "Suite de tests", + "loc.input.help.testSuite": "Sélectionnez une ou plusieurs suites de tests contenant des cas de test automatisés. Les éléments de travail des cas de test doivent être associés à une méthode de test automatisée. [En savoir plus.](https://go.microsoft.com/fwlink/?linkid=847773", + "loc.input.label.testConfiguration": "Configuration de test", + "loc.input.help.testConfiguration": "Sélectionnez la configuration de test.", + "loc.input.label.tcmTestRun": "Série de tests", + "loc.input.help.tcmTestRun": "La sélection en fonction de la série de tests est utilisée quand les séries de tests automatisés sont déclenchées à partir du hub de test. Vous ne pouvez pas utiliser cette option pour exécuter des tests dans le pipeline CI/CD.", + "loc.input.label.searchFolder": "Dossier de recherche", + "loc.input.help.searchFolder": "Dossier de recherche des assemblys de tests.", + "loc.input.label.resultsFolder": "Dossier des résultats des tests", + "loc.input.help.resultsFolder": "Dossier de stockage des résultats des tests. Quand cette entrée n'est pas spécifiée, les résultats sont stockés dans $(Agent.TempDirectory)/TestResults par défaut, qui est nettoyé à la fin d'une exécution de pipeline. Le répertoire des résultats est toujours nettoyé au début de la tâche vstest, avant l'exécution des tests. Le chemin relatif au dossier, s'il est fourni, est pris en compte par rapport à $(Agent.TempDirectory)", + "loc.input.label.testFiltercriteria": "Critères de filtre de test", + "loc.input.help.testFiltercriteria": "Critères supplémentaires pour le filtrage des tests des assemblys de tests. Exemple : 'Priority=1|Name=MyTestMethod'. [Plus d'informations](https://msdn.microsoft.com/fr-fr/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "Exécuter uniquement les tests impactés", + "loc.input.help.runOnlyImpactedTests": "Sélectionnez automatiquement, puis exécutez uniquement les tests nécessaires pour valider les modifications du code. [Plus d'informations](https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "Nombre de builds à partir duquel tous les tests doivent être exécutés", + "loc.input.help.runAllTestsAfterXBuilds": "Nombre de générations à partir duquel exécuter automatiquement tous les tests. L'analyse d'impact de test stocke le mappage entre les cas de test et le code source. Nous vous recommandons de régénérer régulièrement le mappage en exécutant tous les tests.", + "loc.input.label.uiTests": "La combinaison de tests contient les tests d'IU", + "loc.input.help.uiTests": "Pour exécuter les tests d'IU (interface utilisateur), vérifiez que l'agent est configuré pour s'exécuter en mode interactif. Si vous configurez un agent pour qu'il s'exécute de manière interactive, vous devez le faire avant de mettre la build/mise en production en file d'attente. Le fait de cocher cette case n'entraîne pas la configuration automatique de l'agent en mode interactif. Cette option de la tâche sert uniquement de rappel pour configurer l'agent de manière appropriée afin d'éviter les échecs.

                  Vous pouvez utiliser les agents Windows hébergés des pools VS 2015 et 2017 pour exécuter des tests d'IU.
                  [Plus d'informations](https://aka.ms/uitestmoreinfo).", + "loc.input.label.vstestLocationMethod": "Sélectionner la plateforme de test via", + "loc.input.label.vsTestVersion": "Version de la plateforme de test", + "loc.input.help.vsTestVersion": "Version de Visual Studio test à utiliser. Si la dernière version est spécifiée, elle choisit la dernière version Visual Studio à partir de VS2022, suivi de VS2019, VS2017 et VS2015 en fonction de ce qui est installé. Visual Studio 2013 n’est pas pris en charge. Pour exécuter des tests sans avoir à Visual Studio sur l’agent, utilisez l’option ‘Installer par les outils’ . Veillez à inclure la ‘tâche Visual Studio Programme d’installation de la plateforme’ de test pour acquérir la plateforme de test à partir de nuget.", + "loc.input.label.vstestLocation": "Chemin de vstest.console.exe", + "loc.input.help.vstestLocation": "Indiquez éventuellement le chemin de VSTest.", + "loc.input.label.runSettingsFile": "Fichier de paramètres", + "loc.input.help.runSettingsFile": "Chemin du fichier runsettings ou testsettings à utiliser avec les tests.", + "loc.input.label.overrideTestrunParameters": "Remplacer les paramètres de série de tests", + "loc.input.help.overrideTestrunParameters": "Remplacez les paramètres définis dans la section 'TestRunParameters' du fichier runsettings ou la section 'Properties' du fichier testsettings. Exemple : '-key1 value1 -key2 value2'. Remarque : Les propriétés spécifiées dans le fichier testsettings sont accessibles via TestContext à l'aide de Visual Studio 2017 Update 4 ou une version ultérieure. ", + "loc.input.label.pathtoCustomTestAdapters": "Chemin des adaptateurs de tests personnalisés", + "loc.input.help.pathtoCustomTestAdapters": "Chemin de répertoire des adaptateurs de test personnalisés. Les adaptateurs résidant dans le même dossier que les assemblys de tests sont automatiquement découverts.", + "loc.input.label.runInParallel": "Exécuter les tests en parallèle sur des machines multicœur", + "loc.input.help.runInParallel": "Si l'option est définie, les tests s'exécutent en parallèle en fonction des cœurs disponibles de la machine. Ceci va remplacer MaxCpuCount, s'il est spécifié dans votre fichier runsettings. [Cliquez ici](https://aka.ms/paralleltestexecution) pour en savoir plus sur l'exécution des tests en parallèle.", + "loc.input.label.runTestsInIsolation": "Exécuter les tests en isolement", + "loc.input.help.runTestsInIsolation": "Exécute les tests dans un processus isolé. Cela rend le processus vstest.console.exe moins susceptible d'être arrêté en cas d'erreur dans les tests. Toutefois, les tests risquent de s'exécuter plus lentement. Cette option ne peut pas être utilisée durant l'exécution avec le paramètre de travail multiagent.", + "loc.input.label.codeCoverageEnabled": "Couverture du code activée", + "loc.input.help.codeCoverageEnabled": "Collectez les informations de couverture du code fournies par la série de tests.", + "loc.input.label.otherConsoleOptions": "Autres options de console", + "loc.input.help.otherConsoleOptions": "Autres options de console pouvant être passées à vstest.console.exe, comme indiqué ici.

                  Ces options ne sont pas prises en charge et sont ignorées quand vous exécutez des tests à l'aide du paramètre parallèle 'Multiagent' d'un travail d'agent, quand vous exécutez des tests à l'aide de l'option 'Plan de test' ou 'Série de tests', ou quand vous sélectionnez une option de traitement par lot personnalisé. À la place, vous pouvez spécifier les options à l'aide d'un fichier de paramètres.

                  ", + "loc.input.label.distributionBatchType": "Tests par lot", + "loc.input.help.distributionBatchType": "Un lot est un groupe de tests. Dans un lot de tests, tous les tests s'exécutent en même temps. Les résultats du lot sont ensuite publiés. Si le travail au cours duquel la tâche s'exécute est configurée pour utiliser plusieurs agents, chaque agent choisit les lots de tests disponibles pour s'exécuter en parallèle.

                  En fonction du nombre de tests et d'agents : traitement par lot simple basé sur le nombre de tests et d'agents impliqués dans la série de tests.

                  En fonction du temps d'exécution des tests : ce traitement par lot prend en compte le temps d'exécution pour créer des lots de tests où chaque lot a environ le même temps d'exécution.

                  En fonction des assemblys de tests : les tests d'un assembly sont regroupés.", + "loc.input.label.batchingBasedOnAgentsOption": "Options de lot", + "loc.input.help.batchingBasedOnAgentsOption": "Traitement par lot simple basé sur le nombre de tests et d'agents impliqués dans la série de tests. Quand la taille du lot est déterminée de façon automatique, chaque lot contient un nombre de tests correspondant à : 'nombre total de tests / nombre d'agents'. Si une taille de lot est spécifiée, chaque lot contient le nombre de tests spécifié.", + "loc.input.label.customBatchSizeValue": "Nombre de tests par lot", + "loc.input.help.customBatchSizeValue": "Spécifier la taille du lot", + "loc.input.label.batchingBasedOnExecutionTimeOption": "Options de lot", + "loc.input.help.batchingBasedOnExecutionTimeOption": "Ce traitement par lot prend en compte le temps d'exécution pour créer des lots de tests où chaque lot a environ le même temps d'exécution. Les tests rapides sont regroupés, alors que les tests plus longs font éventuellement partie d'un autre lot. Quand cette option est utilisée avec le paramètre de travail multiagent, la durée totale des tests est réduite au minimum.", + "loc.input.label.customRunTimePerBatchValue": "Temps d'exécution (en secondes) par lot", + "loc.input.help.customRunTimePerBatchValue": "Spécifier le temps d'exécution (en secondes) par lot", + "loc.input.label.dontDistribute": "Répliquer les tests au lieu de les distribuer quand plusieurs agents sont utilisés dans le travail", + "loc.input.help.dontDistribute": "Si vous choisissez cette option, les tests ne sont pas distribués entre les agents quand la tâche s'exécute dans le cadre d'un travail multiagent.
                  Chacun des tests sélectionnés est répété sur chaque agent.
                  L'option est non applicable quand le travail d'agent est configuré pour s'exécuter sans parallélisme ou avec l'option de multiconfiguration.", + "loc.input.label.testRunTitle": "Titre de la série de tests", + "loc.input.help.testRunTitle": "Indiquez le nom de la série de tests.", + "loc.input.label.platform": "Plateforme de build", + "loc.input.help.platform": "Plateforme de build pour laquelle les tests doivent être signalés. Si vous avez défini une variable de plateforme dans votre tâche de build, utilisez-la ici.", + "loc.input.label.configuration": "Configuration de build", + "loc.input.help.configuration": "Configuration de build pour laquelle les tests doivent être signalés. Si vous avez défini une variable de configuration dans votre tâche de build, utilisez-la ici.", + "loc.input.label.publishRunAttachments": "Charger les pièces jointes du test", + "loc.input.help.publishRunAttachments": "Acceptation/refus de la publication des pièces jointes de la série.", + "loc.input.label.failOnMinTestsNotRun": "Échec de la tâche si un nombre minimal de tests n'est pas exécuté.", + "loc.input.help.failOnMinTestsNotRun": "La sélection de cette option entraîne l'échec de la tâche si le nombre minimal de tests spécifié n'est pas exécuté.", + "loc.input.label.minimumExpectedTests": "Nombre minimal de tests", + "loc.input.help.minimumExpectedTests": "Spécifiez le nombre minimal de tests à exécuter pour que la tâche réussisse. Le nombre total de tests exécutés est calculé en tant que somme des tests réussis, non réussis et abandonnés.", + "loc.input.label.diagnosticsEnabled": "Collecter les diagnostics avancés en cas de défaillances majeures", + "loc.input.help.diagnosticsEnabled": "Collectez les diagnostics avancés en cas de défaillances majeures.", + "loc.input.label.collectDumpOn": "Collecter l'image mémoire du processus, et la joindre au rapport de série de tests", + "loc.input.help.collectDumpOn": "Collectez l'image mémoire du processus, et joignez-la au rapport de série de tests.", + "loc.input.label.rerunFailedTests": "Réexécuter les tests non réussis", + "loc.input.help.rerunFailedTests": "Si vous sélectionnez cette option, tous les tests non réussis sont réexécutés jusqu'à ce qu'ils réussissent ou que le nombre maximal de tentatives soit atteint.", + "loc.input.label.rerunType": "Ne pas réexécuter si les tests non réussis dépassent le seuil spécifié", + "loc.input.help.rerunType": "Utilisez cette option pour éviter de réexécuter les tests quand le taux d'échec dépasse le seuil spécifié. Cela s'applique quand des problèmes d'environnement entraînent un grand nombre d'échecs.
                  Vous pouvez spécifier un seuil basé sur le % d'échecs ou sur le nombre de tests non réussis.", + "loc.input.label.rerunFailedThreshold": "% d'échecs", + "loc.input.help.rerunFailedThreshold": "Utilisez cette option pour éviter de réexécuter les tests quand le taux d'échec dépasse le seuil spécifié. Cela s'applique quand des problèmes d'environnement entraînent un grand nombre d'échecs.", + "loc.input.label.rerunFailedTestCasesMaxLimit": "Nombre de tests non réussis", + "loc.input.help.rerunFailedTestCasesMaxLimit": "Utilisez cette option pour éviter de réexécuter les tests quand le nombre de cas de test non réussis dépasse la limite spécifiée. Cela s'applique quand des problèmes d'environnement entraînent un grand nombre d'échecs.", + "loc.input.label.rerunMaxAttempts": "Nombre maximal de tentatives", + "loc.input.help.rerunMaxAttempts": "Spécifiez le nombre maximal de nouvelles tentatives d'un test non réussi. Si un test réussit avant que le nombre maximal de tentatives ne soit atteint, il n'est pas réexécuté.", + "loc.messages.VstestLocationDoesNotExist": "L'emplacement spécifié '%s' pour 'vstest.console.exe' n'existe pas.", + "loc.messages.VstestFailedReturnCode": "Échec de la tâche VsTest.", + "loc.messages.VstestPassedReturnCode": "Exécution réussie de la tâche VsTest.", + "loc.messages.NoMatchingTestAssemblies": "Aucun assembly de test ne correspond au modèle %s.", + "loc.messages.VstestNotFound": "Visual Studio %d est introuvable. Réessayez avec une version qui existe sur la machine d'agent de build.", + "loc.messages.NoVstestFound": "La plateforme de test est introuvable. Réessayez l'opération après l'avoir installée sur votre machine d'agent de build.", + "loc.messages.VstestFailed": "Échec de Vstest avec une erreur. Vérifiez la présence d'échecs dans les journaux. Il est possible que des tests aient échoué.", + "loc.messages.VstestTIANotSupported": "Installez Visual Studio 2015 Update 3 ou Visual Studio 2017 RC (ou version ultérieure) pour exécuter l'analyse de l'impact de test.", + "loc.messages.NoResultsToPublish": "Aucun résultat à publier.", + "loc.messages.ErrorWhileReadingRunSettings": "Une erreur s'est produite durant la lecture du fichier de paramètres d'exécution. Erreur : %s.", + "loc.messages.ErrorWhileReadingTestSettings": "Une erreur s'est produite durant la lecture du fichier de paramètres de test. Erreur : %s.", + "loc.messages.RunInParallelNotSupported": "L'exécution de tests en parallèle sur des machines multicœur n'est pas prise en charge avec le fichier testsettings. Cette option va être ignorée.", + "loc.messages.InvalidSettingsFile": "Le fichier de paramètres spécifié, %s, est non valide ou n'existe pas. Indiquez un fichier de paramètres valide ou effacez le champ.", + "loc.messages.UpdateThreeOrHigherRequired": "Installez Visual Studio 2015 Update 3, ou une version ultérieure, sur votre machine d'agent de build pour exécuter les tests en parallèle.", + "loc.messages.ErrorOccuredWhileSettingRegistry": "Une erreur s'est produite durant la définition de la clé de Registre. Erreur : %s.", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "Une erreur s'est produite pendant la définition du Collecteur d'impact de test dans le fichier de paramètres de test.", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "Une erreur s'est produite pendant la définition du Collecteur d'impact de test dans le fichier de paramètres d'exécution.", + "loc.messages.ErrorWhileCreatingResponseFile": "Une erreur s'est produite pendant la création du fichier réponse. Tous les tests de cette série vont être exécutés.", + "loc.messages.ErrorWhileUpdatingResponseFile": "Une erreur s'est produite pendant la mise à jour du fichier réponse '%s'. Tous les tests de cette série vont être exécutés.", + "loc.messages.ErrorWhilePublishingCodeChanges": "Une erreur s'est produite durant la publication des modifications du code. Tous les tests vont être exécutés pour cette série.", + "loc.messages.ErrorWhileListingDiscoveredTests": "Une erreur s'est produite durant la découverte des tests. Tous les tests vont être exécutés pour cette série.", + "loc.messages.PublishCodeChangesPerfTime": "Temps total de publication des modifications du code : %d millisecondes.", + "loc.messages.GenerateResponseFilePerfTime": "Temps total d'obtention du fichier réponse : %d millisecondes.", + "loc.messages.UploadTestResultsPerfTime": "Durée totale du chargement des résultats des tests : %d millisecondes.", + "loc.messages.ErrorReadingVstestVersion": "Erreur à la lecture de la version de vstest.console.exe.", + "loc.messages.UnexpectedVersionString": "Chaîne de version inattendue détectée pour vstest.console.exe : %s.", + "loc.messages.UnexpectedVersionNumber": "Numéro de version inattendu détecté pour vstest.console.exe : %s.", + "loc.messages.VstestDiagNotSupported": "La version de vstest.console.exe ne prend pas en charge l'indicateur /diag. Activez les diagnostics via les fichiers exe.config", + "loc.messages.NoIncludePatternFound": "Modèle d'inclusion introuvable. Spécifiez au moins un modèle d'inclusion pour rechercher des assemblys de test.", + "loc.messages.ErrorWhileUpdatingSettings": "Une erreur s'est produite durant la mise à jour du fichier de paramètres. Utilisation du fichier de paramètres spécifié.", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "Video collector n'est pas pris en charge avec les paramètres d'exécution.", + "loc.messages.runTestInIsolationNotSupported": "L'exécution des tests en isolement n'est pas prise en charge avec le paramètre de travail multiagent. Cette option va être ignorée.", + "loc.messages.overrideNotSupported": "Le remplacement des paramètres de série de tests est pris en charge uniquement avec un fichier runsettings ou testsettings valide. Cette option va être ignorée.", + "loc.messages.testSettingPropertiesNotSupported": "Les propriétés spécifiées dans le fichier testsettings sont accessibles via TestContext à l'aide de Visual Studio 2017 Update 4 ou une version ultérieure.", + "loc.messages.vstestVersionInvalid": "La version %s de la plateforme de test spécifiée n'est pas prise en charge.", + "loc.messages.configureDtaAgentFailed": "La configuration de l'agent de test et du serveur a échoué même après %d nouvelles tentatives. Erreur %s", + "loc.messages.otherConsoleOptionsNotSupported": "Les autres options de console ne sont pas prises en charge pour cette configuration de tâche. Cette option va être ignorée.", + "loc.messages.distributedTestWorkflow": "Dans le flux de test distribué", + "loc.messages.nonDistributedTestWorkflow": "Exécution des tests à l'aide de l'exécuteur vstest.console.exe.", + "loc.messages.dtaNumberOfAgents": "Exécution du test distribué. Nombre d'agents dans le travail : %s", + "loc.messages.testSelectorInput": "Sélecteur de test : %s", + "loc.messages.searchFolderInput": "Dossier de recherche : %s", + "loc.messages.testFilterCriteriaInput": "Critères de filtre de test : %s", + "loc.messages.runSettingsFileInput": "Fichier de paramètres d'exécution : %s", + "loc.messages.runInParallelInput": "Exécuter en parallèle : %s", + "loc.messages.runInIsolationInput": "Exécuter en isolation : %s", + "loc.messages.pathToCustomAdaptersInput": "Chemin des adaptateurs personnalisés : %s", + "loc.messages.otherConsoleOptionsInput": "Autres options de console : %s", + "loc.messages.codeCoverageInput": "Couverture du code activée : %s", + "loc.messages.testPlanInput": "ID de plan de test : %s", + "loc.messages.testplanConfigInput": "ID de configuration du plan de test : %s", + "loc.messages.testSuiteSelected": "ID de suite de tests sélectionné : %s", + "loc.messages.testAssemblyFilterInput": "Assemblys de test : %s", + "loc.messages.vsVersionSelected": "Version de Visual Studio sélectionnée pour l'exécution des tests : %s", + "loc.messages.runTestsLocally": "Exécuter les tests localement à l'aide de %s", + "loc.messages.vstestLocationSpecified": "%s, emplacement spécifiée : %s", + "loc.messages.uitestsparallel": "L'exécution de tests d'IU en parallèle sur la même machine peut entraîner des erreurs. Désactivez l'option Exécuter en parallèle, ou exécutez les tests d'IU à l'aide d'une tâche distincte. Pour en savoir plus, consultez https://aka.ms/paralleltestexecution ", + "loc.messages.pathToCustomAdaptersInvalid": "Le chemin des adaptateurs personnalisés '%s' doit correspondre à un répertoire existant.", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "Le chemin des adaptateurs personnalisés '%s' ne contient aucun adaptateur de test. Indiquez un chemin valide.", + "loc.messages.testAssembliesSelector": "Assemblys de tests", + "loc.messages.testPlanSelector": "Plan de test", + "loc.messages.testRunSelector": "Série de tests", + "loc.messages.testRunIdInvalid": "La sélection de test correspond à 'Série de tests', mais l'ID de série de tests '%s' fourni est non valide", + "loc.messages.testRunIdInput": "ID de série de tests : '%s'", + "loc.messages.testSourcesFilteringFailed": "Échec de la préparation du fichier de sources de test. Erreur : %s", + "loc.messages.noTestSourcesFound": "Aucune source de test ne correspond au filtre spécifié '%s'", + "loc.messages.DontShowWERUIDisabledWarning": "DontShowUI n'est pas défini pour le rapport d'erreurs Windows. Si la boîte de dialogue d'erreur de Windows s'affiche durant l'exécution du test d'IU, le test cessera de répondre", + "loc.messages.noVstestConsole": "Les tests ne seront pas exécutés avec la console vstest. Installez Visual Studio 2017 RC ou une version ultérieure pour exécuter des tests via la console vstest.", + "loc.messages.numberOfTestCasesPerSlice": "Nombre de cas de test par lot : %s", + "loc.messages.invalidTestBatchSize": "Taille de lot fournie non valide : %s", + "loc.messages.invalidRunTimePerBatch": "Temps d'exécution (en secondes) par lot non valide : %s", + "loc.messages.minimumRunTimePerBatchWarning": "La valeur de Temps d'exécution (en secondes) par lot doit être au moins de '%s' secondes. Affectation par défaut de la valeur minimale prise en charge.", + "loc.messages.RunTimePerBatch": "Temps d'exécution par lot (en secondes) : %s", + "loc.messages.searchLocationNotDirectory": "Dossier de recherche : '%s' doit correspondre à un répertoire existant.", + "loc.messages.rerunFailedTests": "Réexécuter les tests non réussis : %s", + "loc.messages.rerunFailedThreshold": "Seuil de réexécution des tests non réussis : %s", + "loc.messages.invalidRerunFailedThreshold": "Seuil non valide pour la réexécution des tests non réussis. Affectation de la valeur par défaut 30 %", + "loc.messages.rerunFailedTestCasesMaxLimit": "Limite maximale de réexécution des cas de test non réussis : %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "Limite non valide pour la réexécution des cas de test non réussis. Affectation de la valeur par défaut 5", + "loc.messages.rerunMaxAttempts": "Nombre maximal de tentatives de réexécution : %s", + "loc.messages.invalidRerunMaxAttempts": "Nombre maximal des tentatives de réexécution non valide/dépassé. Affectation de la valeur par défaut 3", + "loc.messages.rerunNotSupported": "Installez Visual Studio 2015 Update 3 ou Visual Studio 2017 pour réexécuter les tests non réussis.", + "loc.messages.toolsInstallerPathNotSet": "Le dossier Plateforme de test VsTest est introuvable dans le cache.", + "loc.messages.testImpactAndCCWontWork": "Le collecteur de données d'impact de test (exécuter uniquement les tests impactés) et de couverture du code ne fonctionne pas.", + "loc.messages.ToolsInstallerInstallationError": "Le programme d'installation des outils Visual Studio Test Platform ne s'est pas exécuté, ou n'a pas pu s'effectuer correctement. Pour plus d'informations sur l'utilisation du programme d'installation des outils, consultez le blog suivant : https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "Remplacement de la valeur du champ UseVerifiableInstrumentation par la valeur false dans le fichier runsettings.", + "loc.messages.NoTestResultsDirectoryFound": "Le répertoire de résultats des tests est introuvable.", + "loc.messages.OnlyWindowsOsSupported": "Cette tâche est prise en charge uniquement sur les agents Windows et ne peut pas être utilisée sur d'autres plateformes.", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "Les exécutions à la demande ne sont pas prises en charge avec l'option Multiconfiguration. Utilisez l'option de parallélisme 'Aucun' ou 'Multiagent'.", + "loc.messages.disabledRerun": "Désactivation de la réexécution des tests ayant échoué car le seuil de réexécution fourni est %s", + "loc.messages.UpgradeAgentMessage": "Mettez à niveau votre version d'agent. https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "VsTestVersion a une valeur null ou est vide", + "loc.messages.UserProvidedSourceFilter": "Filtre source : %s", + "loc.messages.UnableToGetFeatureFlag": "Impossible d'obtenir l'indicateur de fonctionnalité : %s", + "loc.messages.diagnosticsInput": "Diagnostics activés : %s", + "loc.messages.UncPathNotSupported": "Le chemin du dossier de recherche des sources de test ne doit pas être un chemin UNC. Indiquez un chemin associé à une racine ou un chemin relatif à $(System.DefaultWorkingDirectory).", + "loc.messages.LookingForBuildToolsInstalltion": "Tentative de localisation de vstest.console à partir d'une installation de Visual Studio Build Tools version %s.", + "loc.messages.LookingForVsInstalltion": "Tentative de localisation de vstest.console à partir d'une installation de Visual Studio version %s.", + "loc.messages.minTestsNotExecuted": "Le nombre minimal de tests spécifié %d n'a pas été exécuté au cours de la série de tests.", + "loc.messages.actionOnThresholdNotMet": "Action quand le seuil minimal de tests n'est pas atteint : %s", + "loc.messages.minimumExpectedTests": "Nombre minimal de tests dont l'exécution est attendue : %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Strings/resources.resjson/it-IT/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/it-IT/resources.resjson new file mode 100644 index 000000000000..614db8a5d333 --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/it-IT/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Test con Visual Studio", + "loc.helpMarkDown": "[Altre informazioni su questa attività](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "Consente di eseguire unit test e test funzionali (Selenium, Appium, test codificato dell'interfaccia utente e così via) usando Visual Studio Test (VsTest) Runner. È anche possibile eseguire i framework di test che contengono un adattatore di test di Visual Studio, come MsTest, xUnit, NUnit, Chutzpah (per test di JavaScript con QUnit, Mocha e Jasmine) e così via. Questa attività consente anche di distribuire i test in più agenti (versione 2).", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
                  • Esecuzione di test con un processo agente: grazie all'agente unificato in Compilazione, Versione e Test è possibile usare agenti di automazione anche per i test. Per distribuire i test, è possibile usare l'impostazione del processo con più agenti. È possibile usare l'impostazione del processo con più configurazioni per replicare test in configurazioni diverse. Altre informazioni
                  • Analisi di impatto test: consente di selezionare ed eseguire automaticamente solo i test necessari per convalidare la modifica al codice.
                  • Usare l'attività Programma di installazione della piattaforma di Visual Studio Test per eseguire test senza disporre di un'installazione completa di Visual Studio.
                  ", + "loc.group.displayName.testSelection": "Selezione test", + "loc.group.displayName.executionOptions": "Opzioni di esecuzione", + "loc.group.displayName.advancedExecutionOptions": "Opzioni di esecuzione avanzate", + "loc.group.displayName.reportingOptions": "Opzioni di creazione report", + "loc.input.label.testSelector": "Seleziona i test con", + "loc.input.help.testSelector": "
                  • Assembly di test: Usare questa opzione per specificare uno o più assembly di test che contengono i test. È possibile facoltativamente specificare i criteri di filtro per selezionare solo test specifici.
                  • Piano di test: Usare questa opzione per eseguire i test dal piano di test a cui è associato un metodo di test automatizzato.
                  • Esecuzione dei test: Usare questa opzione quando si configura un ambiente per eseguire i test dall'hub di test. Questa opzione non deve essere usata quando si eseguono test in una pipeline con integrazione continua/distribuzione continua (CI/CD).
                  • ", + "loc.input.label.testAssemblyVer2": "File di test", + "loc.input.help.testAssemblyVer2": "Esegue i test dai file specificati.
                    Per eseguire test ordinati e test Web, è possibile specificare rispettivamente i file con estensione orderedtest e webtest. Per eseguire file con estensione webtest, è necessario Visual Studio 2017 Update 4 o versioni successive.

                    I percorsi di file sono relativi alla cartella di ricerca. Sono supportate più righe di criteri di corrispondenza minima. [Altre informazioni](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "Piano di test", + "loc.input.help.testPlan": "Consente di selezionare un piano di test contenente gruppi di test con test case automatizzati.", + "loc.input.label.testSuite": "Gruppo di test", + "loc.input.help.testSuite": "Consente di selezionare uno o più gruppi di test contenenti test case automatizzati. Gli elementi di lavoro dei test case devono essere associati a un metodo di test automatizzato. [Altre informazioni](https://go.microsoft.com/fwlink/?linkid=847773", + "loc.input.label.testConfiguration": "Configurazione di test", + "loc.input.help.testConfiguration": "Consente di selezionare la configurazione di test.", + "loc.input.label.tcmTestRun": "Esecuzione dei test", + "loc.input.help.tcmTestRun": "La selezione basata sull'esecuzione dei test viene usata quando si attivano esecuzione dei test automatizzati dall'hub di test. Non è possibile usare questa opzione per l'esecuzione dei test nella pipeline CI/CD.", + "loc.input.label.searchFolder": "Cartella di ricerca", + "loc.input.help.searchFolder": "Cartella in cui cercare gli assembly di test.", + "loc.input.label.resultsFolder": "Cartella dei risultati dei test", + "loc.input.help.resultsFolder": "Cartella in cui archiviare i risultati dei test. Quando questo valore di input non viene specificato, per impostazione predefinita i risultati vengono archiviati in $(Agent.TempDirectory)/TestResults e tale directory viene pulita alla fine di un'esecuzione della pipeline. La directory dei risultati viene sempre pulita all'avvio dell'attività VSTest prima dell'esecuzione dei test. Se specificato, il percorso relativo della cartella verrà considerato relativo a $(Agent.TempDirectory)", + "loc.input.label.testFiltercriteria": "Criteri di filtro dei test", + "loc.input.help.testFiltercriteria": "Criteri aggiuntivi per filtrare i test negli assembly di test, ad esempio `Priority=1|Name=MyTestMethod`. [Altre informazioni](https://msdn.microsoft.com/it-it/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "Esegui solo i test interessati", + "loc.input.help.runOnlyImpactedTests": "Consente di selezionare ed eseguire automaticamente solo i test necessari per convalidare la modifica al codice. [Altre informazioni](https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "Numero di compilazioni dopo il quale devono essere eseguiti tutti i test", + "loc.input.help.runAllTestsAfterXBuilds": "Numero di compilazioni dopo il quale verranno eseguiti automaticamente tutti i test. Con Analisi di impatto test viene archiviato il mapping tra test case e codice sorgente. È consigliabile generare il mapping eseguendo periodicamente tutti i test.", + "loc.input.label.uiTests": "La combinazione di test contiene test dell'interfaccia utente", + "loc.input.help.uiTests": "Per eseguire test dell'interfaccia utente, assicurarsi che l'agente sia impostato per l'esecuzione in modalità interattiva. La configurazione di un agente per l'esecuzione in modalità interattiva deve essere eseguita prima di accodare la compilazione/versione. La selezione di questa casella non implica la configurazione automatica dell'agente in modalità interattiva. Questa opzione nell'attività funge solo da promemoria per la corretta configurazione dell'agente allo scopo di evitare errori.

                    Per eseguire test dell'interfaccia utente, è possibile usare agenti Windows ospitati dei pool di Visual Studio 2015 e 2017.
                    [Altre informazioni](https://aka.ms/uitestmoreinfo).", + "loc.input.label.vstestLocationMethod": "Seleziona la piattaforma di test con", + "loc.input.label.vsTestVersion": "Versione della piattaforma di test", + "loc.input.help.vsTestVersion": "Versione del test di Visual Studio da usare. Se viene specificata la versione più recente, viene scelta la versione più recente di Visual Studio, a partire da VS2022, seguita da VS2019, VS2017 e VS2015, a seconda della versione installata. Visual Studio 2013 non è supportato. Per eseguire test senza che nell'agente sia presente Visual Studio, usare l'opzione 'Installato dal programma di installazione degli strumenti'. Assicurarsi di includere l'attività 'Programma di installazione della piattaforma di test di Visual Studio' per acquisire la piattaforma di test da NuGet.", + "loc.input.label.vstestLocation": "Percorso di vstest.console.exe", + "loc.input.help.vstestLocation": "Consente, facoltativamente, di specificare il percorso di VSTest.", + "loc.input.label.runSettingsFile": "File di impostazioni", + "loc.input.help.runSettingsFile": "Percorso del file runsettings o testsettings da usare con i test.", + "loc.input.label.overrideTestrunParameters": "Esegui override dei parametri di esecuzione dei test", + "loc.input.help.overrideTestrunParameters": "Esegue l'override dei parametri definiti nella sezione `TestRunParameters` del file runsettings o nella sezione `Properties` del file testsettings, ad esempio: `-key1 value1 -key2 value2`. Nota: è possibile accedere alle proprietà specificate nel file testsettings tramite l'elemento TestContext usando Visual Studio 2017 Update 4 o versione successiva ", + "loc.input.label.pathtoCustomTestAdapters": "Percorso degli adattatori di test personalizzati", + "loc.input.help.pathtoCustomTestAdapters": "Percorso della directory degli adattatori di test personalizzati. Gli adattatori che si trovano nella stessa cartella degli assembly di test vengono individuati automaticamente.", + "loc.input.label.runInParallel": "Esegui test in parallelo in computer multicore", + "loc.input.help.runInParallel": "Se è impostata, i test verranno eseguiti in parallelo sfruttando i core disponibili del computer. Questa impostazione sostituisce il valore di MaxCpuCount eventualmente specificato nel file runsettings. Per altre informazioni sull'esecuzione di test in parallelo, [fare clic qui](https://aka.ms/paralleltestexecution).", + "loc.input.label.runTestsInIsolation": "Esegui test in isolamento", + "loc.input.help.runTestsInIsolation": "Esegue i test in un processo isolato. In questo modo è meno probabile che il processo vstest.console.exe venga arrestato in caso di errore nei test, che però potrebbero risultare più lenti. Non è attualmente possibile usare questa opzione durante l'esecuzione con l'impostazione del processo con più agenti.", + "loc.input.label.codeCoverageEnabled": "Code coverage abilitato", + "loc.input.help.codeCoverageEnabled": "Consente di raccogliere le informazioni sul code coverage dall'esecuzione dei test.", + "loc.input.label.otherConsoleOptions": "Altre opzioni della console", + "loc.input.help.otherConsoleOptions": "Altre opzioni della console che è possibile passare a vstest.console.exe, come documentato qui.

                    Queste opzioni non sono supportate e verranno ignorate durante l'esecuzione di test con l'impostazione 'Più agenti' in parallelo di un processo agente o durante l'esecuzione di test con l'opzione 'Piano di test' oppure l'opzione 'Esecuzione dei test' o quando è selezionata un'opzione batch personalizzata. In alternativa, è possibile specificare le opzioni con un file di impostazioni.

                    ", + "loc.input.label.distributionBatchType": "Test in batch", + "loc.input.help.distributionBatchType": "Un batch è un gruppo di test che vengono eseguiti contemporaneamente e i cui risultati vengono pubblicati. Se il processo in cui viene eseguita l'attività è impostata per l'uso di più agenti, ogni agente seleziona tutti i batch di test disponibili da eseguire in parallelo.

                    In base al numero di test e agenti: batch semplice basato sul numero di test e agenti che partecipano all'esecuzione dei test.

                    In base al tempo di esecuzione passato dei test: questo batch considera il tempo di esecuzione passato per creare batch di test in modo tale che il tempo di esecuzione sia all'incirca identico per ogni batch.

                    In base agli assembly di test: viene creato un batch con tutti i test di un assembly.", + "loc.input.label.batchingBasedOnAgentsOption": "Opzioni per batch", + "loc.input.help.batchingBasedOnAgentsOption": "Batch semplice basato sul numero di test e agenti che partecipano all'esecuzione dei test. Quando le dimensioni del batch sono determinate automaticamente, ogni batch contiene un numero di test pari a `(numero totale di test/numero di agenti)`. Se si specificano le dimensioni del batch, ogni batch conterrà il numero specificato di test.", + "loc.input.label.customBatchSizeValue": "Numero di test per batch", + "loc.input.help.customBatchSizeValue": "Consente di specificare le dimensioni del batch", + "loc.input.label.batchingBasedOnExecutionTimeOption": "Opzioni per batch", + "loc.input.help.batchingBasedOnExecutionTimeOption": "Questo batch considera il tempo di esecuzione passato per creare batch di test in modo tale che il tempo di esecuzione sia all'incirca identico per ogni batch. I test a esecuzione rapida verranno inviati in batch insieme, mentre quelli a esecuzione prolungata appartengono a batch separati. Quando si usa questa opzione con l'impostazione del processo con più agenti, il tempo di test totale viene ridotto al minimo.", + "loc.input.label.customRunTimePerBatchValue": "Tempo di esecuzione per batch (sec)", + "loc.input.help.customRunTimePerBatchValue": "Consente di specificare il tempo di esecuzione in secondi per singolo batch", + "loc.input.label.dontDistribute": "Replica i test invece di distribuire quando nel processo vengono usati più agenti", + "loc.input.help.dontDistribute": "Se si sceglie questa opzione, i test non verranno distribuiti tra gli agenti quando l'attività viene eseguita in un processo con più agenti.
                    Ognuno dei test selezionati verrà ripetuto in ogni agente.
                    L'opzione non è applicabile quando il processo agente è configurato per l'esecuzione senza parallelismo o con l'opzione per più configurazioni.", + "loc.input.label.testRunTitle": "Titolo dell'esecuzione dei test", + "loc.input.help.testRunTitle": "Consente di specificare un nome per l'esecuzione dei test.", + "loc.input.label.platform": "Piattaforma di compilazione", + "loc.input.help.platform": "Piattaforma di compilazione da usare per i test. Usare qui l'eventuale variabile definita per la piattaforma nell'attività di compilazione.", + "loc.input.label.configuration": "Configurazione della build", + "loc.input.help.configuration": "Configurazione della build da usare per i test. Usare qui l'eventuale variabile definita per la configurazione nell'attività di compilazione.", + "loc.input.label.publishRunAttachments": "Carica allegati del test", + "loc.input.help.publishRunAttachments": "Consente di acconsentire o rifiutare esplicitamente la pubblicazione degli allegati a livello di esecuzione.", + "loc.input.label.failOnMinTestsNotRun": "Non eseguire l'attività se non è stato eseguito un numero minimo di test.", + "loc.input.help.failOnMinTestsNotRun": "Se si seleziona questa opzione, l'attività non verrà eseguita se non viene eseguito il numero minimo di test specificato.", + "loc.input.label.minimumExpectedTests": "Numero minimo di test", + "loc.input.help.minimumExpectedTests": "Consente di specificare il numero minimo di test da eseguire per l'esecuzione dell'attività. Il numero totale di test eseguiti è dato dalla somma dei test superati, non superati e interrotti.", + "loc.input.label.diagnosticsEnabled": "Raccogli la diagnostica avanzata in caso di errori irreversibili", + "loc.input.help.diagnosticsEnabled": "Consente di raccogliere la diagnostica avanzata in caso di errori irreversibili.", + "loc.input.label.collectDumpOn": "Raccogli il dump di processo e allegalo al report di esecuzione dei test", + "loc.input.help.collectDumpOn": "Consente di raccogliere il dump di processo e di allegarlo al report di esecuzione dei test.", + "loc.input.label.rerunFailedTests": "Ripeti i test non superati", + "loc.input.help.rerunFailedTests": "Se si seleziona questa opzione, eventuali test non riusciti verranno ripetuti finché non vengono superati o finché non viene raggiunto il numero massimo di tentativi di ripetizione.", + "loc.input.label.rerunType": "Non ripetere i test se viene superata la soglia specificata per quelli non superati", + "loc.input.help.rerunType": "Usare questa opzione per evitare di ripetere i test quando la percentuale di errori raggiunge la soglia specificata. È applicabile se eventuali problemi nell'ambiente causano un numero elevato di errori.
                    Come soglia è possibile specificare la percentuale di errori o il numero di test non superati.", + "loc.input.label.rerunFailedThreshold": "Percentuale di errori", + "loc.input.help.rerunFailedThreshold": "Usare questa opzione per evitare di ripetere i test quando la percentuale di errori raggiunge la soglia specificata. È applicabile se eventuali problemi nell'ambiente causano un numero elevato di errori.", + "loc.input.label.rerunFailedTestCasesMaxLimit": "Numero di test non superati", + "loc.input.help.rerunFailedTestCasesMaxLimit": "Usare questa opzione per evitare di ripetere i test quando il numero di test case non superati raggiunge il limite specificato. È applicabile se eventuali problemi nell'ambiente causano un numero elevato di errori.", + "loc.input.label.rerunMaxAttempts": "Numero massimo di tentativi", + "loc.input.help.rerunMaxAttempts": "Consente di specificare il numero massimo di tentativi di ripetizione di un test non superato. Se un test viene superato prima che venga raggiunto il numero massimo di tentativi, non verrà ripetuto ulteriormente.", + "loc.messages.VstestLocationDoesNotExist": "Il percorso specificato di 'vstest.console.exe' '%s' non esiste.", + "loc.messages.VstestFailedReturnCode": "L'attività VsTest non è riuscita.", + "loc.messages.VstestPassedReturnCode": "L'attività VsTest è riuscita.", + "loc.messages.NoMatchingTestAssemblies": "Non sono stati trovati assembly di test corrispondenti al criterio %s.", + "loc.messages.VstestNotFound": "Visual Studio %d non è stato trovato. Riprovare con una versione esistente nel computer dell'agente di compilazione.", + "loc.messages.NoVstestFound": "La piattaforma di test non è stata trovata. Riprovare dopo averla installata nel computer dell'agente di compilazione.", + "loc.messages.VstestFailed": "Vstest non è riuscito e sono stati restituiti errori. Per gli errori, vedere i log. Potrebbero esserci anche test non superati.", + "loc.messages.VstestTIANotSupported": "Per eseguire Analisi di impatto test, installare Visual Studio 2015 Update 3 o Visual Studio 2017 RC.", + "loc.messages.NoResultsToPublish": "Non sono stati trovati risultati da pubblicare.", + "loc.messages.ErrorWhileReadingRunSettings": "Si è verificato un errore durante la lettura del file delle impostazioni esecuzione test. Errore: %s.", + "loc.messages.ErrorWhileReadingTestSettings": "Si è verificato un errore durante la lettura del file delle impostazioni test. Errore: %s.", + "loc.messages.RunInParallelNotSupported": "Con il file testsettings non è possibile eseguire test in parallelo in computer multicore. Questa opzione verrà ignorata.", + "loc.messages.InvalidSettingsFile": "Il file di impostazioni specificato %s non è valido o non esiste. Specificare un file di impostazioni valido o deselezionare il campo.", + "loc.messages.UpdateThreeOrHigherRequired": "Per eseguire i test in parallelo, installare Visual Studio 2015 Update 3 o versione successiva nella macchina virtuale dell'agente di compilazione.", + "loc.messages.ErrorOccuredWhileSettingRegistry": "Si è verificato un errore durante l'impostazione della chiave del Registro di sistema. Errore: %s.", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "Si è verificato un errore durante l'impostazione di Agente di raccolta impatto test nel file delle impostazioni test.", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "Si è verificato un errore durante l'impostazione di Agente di raccolta impatto test nel file delle impostazioni esecuzione test.", + "loc.messages.ErrorWhileCreatingResponseFile": "Si è verificato un errore durante la creazione del file di risposta. Verranno eseguiti tutti i test per questa esecuzione.", + "loc.messages.ErrorWhileUpdatingResponseFile": "Si è verificato un errore durante l'aggiornamento del file di risposta '%s'. Verranno eseguiti tutti i test per questa esecuzione.", + "loc.messages.ErrorWhilePublishingCodeChanges": "Si è verificato un errore durante la pubblicazione delle modifiche apportate al codice. Verranno eseguiti tutti i test per questa esecuzione.", + "loc.messages.ErrorWhileListingDiscoveredTests": "Si è verificato un errore durante l'individuazione dei test. Verranno eseguiti tutti i test per questa esecuzione.", + "loc.messages.PublishCodeChangesPerfTime": "Tempo totale necessario per pubblicare le modifiche apportate al codice: %d millisecondi.", + "loc.messages.GenerateResponseFilePerfTime": "Tempo totale necessario per ottenere il file di risposta: %d millisecondi.", + "loc.messages.UploadTestResultsPerfTime": "Tempo totale necessario per caricare i risultati dei test: %d millisecondi.", + "loc.messages.ErrorReadingVstestVersion": "Si è verificato un errore durante la lettura della versione di vstest.console.exe.", + "loc.messages.UnexpectedVersionString": "È stata rilevata una stringa di versione imprevista per vstest.console.exe: %s.", + "loc.messages.UnexpectedVersionNumber": "È stato rilevato un numero di versione imprevisto per vstest.console.exe: %s.", + "loc.messages.VstestDiagNotSupported": "La versione di vstest.console.exe non supporta il flag /diag. Abilitare la diagnostica tramite i file exe.config", + "loc.messages.NoIncludePatternFound": "Non sono stati trovati criteri di inclusione. Specificare almeno un criterio per eseguire ricerche negli assembly di test.", + "loc.messages.ErrorWhileUpdatingSettings": "Si è verificato un errore durante l'aggiornamento del file di impostazioni. Verrà usato il file specificato.", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "Video collector non è supportato con le impostazioni esecuzione test.", + "loc.messages.runTestInIsolationNotSupported": "L'esecuzione di test in isolamento non è supportata quando si usa l'impostazione del processo con più agenti. Questa opzione verrà ignorata.", + "loc.messages.overrideNotSupported": "L'override dei parametri di esecuzione dei test è supportato solo con un file runsettings o testsettings valido. Questa opzione verrà ignorata.", + "loc.messages.testSettingPropertiesNotSupported": "È possibile accedere alle proprietà specificate nel file testsettings tramite l'elemento TestContext usando Visual Studio 2017 Update 4 o versione successiva", + "loc.messages.vstestVersionInvalid": "La versione specificata %s della piattaforma di test non è supportata.", + "loc.messages.configureDtaAgentFailed": "La configurazione dell'agente di test con il server non è riuscita anche dopo %d tentativi. Errore: %s", + "loc.messages.otherConsoleOptionsNotSupported": "Le altre opzioni della console non sono supportate per questa configurazione di attività. Questa opzione verrà ignorata.", + "loc.messages.distributedTestWorkflow": "Nel flusso di test distribuito", + "loc.messages.nonDistributedTestWorkflow": "Esecuzione dei test con lo strumento di esecuzione attività vstest.console.exe.", + "loc.messages.dtaNumberOfAgents": "Esecuzione dei test distribuiti. Numero di agenti nel processo: %s", + "loc.messages.testSelectorInput": "Selettore test: %s", + "loc.messages.searchFolderInput": "Cartella di ricerca: %s", + "loc.messages.testFilterCriteriaInput": "Criteri di filtro dei test: %s", + "loc.messages.runSettingsFileInput": "File di impostazioni esecuzione test: %s", + "loc.messages.runInParallelInput": "Esegui in parallelo: %s", + "loc.messages.runInIsolationInput": "Esegui in isolamento: %s", + "loc.messages.pathToCustomAdaptersInput": "Percorso degli adattatori personalizzati: %s", + "loc.messages.otherConsoleOptionsInput": "Altre opzioni della console: %s", + "loc.messages.codeCoverageInput": "Code coverage abilitato: %s", + "loc.messages.testPlanInput": "ID piano di test: %s", + "loc.messages.testplanConfigInput": "ID configurazione piano di test: %s", + "loc.messages.testSuiteSelected": "ID gruppo di test selezionato: %s", + "loc.messages.testAssemblyFilterInput": "Assembly di test: %s", + "loc.messages.vsVersionSelected": "Versione di Visual Studio selezionata per l'esecuzione dei test: %s", + "loc.messages.runTestsLocally": "Eseguire i test in locale con %s", + "loc.messages.vstestLocationSpecified": "%s. Posizione specificata: %s", + "loc.messages.uitestsparallel": "L'esecuzione di test dell'interfaccia utente in parallelo nello stesso computer può comportare errori. Provare a disabilitare l'opzione 'Esegui in parallelo' o a eseguire i test dell'interfaccia utente con un'attività separata. Per altre informazioni, vedere https://aka.ms/paralleltestexecution ", + "loc.messages.pathToCustomAdaptersInvalid": "Il percorso degli adattatori personalizzati '%s' deve essere una directory e deve essere già esistente.", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "Il percorso degli adattatori personalizzati '%s' non contiene alcun adattatore di test. Specificare un percorso valido.", + "loc.messages.testAssembliesSelector": "Assembly di test", + "loc.messages.testPlanSelector": "Piano di test", + "loc.messages.testRunSelector": "Esecuzione dei test", + "loc.messages.testRunIdInvalid": "La selezione test è 'Esecuzione dei test', ma l'ID esecuzione dei test specificato '%s' non è valido", + "loc.messages.testRunIdInput": "ID esecuzione dei test: '%s'", + "loc.messages.testSourcesFilteringFailed": "La preparazione del file delle origini test non è riuscita. Errore: %s", + "loc.messages.noTestSourcesFound": "Non sono state trovate origini test corrispondenti al filtro specificato '%s'", + "loc.messages.DontShowWERUIDisabledWarning": "Il valore DontShowUI di Segnalazione errori Windows non è impostato. Se durante l'esecuzione del test dell'interfaccia utente viene visualizzata la finestra di dialogo di errore di Windows, il test si bloccherà", + "loc.messages.noVstestConsole": "I test non verranno eseguiti con la console VSTest. Per eseguire i test tramite tale console, installare Visual Studio 2017 RC o versione successiva.", + "loc.messages.numberOfTestCasesPerSlice": "Numero di test case per batch: %s", + "loc.messages.invalidTestBatchSize": "Le dimensioni specificate per il batch non sono valide: %s", + "loc.messages.invalidRunTimePerBatch": "Il valore di 'Tempo di esecuzione per batch (sec)' non è valido: %s", + "loc.messages.minimumRunTimePerBatchWarning": "Il valore di 'Tempo di esecuzione per batch (sec)' deve essere pari ad almeno '%s' secondi. Per impostazione predefinita, verrà usato il valore minimo supportato.", + "loc.messages.RunTimePerBatch": "Tempo di esecuzione per batch (sec): %s", + "loc.messages.searchLocationNotDirectory": "La cartella ricerche '%s' deve essere una directory e deve essere già esistente.", + "loc.messages.rerunFailedTests": "Ripeti i test non superati: %s", + "loc.messages.rerunFailedThreshold": "Soglia per la ripetizione dei test non superati: %s", + "loc.messages.invalidRerunFailedThreshold": "La soglia per la ripetizione dei test non superati non è valida. Verrà usato il valore predefinito 30%", + "loc.messages.rerunFailedTestCasesMaxLimit": "Limite massimo per la ripetizione dei test case non superati: %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "Il limite per la ripetizione dei test case non superati non è valido. Verrà usato il valore predefinito 5", + "loc.messages.rerunMaxAttempts": "Numero massimo di tentativi di ripetizione: %s", + "loc.messages.invalidRerunMaxAttempts": "Il numero massimo di tentativi di ripetizione non è valido o è stato superato. Verrà usato il valore predefinito 3", + "loc.messages.rerunNotSupported": "Per ripetere i test non superati, installare Visual Studio 2015 Update 3 o Visual Studio 2017.", + "loc.messages.toolsInstallerPathNotSet": "La cartella della piattaforma di test di VsTest non è stata trovata nella cache.", + "loc.messages.testImpactAndCCWontWork": "L'agente di raccolta dati di Impatto test (Esegui solo test interessati) e Code coverage non funzionerà.", + "loc.messages.ToolsInstallerInstallationError": "Il programma di installazione degli strumenti della piattaforma di Visual Studio Test non è stato eseguito oppure l'installazione non è stata completata. Vedere il blog seguente per informazioni su come usare il programma di installazione degli strumenti: https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "Verrà eseguito l'override del campo UseVerifiableInstrumentation su false nel file runsettings.", + "loc.messages.NoTestResultsDirectoryFound": "La directory dei risultati test non è stata trovata.", + "loc.messages.OnlyWindowsOsSupported": "Questa attività è supportata solo in agenti Windows e non può essere usata su altre piattaforme.", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "Le esecuzioni su richiesta non sono supportate con l'opzione Più configurazioni. Usare l'opzione di parallelismo 'Nessuno' o 'Più agenti'.", + "loc.messages.disabledRerun": "La ripetizione dei test non superati verrà disabilitata perché la soglia di ripetizione specificata è %s", + "loc.messages.UpgradeAgentMessage": "Aggiornare la versione dell'agente. https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "VsTestVersion è Null o vuoto", + "loc.messages.UserProvidedSourceFilter": "Filtro di origine: %s", + "loc.messages.UnableToGetFeatureFlag": "Non è possibile ottenere il flag di funzionalità: %s", + "loc.messages.diagnosticsInput": "Diagnostica abilitata: %s", + "loc.messages.UncPathNotSupported": "Il percorso della cartella di ricerca delle origini di test non può essere un percorso UNC. Specificare un percorso completo o un percorso relativo a $(System.DefaultWorkingDirectory).", + "loc.messages.LookingForBuildToolsInstalltion": "Verrà effettuato un tentativo per trovare il file vstest.console di un'installazione di Visual Studio Build Tools versione %s.", + "loc.messages.LookingForVsInstalltion": "Verrà effettuato un tentativo per trovare il file vstest.console di un'installazione di Visual Studio versione %s.", + "loc.messages.minTestsNotExecuted": "Nell'esecuzione dei test non è stato eseguito il numero minimo specificato di test, pari a %d.", + "loc.messages.actionOnThresholdNotMet": "Azione da eseguire quando la soglia minima dei test non viene soddisfatta: %s", + "loc.messages.minimumExpectedTests": "Numero minimo di test da eseguire: %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Strings/resources.resjson/ja-JP/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/ja-JP/resources.resjson new file mode 100644 index 000000000000..3ac1c6217d67 --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/ja-JP/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Visual Studio テスト", + "loc.helpMarkDown": "[このタスクの詳細を表示](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "Visual Studio Test (VsTest) ランナーを使用して、ユニット テストおよび機能テスト (Selenium、Appium、コード化された UI テストなど) を実行します。MsTest、xUnit、NUnit、Chutzpah (QUnit、Mocha、Jasmine を使用した JavaScript テスト向け) などの Visual Studio テスト アダプターを持つテスト フレームワークを実行できます。テストは、このタスク (バージョン 2) を使用して複数のエージェント上で配布できます。", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
                    • エージェント ジョブを使用したテストの実行: ビルド、リリース、テストの統合エージェントでは、テスト用に自動化エージェントを使用することもできます。複数エージェント ジョブ設定を使用してテストを分散できます。複数構成ジョブ設定は、さまざまな構成でテストを複製するために使用できます。詳細情報
                    • テストの影響分析: コード変更を検証するために必要なテストのみを自動的に選択し、実行します。
                    • Visual Studio テスト プラットフォーム インストーラー タスクを使用すると、完全な Visual Studio インストールなしでテストを実行できます。
                    ", + "loc.group.displayName.testSelection": "テストの選択", + "loc.group.displayName.executionOptions": "実行オプション", + "loc.group.displayName.advancedExecutionOptions": "実行の詳細設定のオプション", + "loc.group.displayName.reportingOptions": "レポートのオプション", + "loc.input.label.testSelector": "次を使用してテストを選択", + "loc.input.help.testSelector": "
                    • テスト アセンブリ: テストの入った 1 つ以上のテスト アセンブリを指定するためのオプションです。特定のテストだけを選択するためにフィルター条件を指定することもできます (省略可能)。
                    • テスト計画: 自動テスト メソッドが関連付けられているテスト計画からテストを実行するためのオプションです。
                    • テストの実行: テスト ハブからテストを実行するための環境をセットアップしているときに使用するオプションです。このオプションは、継続的インテグレーション/継続的デプロイ (CI/CD) パイプラインでテストを実行しているときには使用しないでください。
                    • ", + "loc.input.label.testAssemblyVer2": "テスト ファイル", + "loc.input.help.testAssemblyVer2": "指定されたファイルからテストを実行します。
                      順序指定テストおよび Web テストは、それぞれ .orderedtest ファイルおよび .webtest ファイルを指定すれば実行できます。.webtest を実行するには、Visual Studio 2017 Update 4 以降が必要です。

                      ファイル パスは検索フォルダーからの相対パスです。minimatch パターンの複数行をサポートします。[詳細情報](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "テスト計画", + "loc.input.help.testPlan": "テスト スイートが自動テスト ケースと共に含まれているテスト計画を選択します。", + "loc.input.label.testSuite": "テスト スイート", + "loc.input.help.testSuite": "自動テスト ケースが含まれている 1 つ以上のテスト スイートを選択します。テスト ケース作業項目は、自動テスト メソッドに関連付ける必要があります。[詳細情報](https://go.microsoft.com/fwlink/?linkid=847773)", + "loc.input.label.testConfiguration": "テスト構成", + "loc.input.help.testConfiguration": "テスト構成を選択します。", + "loc.input.label.tcmTestRun": "テストの実行", + "loc.input.help.tcmTestRun": "テストの実行に基づく選択は、テスト ハブから自動テストの実行をトリガーする場合に使用されます。このオプションは、CI/CD パイプラインでのテスト実行には使用できません。", + "loc.input.label.searchFolder": "検索フォルダー", + "loc.input.help.searchFolder": "テスト アセンブリを検索するフォルダー。", + "loc.input.label.resultsFolder": "テスト結果フォルダー", + "loc.input.help.resultsFolder": "テスト結果を保存するフォルダー。この入力が指定されていない場合、結果は既定で $(Agent.TempDirectory)/TestResults に保存され、これはパイプライン実行の終了時に消去されます。結果のディレクトリは、vstest タスクの開始時、テストが実行される前に必ずクリーンアップされます。フォルダーの相対パスが指定された場合は、$(Agent.TempDirectory) からの相対指定と見なされます", + "loc.input.label.testFiltercriteria": "テストのフィルター条件", + "loc.input.help.testFiltercriteria": "テスト アセンブリからのテストをフィルター処理する追加条件。例: `Priority=1|Name=MyTestMethod`。[詳細](https://msdn.microsoft.com/ja-JP/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "影響を受けたテストのみ実行する", + "loc.input.help.runOnlyImpactedTests": "コードの変更を検証する必要のあるテストのみが自動的に選択され、実行されます。[詳細情報](https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "すべてのテストを実行するまでのビルド数", + "loc.input.help.runAllTestsAfterXBuilds": "すべてのテストを自動的に実行するまでのビルド数。テスト インパクト 分析には、テスト ケースとソース コードの間のマッピングが格納されます。定期的にすべてのテストを実行して、マッピングを生成しなおすことをお勧めします。", + "loc.input.label.uiTests": "テスト ミックスに UI テストが含まれています", + "loc.input.help.uiTests": "UI テストを実行するには、エージェントが対話モードで実行されるように設定されていることを確認します。ビルド/リリースをキューに登録する前に、エージェントを対話的に実行する設定を行う必要があります。このチェック ボックスをオンにしても、エージェントは自動的に対話モードに設定されません。タスクのこのオプションは、エラーを回避するためにエージェントを適切に構成するリマインダーとしてのみ使えます。

                      VS 2015 と 2017 プールからの Hosted Windows エージェントを、UI テストを実行するために使用できます。
                      [詳細情報](https://aka.ms/uitestmoreinfo)。", + "loc.input.label.vstestLocationMethod": "次を使用してテスト プラットフォームを選択", + "loc.input.label.vsTestVersion": "テスト プラットフォームのバージョン", + "loc.input.help.vsTestVersion": "使用する Visual Studio テストのバージョンです。最新バージョンが指定されている場合、インストールされているバージョンに応じて、VS2022、VS2019、VS2017、VS2015 の順に選択されます。Visual Studio 2013 はサポートされていません。エージェントで Visual Studio を必要とせずにテストを実行するには、[ツール インストーラーを使用してインストール済み] オプションを使用します。NuGet からテスト プラットフォームを取得するには、[Visual Studio テスト プラットフォーム インストーラー] タスクを含めてください。", + "loc.input.label.vstestLocation": "vstest.console.exe へのパス", + "loc.input.help.vstestLocation": "必要に応じて、VSTest へのパスを指定します。", + "loc.input.label.runSettingsFile": "設定ファイル", + "loc.input.help.runSettingsFile": "テストで使用する runsettings または testsettings ファイルへのパス。", + "loc.input.label.overrideTestrunParameters": "テストの実行パラメーターのオーバーライド", + "loc.input.help.overrideTestrunParameters": "runsettings ファイルの `TestRunParameters` セクションまたは testsettings ファイルの `Properties` セクションで定義されたパラメーターを無視オーバーライドします。例: `-key1 value1 -key2 value2`。注: testsettings ファイルで指定されたプロパティには、Visual Studio 2017 Update 4 以降で TestContext を使用してアクセスできます ", + "loc.input.label.pathtoCustomTestAdapters": "カスタム テスト アダプターへのパス", + "loc.input.help.pathtoCustomTestAdapters": "カスタム テスト アダプターへのディレクトリ パス。テスト アセンブリと同じフォルダー内のアダプターが自動的に検出されます。", + "loc.input.label.runInParallel": "マルチコア マシンでテストを並列実行する", + "loc.input.help.runInParallel": "設定すると、テストはマシンの使用可能なコアを並列利用して実行されます。これは、RunSettings ファイル内で指定されている MaxCpuCount をオーバーライドします (指定されている場合)。[ここをクリック](https://aka.ms/paralleltestexecution) してテストの並列実行の詳細をご確認ください。", + "loc.input.label.runTestsInIsolation": "テストを分離して実行する", + "loc.input.help.runTestsInIsolation": "分離プロセスでテストを実行します。これにより、vstest.console.exe プロセスがテスト中のエラーで停止する可能性は低くなりますが、テストの実行が遅くなる可能性があります。このオプションは現在、マルチエージェント ジョブ設定で実行する際には使用できません。", + "loc.input.label.codeCoverageEnabled": "コード カバレッジ有効", + "loc.input.help.codeCoverageEnabled": "テストの実行でコード カバレッジ情報を収集します。", + "loc.input.label.otherConsoleOptions": "その他のコンソールのオプション", + "loc.input.help.otherConsoleOptions": "vstest.console.exe に渡すことのできるその他のコンソール オプションの説明については、こちらをご覧ください。

                      エージェント ジョブの '複数エージェント' 並列設定を使ってテストを実行している場合、[テスト計画] または [テストの実行] オプションを使ってテストを実行している場合、カスタム バッチ処理オプションが選択されている場合は、これらのオプションはサポートされず、無視されます。代わりに、これらのオプションは設定ファイルを使って指定することができます。

                      ", + "loc.input.label.distributionBatchType": "バッチ テスト", + "loc.input.help.distributionBatchType": "バッチはテストのグループです。テストのバッチによってそのテストが同時に実行され、バッチの結果が公開されます。タスクを実行するジョブが複数のエージェントを使用するように設定されている場合、各エージェントにより、並列で実行される利用可能なテストのバッチが選択されます。

                      テストとエージェントの数に基づく: テストの実行に参加するテストとエージェントの数に基づき、単純にバッチにまとめます。

                      テストの過去の実行時間に基づく: このバッチ処理では、テストのバッチを作成するために要した過去の実行時間を考慮に入れて、各バッチの実行時間がほぼ等しくなるようにします。

                      テスト アセンブリに基づく: 1 つのアセンブリからのテストが一緒にバッチにまとめられます。", + "loc.input.label.batchingBasedOnAgentsOption": "バッチ オプション", + "loc.input.help.batchingBasedOnAgentsOption": "テストの数と、テストの実行に参加するエージェントの数に基づいたシンプルなバッチ処理。バッチのサイズを自動的に決定する場合、各バッチには `(テストの合計数 / エージェントの数)` 件のテストが入ります。バッチのサイズを指定する場合、各バッチには指定した数のテストが入ります。", + "loc.input.label.customBatchSizeValue": "バッチあたりのテスト数", + "loc.input.help.customBatchSizeValue": "バッチのサイズを指定します", + "loc.input.label.batchingBasedOnExecutionTimeOption": "バッチ オプション", + "loc.input.help.batchingBasedOnExecutionTimeOption": "このバッチ処理では、過去の実行時間を検討して、各バッチの実行時間がほぼ同じになるようにテストのバッチを作成します。実行時間の短いテストがまとめてバッチに組み込まれ、実行時間の長いテストは別々のバッチに組み込まれます。このオプションを複数エージェントのジョブ設定と一緒に使うと、テストの合計時間が最短になります。", + "loc.input.label.customRunTimePerBatchValue": "バッチあたりの実行時間 (秒)", + "loc.input.help.customRunTimePerBatchValue": "バッチあたりの実行時間 (秒) を指定します", + "loc.input.label.dontDistribute": "ジョブ内で複数のエージェントを使う場合は、テストを配布するのではなく、レプリケートしてください", + "loc.input.help.dontDistribute": "このオプションを選択すると、タスクが複数エージェントのフェーズで実行される場合に、テストがエージェント間に配布されなくなります。
                      選択された各テストは、各エージェント上で反復されます。
                      このオプションは、エージェントのフェーズが並列処理なしで実行されるように、または複数の構成オプションを指定して実行されるように構成された場合には適用されません。", + "loc.input.label.testRunTitle": "テストの実行のタイトル", + "loc.input.help.testRunTitle": "テストの実行の名前を指定します。", + "loc.input.label.platform": "ビルド プラットフォーム", + "loc.input.help.platform": "テストを報告する対象となるビルド プラットフォーム。ビルド タスク内にプラットフォームの変数を定義した場合には、ここで使用します。", + "loc.input.label.configuration": "ビルド構成", + "loc.input.help.configuration": "テストを報告する対象となるビルド構成。ビルド タスク内に構成の変数を定義した場合、ここでそれを使用します。", + "loc.input.label.publishRunAttachments": "テストの添付ファイルのアップロード", + "loc.input.help.publishRunAttachments": "実行レベルの添付ファイルの発行をオプトイン/オプトアウトします。", + "loc.input.label.failOnMinTestsNotRun": "最小数のテストが実行されない場合にタスクを失敗させます。", + "loc.input.help.failOnMinTestsNotRun": "このオプションを選択すると、指定された最小数のテストが実行されていない場合にタスクが失敗します。", + "loc.input.label.minimumExpectedTests": "テストの最小数", + "loc.input.help.minimumExpectedTests": "タスクを成功させるために実行する必要のあるテストの最小数を指定します。実行されたテストの合計は、成功、失敗、中止されたテストの合計として計算されます。", + "loc.input.label.diagnosticsEnabled": "致命的なエラーが発生した場合に、高度な診断情報を収集する", + "loc.input.help.diagnosticsEnabled": "致命的なエラーが発生した場合に高度な診断情報を収集します。", + "loc.input.label.collectDumpOn": "プロセスのダンプを収集し、テストの実行レポートに添付する", + "loc.input.help.collectDumpOn": "プロセスのダンプを収集し、テストの実行レポートに添付します。", + "loc.input.label.rerunFailedTests": "失敗したテストの再実行", + "loc.input.help.rerunFailedTests": "このオプションを選択すると、合格するか最大試行回数に達するまで、失敗したテストを再実行します。", + "loc.input.label.rerunType": "テスト失敗回数が指定のしきい値を超えるときには再実行しない", + "loc.input.help.rerunType": "エラーの発生率が指定したしきい値を超えたときにテストの再実行を回避するには、このオプションを使用します。これは、環境の問題が大規模な障害の発生につながる場合に適用されます。
                      しきい値としてはエラーになったテストの発生率または発生数を指定できます。", + "loc.input.label.rerunFailedThreshold": "失敗の割合", + "loc.input.help.rerunFailedThreshold": "エラーの発生率が指定したしきい値を超えたときにテストの再実行を回避するには、このオプションを使用します。これは、環境の問題が大規模な障害の発生につながる場合に適用されます。", + "loc.input.label.rerunFailedTestCasesMaxLimit": "失敗したテストの数", + "loc.input.help.rerunFailedTestCasesMaxLimit": "失敗したテスト ケースの数が指定した制限を超えたときにテストの再実行を回避するには、このオプションを使用します。これは、環境の問題が大規模な障害の発生につながる場合に適用されます。", + "loc.input.label.rerunMaxAttempts": "最大試行回数", + "loc.input.help.rerunMaxAttempts": "失敗したテストの最大試行回数を指定します。最大試行回数に達する前にテストに合格すると、それ以上は再実行しません。", + "loc.messages.VstestLocationDoesNotExist": "'vstest.console.exe' が指定された '%s' の場所が存在しません。", + "loc.messages.VstestFailedReturnCode": "VsTest タスクが失敗しました。", + "loc.messages.VstestPassedReturnCode": "VsTest タスクが成功しました。", + "loc.messages.NoMatchingTestAssemblies": "パターン %s に一致するテスト アセンブリが見つかりませんでした。", + "loc.messages.VstestNotFound": "Visual Studio %d が見つかりません。ビルド エージェント マシンにあるバージョンでもう一度お試しください。", + "loc.messages.NoVstestFound": "テスト プラットフォームが見つかりません。ビルド エージェント マシンにインストールしてから、もう一度お試しください。", + "loc.messages.VstestFailed": "Vstest でエラーが発生しました。ログでエラーをご確認ください。失敗したテストがある可能性があります。", + "loc.messages.VstestTIANotSupported": "テスト インパクト 解析を実行するには、Visual Studio 2015 update 3 または Visual Studio 2017 RC 以降をインストールします。", + "loc.messages.NoResultsToPublish": "公開する結果が見つかりませんでした。", + "loc.messages.ErrorWhileReadingRunSettings": "実行設定ファイルの読み取り中にエラーが発生しました。エラー: %s。", + "loc.messages.ErrorWhileReadingTestSettings": "テストの設定ファイルの読み取り中にエラーが発生しました。エラー: %s。", + "loc.messages.RunInParallelNotSupported": "testsettings ファイルでは、マルチコア マシンでのテストの並列実行はサポートされていません。このオプションは無視されます。", + "loc.messages.InvalidSettingsFile": "指定された設定ファイル %s が無効か、存在していません。有効な設定ファイルを指定するか、フィールドをクリアしてください。", + "loc.messages.UpdateThreeOrHigherRequired": "並列でテストを実行するには、ビルド エージェント マシンに Visual Studio 2015 Update 3 以降をインストールしてください。", + "loc.messages.ErrorOccuredWhileSettingRegistry": "レジストリ キーの設定中にエラーが発生しました。エラー: %s。", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "テスト設定ファイルでテスト インパクト コレクターの設定中にエラーが発生しました。", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "実行設定ファイルでテスト インパクト コレクターの設定中にエラーが発生しました。", + "loc.messages.ErrorWhileCreatingResponseFile": "応答ファイルの作成中にエラーが発生しました。この実行に対してすべてのテストが実行されます。", + "loc.messages.ErrorWhileUpdatingResponseFile": "応答ファイル '%s' の更新中にエラーが発生しました。この実行に対してすべてのテストが実行されます。", + "loc.messages.ErrorWhilePublishingCodeChanges": "コード変更の公開中にエラーが発生しました。この実行についてはすべてのテストが実行されます。", + "loc.messages.ErrorWhileListingDiscoveredTests": "テストの検出中にエラーが発生しました。この実行では、すべてのテストが実行されます。", + "loc.messages.PublishCodeChangesPerfTime": "コード変更の公開にかかった合計時間: %d ミリ秒。", + "loc.messages.GenerateResponseFilePerfTime": "応答ファイルの取得にかかった合計時間: %d ミリ秒。", + "loc.messages.UploadTestResultsPerfTime": "テスト結果をアップロードするのにかかった合計時間: %d ミリ秒。", + "loc.messages.ErrorReadingVstestVersion": "vstest.console.exe のバージョンの読み取りエラーです。", + "loc.messages.UnexpectedVersionString": "vstest.console.exe で予期しないバージョン文字列が検出されました: %s。", + "loc.messages.UnexpectedVersionNumber": "vstest.console.exe で予期しないバージョン番号が検出されました: %s。", + "loc.messages.VstestDiagNotSupported": "vstest.console.exe バージョンは /diag フラグをサポートしていません。exe.config ファイルから診断を有効にします", + "loc.messages.NoIncludePatternFound": "インクルード パターンが見つかりませんでした。テスト アセンブリを検索するインクルード パターンを少なくとも 1 つ指定してください。", + "loc.messages.ErrorWhileUpdatingSettings": "設定ファイルの更新中にエラーが発生しました。指定された設定ファイルを使用しています。", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "実行設定で Video collector はサポートされていません。", + "loc.messages.runTestInIsolationNotSupported": "複数エージェント ジョブ設定を使用する場合、テストの分離実行はサポートされていません。このオプションは無視されます。", + "loc.messages.overrideNotSupported": "テストの実行パラメーターの無視は有効な runsettings ファイルまたは testsettings ファイルでのみサポートされています。このオプションは無視されます。", + "loc.messages.testSettingPropertiesNotSupported": "testsettings ファイルに指定されたプロパティには、Visual Studio 2017 Update 4 以降で TestContext を使用してアクセスできます", + "loc.messages.vstestVersionInvalid": "指定されたテスト プラットフォームのバージョン %s はサポートされていません。", + "loc.messages.configureDtaAgentFailed": "サーバーでのテスト エージェントの構成を %d 回試行しましたが、エラー %s で失敗しました", + "loc.messages.otherConsoleOptionsNotSupported": "このタスク構成では、他のコンソール オプションはサポートされていません。このオプションは無視されます。", + "loc.messages.distributedTestWorkflow": "配布されたテスト フローで", + "loc.messages.nonDistributedTestWorkflow": "vstest.console.exe ランナーを使用してテストを実行しています。", + "loc.messages.dtaNumberOfAgents": "配布されたテスト実行で、ジョブ内のエージェントの数: %s", + "loc.messages.testSelectorInput": "テスト セレクター: %s", + "loc.messages.searchFolderInput": "検索フォルダー: %s", + "loc.messages.testFilterCriteriaInput": "テスト フィルターの条件: %s", + "loc.messages.runSettingsFileInput": "実行設定ファイル: %s", + "loc.messages.runInParallelInput": "並列で実行: %s", + "loc.messages.runInIsolationInput": "別々に実行: %s", + "loc.messages.pathToCustomAdaptersInput": "カスタム アダプターへのパス: %s", + "loc.messages.otherConsoleOptionsInput": "その他のコンソール オプション: %s", + "loc.messages.codeCoverageInput": "コード カバレッジが有効になりました: %s", + "loc.messages.testPlanInput": "テスト計画 ID: %s", + "loc.messages.testplanConfigInput": "テスト計画構成 ID: %s", + "loc.messages.testSuiteSelected": "選択されたテスト スイート ID: %s", + "loc.messages.testAssemblyFilterInput": "テスト アセンブリ: %s", + "loc.messages.vsVersionSelected": "テストの実行用に選択された Visual Studio のバージョン: %s", + "loc.messages.runTestsLocally": "%s を使ってローカルでテストを実行", + "loc.messages.vstestLocationSpecified": "%s、指定された場所: %s", + "loc.messages.uitestsparallel": "同じマシン上で並列に UI テストを実行すると、エラーが発生することがあります。[並列で実行] オプションを無効にするか、別のタスクを使って UI テストを実行することを検討してください。詳細については、https://aka.ms/paralleltestexecution をご覧ください ", + "loc.messages.pathToCustomAdaptersInvalid": "カスタム アダプター '%s' へのパスは存在し、ディレクトリでなければなりません。", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "カスタム アダプター '%s' へのパスにはテスト アダプターが含まれていません。有効なパスを指定してください。", + "loc.messages.testAssembliesSelector": "テスト アセンブリ", + "loc.messages.testPlanSelector": "テスト計画", + "loc.messages.testRunSelector": "テストの実行", + "loc.messages.testRunIdInvalid": "テストの選択は [テストの実行] ですが、指定されているテストの実行 ID '%s' が無効です", + "loc.messages.testRunIdInput": "テストの実行 ID: '%s'", + "loc.messages.testSourcesFilteringFailed": "テスト ソース ファイルの準備に失敗しました。エラー: %s", + "loc.messages.noTestSourcesFound": "指定されたフィルター '%s' に一致するテスト ソースが見つかりません", + "loc.messages.DontShowWERUIDisabledWarning": "テストがハングするのではなく、Windows のエラー ダイアログが UI テストの実行中にポップアップする場合、Windows エラー報告 DontShowUI が設定されていません", + "loc.messages.noVstestConsole": "テストは vstest コンソールでは実行されません。vstest コンソールを介してテストを実行するには、Visual Studio 2017 RC 以上をインストールしてください。", + "loc.messages.numberOfTestCasesPerSlice": "バッチあたりのテスト ケース数: %s", + "loc.messages.invalidTestBatchSize": "指定されたバッチ サイズが無効です: %s", + "loc.messages.invalidRunTimePerBatch": "'バッチあたりの実行時間 (秒)' が無効です: %s", + "loc.messages.minimumRunTimePerBatchWarning": "'バッチごとの実行時間 (秒)' は、少なくとも '%s' 秒である必要があります。既定値はサポートされる最小値です。", + "loc.messages.RunTimePerBatch": "バッチあたりの実行時間 (秒): %s", + "loc.messages.searchLocationNotDirectory": "検索フォルダー: '%s' は、ディレクトリでなければならず、存在していなければなりません。", + "loc.messages.rerunFailedTests": "失敗したテストを再実行します: %s", + "loc.messages.rerunFailedThreshold": "失敗したテストの再実行のしきい値: %s", + "loc.messages.invalidRerunFailedThreshold": "失敗したテストの再実行のしきい値が無効です。既定の 30% になります", + "loc.messages.rerunFailedTestCasesMaxLimit": "失敗したテスト ケースの最大再実行回数: %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "失敗したテスト ケースの再実行の制限が無効です。既定の 5 になります", + "loc.messages.rerunMaxAttempts": "最大試行回数、再実行します: %s", + "loc.messages.invalidRerunMaxAttempts": "再実行の最大再試行回数が無効であるか、それを超過しました。既定の 3 になります", + "loc.messages.rerunNotSupported": "Visual Studio 2015 Update 3 または Visual Studio 2017 をインストールして、失敗したテストを再実行してください。", + "loc.messages.toolsInstallerPathNotSet": "VsTest テスト プラットフォームのフォルダーがキャッシュ内に見つかりませんでした。", + "loc.messages.testImpactAndCCWontWork": "テスト インパクト (影響を受けたテストのみ実行する) およびコード カバレッジ データ コレクターは機能しません。", + "loc.messages.ToolsInstallerInstallationError": "Visual Studio テスト プラットフォーム ツール インストーラーが実行されなかったか、インストールが正常に完了しませんでした。ツール インストーラーの使用方法については、次のブログを参照してください: https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "runsettings ファイルで UseVerifiableInstrumentation フィールドを false に上書きしています。", + "loc.messages.NoTestResultsDirectoryFound": "テスト結果のディレクトリが見つかりません。", + "loc.messages.OnlyWindowsOsSupported": "このタスクは、Windows エージェントでのみサポートされ、他のプラットフォームでは使用できません。", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "オンデマンド実行は、複数構成オプションではサポートされていません。'None' または 'Multi-agent' 並列処理オプションをご使用ください。", + "loc.messages.disabledRerun": "失敗したテストの再実行を無効にします。指定された再実行のしきい値は %s です", + "loc.messages.UpgradeAgentMessage": "エージェントのバージョンをアップグレードしてください。https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "VsTestVersion が null または空です", + "loc.messages.UserProvidedSourceFilter": "ソース フィルター: %s", + "loc.messages.UnableToGetFeatureFlag": "次のフィーチャー フラグを取得できません。 %s", + "loc.messages.diagnosticsInput": "診断が有効: %s", + "loc.messages.UncPathNotSupported": "テスト ソースの検索フォルダーへのパスを UNC パスにすることはできません。ルートからのパスまたは $(System.DefaultWorkingDirectory) からの相対パスを指定してください。", + "loc.messages.LookingForBuildToolsInstalltion": "Visual Studio Build Tools バージョン %s のインストールからの vstest.console の検索を試行しています。", + "loc.messages.LookingForVsInstalltion": "Visual Studio バージョン %s のインストールからの vstest.console の検索を試行しています。", + "loc.messages.minTestsNotExecuted": "テストの実行で、指定されたテストの最小数 %d が実行されませんでした。", + "loc.messages.actionOnThresholdNotMet": "テストの最小しきい値が満たされていない場合のアクション: %s", + "loc.messages.minimumExpectedTests": "実行されるテストの最小数: %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Strings/resources.resjson/ko-KR/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/ko-KR/resources.resjson new file mode 100644 index 000000000000..39dd018fab46 --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/ko-KR/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Visual Studio 테스트", + "loc.helpMarkDown": "[이 작업에 대한 자세한 정보](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "VsTest(Visual Studio Test) Runner를 사용하여 단위 및 기능 테스트(Selenium, Appium, 코딩된 UI 테스트 등)를 실행합니다. MsTest, xUnit, NUnit, Chutzpah(QUnit, Mocha 및 Jasmine을 사용한 JavaScript 테스트용) 등의 Visual Studio 테스트 어댑터가 있는 테스트 프레임워크를 실행할 수 있습니다. 이 작업(버전 2)을 사용하여 여러 에이전트에 테스트를 배포할 수 있습니다.", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
                      • 에이전트 작업을 사용하여 테스트 실행: 빌드, 릴리스 및 테스트에 통합 에이전트를 사용할 경우 자동화 에이전트도 테스트 용도로 사용할 수 있습니다. 다중 에이전트 작업 설정을 사용하여 테스트를 분산할 수 있습니다. 다중 구성 작업 설정을 사용하면 여러 구성으로 테스트를 복제할 수 있습니다. 자세한 정보
                      • 테스트 영향 분석: 코드 변경의 유효성을 검사하는 데 필요한 테스트만 자동으로 선택하고 실행합니다.
                      • Visual Studio 테스트 플랫폼 설치 관리자 작업을 사용하여 전체 Visual Studio 설치를 요구하지 않고 테스트를 실행합니다.
                      ", + "loc.group.displayName.testSelection": "테스트 선택", + "loc.group.displayName.executionOptions": "실행 옵션", + "loc.group.displayName.advancedExecutionOptions": "고급 실행 옵션", + "loc.group.displayName.reportingOptions": "보고 옵션", + "loc.input.label.testSelector": "다음을 사용하여 테스트 선택", + "loc.input.help.testSelector": "
                      • 테스트 어셈블리: 테스트가 들어 있는 테스트 어셈블리를 하나 이상 지정하려면 이 옵션을 사용합니다. 필요한 경우 필터 조건을 지정하여 특정 테스트만 선택할 수 있습니다.
                      • 테스트 계획: 테스트 계획에서 자동화된 테스트 메서드가 연결되어 있는 테스트를 실행하려면 이 옵션을 사용합니다.
                      • 테스트 실행: 테스트 허브에서 테스트를 실행할 환경을 설정하는 경우 이 옵션을 사용합니다. CI/CD(연속 통합/연속 배포) 파이프라인에서 테스트를 실행하는 경우에는 이 옵션을 사용할 수 없습니다.
                      • ", + "loc.input.label.testAssemblyVer2": "테스트 파일", + "loc.input.help.testAssemblyVer2": "지정한 파일에서 테스트를 실행합니다.
                        각각 .orderedtest 및 .webtest 파일을 지정하여 순서가 지정된 테스트와 웹 테스트를 실행할 수 있습니다. .webtest를 실행하려면 Visual Studio 2017 업데이트 4 이상이 필요합니다.

                        파일 경로는 검색 폴더에 상대적입니다. 여러 줄의 minimatch 패턴을 지원합니다. [자세한 정보](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "테스트 계획", + "loc.input.help.testPlan": "자동화된 테스트 사례를 사용하는 테스트 도구 모음을 포함하는 테스트 계획을 선택합니다.", + "loc.input.label.testSuite": "테스트 도구 모음", + "loc.input.help.testSuite": "자동화된 테스트 사례를 포함하는 테스트 도구 모음을 하나 이상 선택합니다. 테스트 사례 작업 항목은 자동화된 테스트 메서드에 연결되어야 합니다. [자세한 정보](https://go.microsoft.com/fwlink/?linkid=847773", + "loc.input.label.testConfiguration": "테스트 구성", + "loc.input.help.testConfiguration": "테스트 구성을 선택합니다.", + "loc.input.label.tcmTestRun": "테스트 실행", + "loc.input.help.tcmTestRun": "테스트 실행 기반 선택은 테스트 허브에서 자동화된 테스트 실행을 트리거할 때 사용됩니다. 이 옵션은 CI/CD 파이프라인에서 테스트를 실행하는 경우 사용할 수 없습니다.", + "loc.input.label.searchFolder": "검색 폴더", + "loc.input.help.searchFolder": "테스트 어셈블리를 검색할 폴더입니다.", + "loc.input.label.resultsFolder": "테스트 결과 폴더", + "loc.input.help.resultsFolder": "테스트 결과를 저장할 폴더입니다. 이 입력을 지정하지 않으면 결과는 기본적으로 $(Agent.TempDirectory)/TestResults에 저장되며 파이프라인 실행이 끝나면 정리됩니다. 결과 디렉터리는 항상 테스트를 실행하기 전, vstest 작업을 시작할 때 정리됩니다. 상대 폴더 경로를 제공하면 해당 경로가 $(Agent.TempDirectory)에 상대적인 것으로 간주됩니다.", + "loc.input.label.testFiltercriteria": "테스트 필터 조건", + "loc.input.help.testFiltercriteria": "테스트 어셈블리에서 테스트를 필터링할 추가 조건입니다. 예: 'Priority=1|Name=MyTestMethod'. [자세한 정보](https://msdn.microsoft.com/en-us/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "영향을 받는 테스트만 실행", + "loc.input.help.runOnlyImpactedTests": "코드 변경의 유효성을 검사하는 데 필요한 테스트만 자동으로 선택하고 실행합니다. [자세한 정보](https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "모든 테스트를 실행하기 전까지의 빌드 수", + "loc.input.help.runAllTestsAfterXBuilds": "모든 테스트를 자동으로 실행하기 전까지의 빌드 수입니다. 테스트 영향 분석에서는 테스트 사례와 소스 코드 간의 매핑을 저장합니다. 정기적으로 모든 테스트를 실행하여 매핑을 다시 생성하는 것이 좋습니다.", + "loc.input.label.uiTests": "테스트 조합에 UI 테스트가 포함되어 있음", + "loc.input.help.uiTests": "UI 테스트를 실행하려면 에이전트가 대화형 모드로 실행되도록 설정되었는지 확인합니다. 빌드/릴리스를 큐에 추가하기 전에 대화형으로 실행되도록 에이전트를 설정해야 합니다. 이 확인란을 선택해도 에이전트가 자동으로 대화형 모드로 구성되지는 않습니다. 작업에서 이 옵션은 실패를 방지하기 위해 에이전트를 제대로 구성하라는 미리 알림 역할만 합니다.

                        VS 2015 및 2017 풀의 호스트된 Windows 에이전트를 사용하여 UI 테스트를 실행할 수는 없습니다.
                        [자세한 정보](https://aka.ms/uitestmoreinfo).", + "loc.input.label.vstestLocationMethod": "다음을 사용하여 테스트 플랫폼 선택", + "loc.input.label.vsTestVersion": "테스트 플랫폼 버전", + "loc.input.help.vsTestVersion": "사용할 Visual Studio 테스트의 버전입니다. 최신 버전을 지정하면 설치된 버전에 따라 VS2022부터 시작하여 VS2019, VS2017, VS2015 순으로 최신 Visual Studio 버전을 선택합니다. Visual Studio 2013은 지원되지 않습니다. 에이전트에 Visual Studio 없이 테스트를 실행하려면 '도구 설치 프로그램으로 설치됨' 옵션을 사용합니다. NuGet에서 테스트 플랫폼을 가져오려면 'Visual Studio 테스트 플랫폼 설치 프로그램' 작업을 포함해야 합니다.", + "loc.input.label.vstestLocation": "vstest.console.exe 경로", + "loc.input.help.vstestLocation": "선택적으로 VSTest 경로를 제공합니다.", + "loc.input.label.runSettingsFile": "설정 파일", + "loc.input.help.runSettingsFile": "테스트에서 사용할 runsettings 또는 testsettings 파일의 경로입니다.", + "loc.input.label.overrideTestrunParameters": "테스트 실행 매개 변수 재정의", + "loc.input.help.overrideTestrunParameters": "runsettings 파일의 'TestRunParameters' 섹션 또는 testsettings 파일의 'Properties' 섹션에 정의된 매개 변수를 재정의합니다. 예: '-key1 value1 -key2 value2'. 참고: testsettings 파일에 지정된 속성은 Visual Studio 2017 업데이트 4 이상을 사용하여 TestContext를 통해 액세스할 수 있습니다. ", + "loc.input.label.pathtoCustomTestAdapters": "사용자 지정 테스트 어댑터 경로", + "loc.input.help.pathtoCustomTestAdapters": "사용자 지정 테스트 어댑터의 디렉터리 경로입니다. 테스트 어셈블리와 동일한 폴더에 있는 어댑터는 자동으로 검색됩니다.", + "loc.input.label.runInParallel": "다중 코어 컴퓨터에서 동시에 테스트 실행", + "loc.input.help.runInParallel": "설정한 경우 테스트는 컴퓨터의 사용 가능한 코어를 활용하여 동시에 실행됩니다. runsettings 파일에 지정하면 MaxCpuCount가 재정의됩니다. [여기를 클릭](https://aka.ms/paralleltestexecution)하여 테스트를 동시에 실행하는 방법에 대해 자세히 알아보세요.", + "loc.input.label.runTestsInIsolation": "격리 모드로 테스트 실행", + "loc.input.help.runTestsInIsolation": "격리 모드에서 테스트를 실행합니다. 이렇게 하면 테스트에서 오류가 발생해도 vstest.console.exe 프로세스가 중지될 가능성이 작아지지만 테스트 실행 속도가 느려질 수 있습니다. 이 옵션은 현재 다중 에이전트 작업 설정으로 실행되는 경우 사용할 수 없습니다.", + "loc.input.label.codeCoverageEnabled": "코드 검사 사용", + "loc.input.help.codeCoverageEnabled": "테스트 실행에서 코드 검사 정보를 수집합니다.", + "loc.input.label.otherConsoleOptions": "기타 콘솔 옵션", + "loc.input.help.otherConsoleOptions": "여기에 문서화된 대로, vstest.console.exe에 전달할 수 있는 기타 콘솔 옵션입니다.

                        이러한 옵션은 지원되지 않으며, 에이전트 작업의 '다중 에이전트' 병렬 설정을 사용하여 테스트를 실행하거나, '테스트 계획' 또는 '테스트 실행' 옵션을 사용하여 테스트를 실행하거나, 사용자 지정 일괄 처리 옵션을 선택한 경우 무시됩니다. 대신 설정 파일을 사용하여 옵션을 지정할 수 있습니다.

                        ", + "loc.input.label.distributionBatchType": "테스트 일괄 처리", + "loc.input.help.distributionBatchType": "일괄 처리는 테스트 그룹입니다. 테스트 일괄 처리는 동시에 해당 테스트를 실행하며, 일괄 처리에 대한 결과가 게시됩니다. 작업이 실행되는 작업이 여러 에이전트를 사용하도록 설정된 경우 각 에이전트가 사용 가능한 테스트 일괄 처리를 선택하여 병렬로 실행합니다.

                        테스트 및 에이전트 수 기반: 테스트 실행에 참여하는 테스트 및 에이전트 수를 기반으로 하는 간단한 일괄 처리입니다.

                        테스트의 이전 실행 시간 기반: 이 일괄 처리에서는 이전 실행 시간을 고려하여 각 일괄 처리의 실행 시간이 대략 동일하도록 테스트 일괄 처리를 만듭니다.

                        테스트 어셈블리 기반: 어셈블리의 테스트가 일괄 처리됩니다.", + "loc.input.label.batchingBasedOnAgentsOption": "일괄 처리 옵션", + "loc.input.help.batchingBasedOnAgentsOption": "테스트 실행에 참여하는 테스트 및 에이전트의 수를 기반으로 하는 간단한 일괄 처리입니다. 일괄 처리 크기가 자동으로 결정되면 각 일괄 처리에는 `(총 테스트 수/에이전트 수)` 테스트가 포함됩니다. 일괄 처리 크기가 지정되면 각 일괄 처리에는 지정된 테스트 수가 포함됩니다.", + "loc.input.label.customBatchSizeValue": "일괄 처리당 테스트 수", + "loc.input.help.customBatchSizeValue": "일괄 처리 크기 지정", + "loc.input.label.batchingBasedOnExecutionTimeOption": "일괄 처리 옵션", + "loc.input.help.batchingBasedOnExecutionTimeOption": "이 일괄 처리에서는 이전 실행 시간을 고려하여 각 일괄 처리의 실행 시간이 대략 동일하도록 테스트 일괄 처리를 만듭니다. 빠른 실행 테스트는 함께 일괄 처리되는 반면, 장기 실행 테스트는 별도의 일괄 처리에 속할 수 있습니다. 이 옵션을 다중 에이전트 작업 설정과 함께 사용할 경우 총 테스트 시간을 최소화할 수 있습니다.", + "loc.input.label.customRunTimePerBatchValue": "일괄 처리당 실행 시간(초)", + "loc.input.help.customRunTimePerBatchValue": "일괄 처리당 실행 시간(초) 지정", + "loc.input.label.dontDistribute": "작업에서 여러 에이전트를 사용하는 경우 테스트를 분산하는 대신 복제", + "loc.input.help.dontDistribute": "이 옵션을 선택하면 다중 에이전트 작업에서 작업을 실행할 때 테스트가 여러 에이전트에 분산되지 않습니다.
                        선택한 각 테스트는 각 에이전트에서 반복됩니다.
                        에이전트 작업이 병렬 처리 없이 또는 다중 구성 옵션을 사용하여 실행되도록 구성된 경우에는 이 옵션을 적용할 수 없습니다.", + "loc.input.label.testRunTitle": "테스트 실행 제목", + "loc.input.help.testRunTitle": "테스트 실행의 이름을 지정하세요.", + "loc.input.label.platform": "빌드 플랫폼", + "loc.input.help.platform": "테스트를 보고해야 하는 빌드 플랫폼입니다. 빌드 작업에서 플랫폼에 사용할 변수를 정의한 경우, 여기에서 해당 변수를 사용하세요.", + "loc.input.label.configuration": "빌드 구성", + "loc.input.help.configuration": "테스트를 보고해야 하는 빌드 구성입니다. 빌드 작업에서 구성에 사용할 변수를 정의한 경우, 여기에서 해당 변수를 사용하세요.", + "loc.input.label.publishRunAttachments": "테스트 첨부 파일 업로드", + "loc.input.help.publishRunAttachments": "게시 실행 수준 첨부 파일의 옵트인(opt in)/옵트아웃(opt out)입니다.", + "loc.input.label.failOnMinTestsNotRun": "최소 수의 테스트를 실행하지 않으면 작업이 실패합니다.", + "loc.input.help.failOnMinTestsNotRun": "지정된 최소 수의 테스트가 실행되지 않을 경우 이 옵션을 선택하면 작업이 실패합니다.", + "loc.input.label.minimumExpectedTests": "최소 테스트 수", + "loc.input.help.minimumExpectedTests": "작업 성공을 위해 실행해야 하는 최소 테스트 수를 지정합니다. 실행된 총 테스트 수는 통과, 실패 및 중단된 테스트의 합계로 계산됩니다.", + "loc.input.label.diagnosticsEnabled": "치명적인 오류가 발생하는 경우 고급 진단 수집", + "loc.input.help.diagnosticsEnabled": "치명적인 오류가 발생하는 경우 고급 진단을 수집합니다.", + "loc.input.label.collectDumpOn": "프로세스 덤프를 수집하여 테스트 실행 보고서에 연결", + "loc.input.help.collectDumpOn": "프로세스 덤프를 수집하고 테스트 실행 보고서에 연결합니다.", + "loc.input.label.rerunFailedTests": "실패한 테스트 다시 실행", + "loc.input.help.rerunFailedTests": "이 옵션을 선택하면 성공하거나 최대 시도 횟수에 도달할 때까지 실패한 테스트가 다시 실행됩니다.", + "loc.input.label.rerunType": "테스트 실패가 지정된 임계값을 초과할 경우 다시 실행 안 함", + "loc.input.help.rerunType": "실패율이 지정된 임계값을 초과할 때 테스트를 다시 실행하지 않으려면 이 옵션을 사용합니다. 환경 문제로 인해 대량 실패가 발생하는 경우에 적용할 수 있습니다.
                        실패율(%) 또는 실패한 테스트 수를 임계값으로 지정할 수 있습니다.", + "loc.input.label.rerunFailedThreshold": "실패율(%)", + "loc.input.help.rerunFailedThreshold": "실패율이 지정된 임계값을 초과할 때 테스트를 다시 실행하지 않으려면 이 옵션을 사용합니다. 환경 문제로 인해 대량 실패가 발생하는 경우에 적용할 수 있습니다.", + "loc.input.label.rerunFailedTestCasesMaxLimit": "실패한 테스트 수", + "loc.input.help.rerunFailedTestCasesMaxLimit": "실패한 테스트 사례 수가 지정된 제한을 초과할 때 테스트를 다시 실행하지 않으려면 이 옵션을 사용합니다. 환경 문제로 인해 대량 실패가 발생하는 경우에 적용할 수 있습니다.", + "loc.input.label.rerunMaxAttempts": "최대 시도 횟수", + "loc.input.help.rerunMaxAttempts": "실패한 테스트를 다시 시도할 최대 횟수를 지정합니다. 최대 시도 횟수에 도달하기 전에 테스트가 성공하면 더 이상 실행되지 않습니다.", + "loc.messages.VstestLocationDoesNotExist": "'%s'을(를) 지정하는 'vstest.console.exe'의 위치가 없습니다.", + "loc.messages.VstestFailedReturnCode": "VsTest 작업이 실패했습니다.", + "loc.messages.VstestPassedReturnCode": "VsTest 작업이 성공했습니다.", + "loc.messages.NoMatchingTestAssemblies": "%s 패턴과 일치하는 테스트 어셈블리를 찾을 수 없습니다.", + "loc.messages.VstestNotFound": "Visual Studio %d을(를) 찾을 수 없습니다. 빌드 에이전트 컴퓨터에 있는 버전을 사용하여 다시 시도하세요.", + "loc.messages.NoVstestFound": "테스트 플랫폼을 찾을 수 없습니다. 테스트 플랫폼을 빌드 에이전트 컴퓨터에 설치한 후 다시 시도하세요.", + "loc.messages.VstestFailed": "오류가 발생하여 Vstest가 실패했습니다. 오류는 로그를 확인하세요. 실패한 테스트가 있을 수 있습니다.", + "loc.messages.VstestTIANotSupported": "테스트 영향 분석을 실행하려면 Visual Studio 2015 업데이트 3 또는 Visual Studio 2017 RC 이상을 설치하세요.", + "loc.messages.NoResultsToPublish": "게시할 결과를 찾을 수 없습니다.", + "loc.messages.ErrorWhileReadingRunSettings": "실행 설정 파일을 읽는 동안 오류가 발생했습니다. 오류: %s.", + "loc.messages.ErrorWhileReadingTestSettings": "테스트 설정 파일을 읽는 동안 오류가 발생했습니다. 오류: %s.", + "loc.messages.RunInParallelNotSupported": "다중 코어 컴퓨터에서의 테스트 동시 실행은 testsettings 파일에서 지원되지 않습니다. 이 옵션은 무시됩니다.", + "loc.messages.InvalidSettingsFile": "지정된 설정 파일 %s이(가) 잘못되었거나 없습니다. 올바른 설정 파일을 지정하거나 필드를 지우세요.", + "loc.messages.UpdateThreeOrHigherRequired": "테스트를 병렬로 실행하려면 빌드 에이전트 컴퓨터에 Visual Studio 2015 업데이트 3 이상을 설치하세요.", + "loc.messages.ErrorOccuredWhileSettingRegistry": "레지스트리 키를 설정하는 동안 오류가 발생했습니다. 오류: %s.", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "테스트 설정 파일에서 테스트 영향 수집기를 설정하는 동안 오류가 발생했습니다.", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "실행 설정 파일에서 테스트 영향 수집기를 설정하는 동안 오류가 발생했습니다.", + "loc.messages.ErrorWhileCreatingResponseFile": "지시 파일을 만드는 동안 오류가 발생했습니다. 모든 테스트는 이 실행에 대해 실행됩니다.", + "loc.messages.ErrorWhileUpdatingResponseFile": "지시 파일 '%s'을(를) 업데이트하는 동안 오류가 발생했습니다. 모든 테스트는 이 실행에 대해 실행됩니다.", + "loc.messages.ErrorWhilePublishingCodeChanges": "코드 변경 내용을 게시하는 동안 오류가 발생했습니다. 모든 테스트는 이 실행에 대해 실행됩니다.", + "loc.messages.ErrorWhileListingDiscoveredTests": "테스트를 검색하는 동안 오류가 발생했습니다. 모든 테스트는 이 실행에 대해 실행됩니다.", + "loc.messages.PublishCodeChangesPerfTime": "코드 변경 내용을 게시하는 데 걸린 총 시간은 %d밀리초입니다.", + "loc.messages.GenerateResponseFilePerfTime": "지시 파일을 가져오는 데 걸린 총 시간은 %d밀리초입니다.", + "loc.messages.UploadTestResultsPerfTime": "테스트 결과를 업로드하는 데 걸린 총 시간은 %d밀리초입니다.", + "loc.messages.ErrorReadingVstestVersion": "vstest.console.exe의 버전을 읽는 동안 오류가 발생했습니다.", + "loc.messages.UnexpectedVersionString": "vstest.console.exe에 대해 예기치 않은 버전 문자열이 검색되었습니다. %s.", + "loc.messages.UnexpectedVersionNumber": "vstest.console.exe에 대해 예기치 않은 버전 번호가 검색되었습니다. %s.", + "loc.messages.VstestDiagNotSupported": "vstest.console.exe 버전에서 /diag 플래그를 지원하지 않습니다. exe.config 파일을 통해 진단을 사용하도록 설정하세요.", + "loc.messages.NoIncludePatternFound": "포함 패턴을 찾을 수 없습니다. 테스트 어셈블리를 검색하려면 포함 패턴을 하나 이상 지정하세요.", + "loc.messages.ErrorWhileUpdatingSettings": "설정 파일을 업데이트하는 동안 오류가 발생했습니다. 지정된 설정 파일을 사용하는 중입니다.", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "Video collector는 실행 설정에서 지원되지 않습니다.", + "loc.messages.runTestInIsolationNotSupported": "다중 에이전트 작업 설정을 사용하는 경우에는 격리 모드로 테스트 실행이 지원되지 않습니다. 이 옵션은 무시됩니다.", + "loc.messages.overrideNotSupported": "테스트 실행 매개 변수 재정의는 유효한 runsettings 또는 testsettings 파일에서만 지원됩니다. 이 옵션은 무시됩니다.", + "loc.messages.testSettingPropertiesNotSupported": "testsettings 파일에 지정된 속성은 Visual Studio 2017 업데이트 4 이상을 사용하여 TestContext를 통해 액세스할 수 있습니다.", + "loc.messages.vstestVersionInvalid": "지정한 테스트 플랫폼 버전 %s은(는) 지원되지 않습니다.", + "loc.messages.configureDtaAgentFailed": "서버에 테스트 에이전트를 구성하는 작업이 %d번의 재시도 후 실패했습니다(오류 %s).", + "loc.messages.otherConsoleOptionsNotSupported": "기타 콘솔 옵션은 이 작업 구성에서 지원되지 않습니다. 이 옵션은 무시됩니다.", + "loc.messages.distributedTestWorkflow": "분산된 테스트 흐름에서", + "loc.messages.nonDistributedTestWorkflow": "vstest.console.exe runner를 사용하여 테스트를 실행 중입니다.", + "loc.messages.dtaNumberOfAgents": "분산 테스트 실행, 작업의 에이전트 수: %s", + "loc.messages.testSelectorInput": "테스트 선택기: %s", + "loc.messages.searchFolderInput": "검색 폴더: %s", + "loc.messages.testFilterCriteriaInput": "테스트 필터 조건: %s", + "loc.messages.runSettingsFileInput": "실행 설정 파일: %s", + "loc.messages.runInParallelInput": "병렬로 실행: %s", + "loc.messages.runInIsolationInput": "격리 상태로 실행: %s", + "loc.messages.pathToCustomAdaptersInput": "사용자 지정 어댑터의 경로: %s", + "loc.messages.otherConsoleOptionsInput": "기타 콘솔 옵션: %s", + "loc.messages.codeCoverageInput": "코드 검사 사용: %s", + "loc.messages.testPlanInput": "테스트 계획 ID: %s", + "loc.messages.testplanConfigInput": "테스트 계획 구성 ID: %s", + "loc.messages.testSuiteSelected": "선택한 테스트 도구 모음 ID: %s", + "loc.messages.testAssemblyFilterInput": "테스트 어셈블리: %s", + "loc.messages.vsVersionSelected": "테스트 실행을 위해 선택한 Visual Studio 버전: %s", + "loc.messages.runTestsLocally": "%s을(를) 사용하여 로컬로 테스트 실행", + "loc.messages.vstestLocationSpecified": "%s, 지정된 위치: %s", + "loc.messages.uitestsparallel": "동일한 컴퓨터에서 UI 테스트를 동시에 실행하면 오류가 발생할 수 있습니다. ‘병렬로 실행’ 옵션을 사용하지 않도록 설정하거나 별도의 작업을 사용하여 UI 테스트를 실행해 보세요. 자세히 알아보려면 https://aka.ms/paralleltestexecution을 참조하세요. ", + "loc.messages.pathToCustomAdaptersInvalid": "사용자 지정 어댑터 '%s'에 대한 경로는 디렉터리로 있어야 합니다.", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "사용자 지정 어댑터 '%s'에 대한 경로에 테스트 어댑터가 포함되어 있지 않습니다. 올바른 경로를 제공하세요.", + "loc.messages.testAssembliesSelector": "테스트 어셈블리", + "loc.messages.testPlanSelector": "테스트 계획", + "loc.messages.testRunSelector": "테스트 실행", + "loc.messages.testRunIdInvalid": "테스트 선택은 '테스트 실행'이지만, 지정한 테스트 실행 ID '%s'이(가) 잘못되었습니다.", + "loc.messages.testRunIdInput": "테스트 실행 ID: '%s'", + "loc.messages.testSourcesFilteringFailed": "테스트 소스 파일을 준비하지 못했습니다. 오류: %s", + "loc.messages.noTestSourcesFound": "지정된 필터 '%s'과(와) 일치하는 테스트 소스를 찾을 수 없습니다.", + "loc.messages.DontShowWERUIDisabledWarning": "Windows 오류 보고 DontShowUI가 설정되지 않았습니다. UI 테스트 실행 중간에 Windows 오류 대화 상자가 나타나면 테스트가 중단됩니다.", + "loc.messages.noVstestConsole": "테스트는 vstest 콘솔에서 실행되지 않습니다. vstest 콘솔을 통해 테스트를 실행하려면 Visual Studio 2017 RC 이상을 설치하세요.", + "loc.messages.numberOfTestCasesPerSlice": "일괄 처리당 테스트 사례 수: %s", + "loc.messages.invalidTestBatchSize": "잘못된 일괄 처리 크기가 지정됨: %s", + "loc.messages.invalidRunTimePerBatch": "잘못된 '일괄 처리당 실행 시간(초)': %s", + "loc.messages.minimumRunTimePerBatchWarning": "'일괄 처리당 실행 시간(초)'은 '%s'초 이상이어야 합니다. 기본값은 지원되는 최소값으로 설정됩니다.", + "loc.messages.RunTimePerBatch": "일괄 처리당 실행 시간(초): %s", + "loc.messages.searchLocationNotDirectory": "검색 폴더 '%s'이(가) 있고 디렉터리여야 합니다.", + "loc.messages.rerunFailedTests": "실패한 테스트 다시 실행: %s", + "loc.messages.rerunFailedThreshold": "실패한 테스트 다시 실행 임계값: %s", + "loc.messages.invalidRerunFailedThreshold": "실패한 테스트 다시 실행 임계값이 잘못되었습니다. 기본값인 30%로 설정합니다.", + "loc.messages.rerunFailedTestCasesMaxLimit": "실패한 테스트 사례 최대 다시 실행 한도: %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "실패한 테스트 사례 다시 실행 제한이 잘못되었습니다. 기본값인 5로 설정합니다.", + "loc.messages.rerunMaxAttempts": "다시 실행 최대 시도 횟수: %s", + "loc.messages.invalidRerunMaxAttempts": "다시 실행 최대 시도 횟수를 초과했거나 잘못되었습니다. 기본값인 3으로 설정합니다.", + "loc.messages.rerunNotSupported": "실패한 테스트를 다시 실행하려면 Visual Studio 2015 업데이트 3 또는 Visual Studio 2017을 설치합니다.", + "loc.messages.toolsInstallerPathNotSet": "VsTest 테스트 플랫폼 폴더가 캐시에 없습니다.", + "loc.messages.testImpactAndCCWontWork": "테스트 영향(영향받는 테스트만 실행) 및 코드 검사 데이터 수집기가 작동하지 않습니다.", + "loc.messages.ToolsInstallerInstallationError": "Visual Studio 테스트 플랫폼 도구 설치 관리자가 실행되지 않았거나 설치를 완료하지 않았습니다. 도구 설치 관리자를 사용하는 방법에 대한 자세한 내용은 다음 블로그를 참조하세요. https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "runsettings 파일에서 UseVerifiableInstrumentation 필드를 false로 재정의합니다.", + "loc.messages.NoTestResultsDirectoryFound": "테스트 결과 디렉터리가 없습니다.", + "loc.messages.OnlyWindowsOsSupported": "이 작업은 Windows 에이전트에서만 지원되며 다른 플랫폼에서는 사용할 수 없습니다.", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "주문형 실행은 다중 구성 옵션에서 지원되지 않습니다. '없음' 또는 '다중 에이전트' 병렬 처리 옵션을 사용하세요.", + "loc.messages.disabledRerun": "제공된 다시 실행 임계값이 %s이므로 실패한 테스트 다시 실행을 사용하지 않도록 설정하는 중", + "loc.messages.UpgradeAgentMessage": "에이전트 버전을 업그레이드하세요. https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "VsTestVersion이 null이거나 비어 있습니다.", + "loc.messages.UserProvidedSourceFilter": "소스 필터: %s", + "loc.messages.UnableToGetFeatureFlag": "기능 플래그를 가져올 수 없습니다. %s", + "loc.messages.diagnosticsInput": "진단 사용: %s", + "loc.messages.UncPathNotSupported": "테스트 소스 검색 폴더의 경로는 UNC 경로일 수 없습니다. 루트 경로 또는 $(System.DefaultWorkingDirectory)의 상대 경로를 입력하세요.", + "loc.messages.LookingForBuildToolsInstalltion": "버전이 %s인 Visual Studio Build Tools 설치에서 vstest.console을 찾는 중입니다.", + "loc.messages.LookingForVsInstalltion": "버전이 %s인 Visual Studio 설치에서 vstest.console을 찾는 중입니다.", + "loc.messages.minTestsNotExecuted": "지정된 최소 테스트 수 %d이(가) 테스트 실행에서 실행되지 않았습니다.", + "loc.messages.actionOnThresholdNotMet": "최소 테스트 임계값이 충족되지 않은 경우의 작업: %s", + "loc.messages.minimumExpectedTests": "실행될 것으로 예상되는 최소 테스트: %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Strings/resources.resjson/ru-RU/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/ru-RU/resources.resjson new file mode 100644 index 000000000000..90ca47481913 --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/ru-RU/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Тест Visual Studio", + "loc.helpMarkDown": "[См. дополнительные сведения об этой задаче](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "Вы можете запускать модульные и функциональные тесты (Selenium, Appium, закодированные тесты пользовательского интерфейса и т. д.) с помощью средства запуска тестов Visual Studio (VsTest). Можно запустить платформы тестирования с адаптером тестов Visual Studio, такие как MsTest, xUnit, NUnit, Chutzpah (для тестов JavaScript с использованием QUnit, Mocha и Jasmine) и т. д. Тесты могут быть распределены между различными агентами с помощью этой задачи (версия 2).", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
                        • Выполнение тестов с помощью задания агента: Унификация агентов сборки, выпуска и тестирования позволяет использовать агенты автоматизации также в целях тестирования. Вы можете распределять тесты с помощью задания с несколькими агентами. С помощью задания с несколькими конфигурациями можно реплицировать тесты в различных конфигурациях. Дополнительные сведения
                        • Анализ влияния на тесты: Автоматически выбирайте и выполняйте только те тесты, которые необходимы для проверки изменений в коде.
                        • Используйте задачу установщика платформы тестирования Visual Studio, чтобы выполнять тесты, не устанавливая Visual Studio полностью.
                        ", + "loc.group.displayName.testSelection": "Выбор теста", + "loc.group.displayName.executionOptions": "Параметры выполнения", + "loc.group.displayName.advancedExecutionOptions": "Дополнительные параметры выполнения", + "loc.group.displayName.reportingOptions": "Параметры отчетов", + "loc.input.label.testSelector": "Выбрать тесты с помощью", + "loc.input.help.testSelector": "
                        • Тестовая сборка: Используйте этот параметр, чтобы указать одну или несколько тестовых сборок, содержащих тесты. При необходимости можно указать условие фильтра для выбора определенных тестов.
                        • План тестирования: Используйте этот параметр для выполнения тестов из плана тестирования, с которым связан метод автоматического тестирования.
                        • Тестовый запуск: Используйте этот параметр при настройке среды для выполнения тестов из центра тестирования. Этот параметр не следует использовать при выполнении тестов в конвейере непрерывной интеграции и непрерывного развертывания (CI/CD).
                        • ", + "loc.input.label.testAssemblyVer2": "Файлы теста", + "loc.input.help.testAssemblyVer2": "Запуск тестов из указанных файлов.
                          Для запуска упорядоченных тестов и веб-тестов необходимо указать файлы .orderedtest и .webtest соответственно. Для запуска файла .webtest необходима среда Visual Studio 2017 с обновлением 4 или более поздней версии.

                          Пути к файлам задаются относительно папки поиска. Поддерживаются многострочные шаблоны minimatch. [Дополнительные сведения](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "План тестирования", + "loc.input.help.testPlan": "Выберите план тестирования, содержащий набор тестов с автоматическими тестовыми случаями.", + "loc.input.label.testSuite": "Набор тестов", + "loc.input.help.testSuite": "Выберите наборы тестов, содержащие автоматические тестовые случаи. Рабочие элементы тестового случая должны быть связаны с методом автоматического тестирования. [Дополнительные сведения.](https://go.microsoft.com/fwlink/?linkid=847773", + "loc.input.label.testConfiguration": "Конфигурация теста", + "loc.input.help.testConfiguration": "Выберите конфигурацию теста.", + "loc.input.label.tcmTestRun": "Тестовый запуск", + "loc.input.help.tcmTestRun": "При активации автоматических тестовых запусков из центра тестирования используется выбор на основе тестового запуска. Данный параметр невозможно использовать для запуска тестов в конвейере CI/CD.", + "loc.input.label.searchFolder": "Папка поиска", + "loc.input.help.searchFolder": "Папка для поиска тестовых сборок.", + "loc.input.label.resultsFolder": "Папка результатов теста", + "loc.input.help.resultsFolder": "Папка для хранения результатов тестов. Если эти входные данные не указаны, результаты по умолчанию хранятся в папке $(Agent.TempDirectory)/TestResults, которая очищается в конце выполнения конвейера. Каталог результатов всегда очищается при запуске задачи vstest перед выполнением тестов. Относительный путь к папке, если он указан, будет определяться относительно $(Agent.TempDirectory)", + "loc.input.label.testFiltercriteria": "Критерии фильтрации тестов", + "loc.input.help.testFiltercriteria": "Дополнительное условие фильтрации тестов из тестовых сборок. \"Priority=1|Name=MyTestMethod\". [Дополнительные сведения](https://msdn.microsoft.com/ru-ru/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "Запустить только затронутые тесты", + "loc.input.help.runOnlyImpactedTests": "Автоматический выбор и запуск только тех тестов, которые необходимы для проверки изменений в коде. [Дополнительные сведения](https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "Число сборок, после которых следует запустить все тесты", + "loc.input.help.runAllTestsAfterXBuilds": "Число сборок, после которых нужно запустить все тесты автоматически. При анализе влияния на тесты сохраняется сопоставление между тестовыми случаями и исходным кодом. Рекомендуется регулярно формировать сопоставление повторно, запуская все тесты.", + "loc.input.label.uiTests": "Тестовый набор содержит тесты пользовательского интерфейса.", + "loc.input.help.uiTests": "Чтобы выполнять тесты пользовательского интерфейса, убедитесь в том, что агент настроен для работы в интерактивном режиме. Настройку агента для работы в интерактивном режиме необходимо выполнить до помещения сборки или выпуска в очередь. Установка этого флажка не приводит к автоматической настройке агента для работы в интерактивном режиме. Этот параметр задачи служит лишь в качестве напоминания о необходимости настроить агент соответствующим образом, чтобы избежать сбоев.

                          Размещенные агенты Windows из пулов VS 2015 и 2017 можно использовать для выполнения тестов пользовательского интерфейса.
                          [Дополнительные сведения](https://aka.ms/uitestmoreinfo).", + "loc.input.label.vstestLocationMethod": "Выбрать платформу тестирования с помощью", + "loc.input.label.vsTestVersion": "Версия платформы тестирования", + "loc.input.help.vsTestVersion": "Используемая версия теста Visual Studio. Если указана последняя версия, будет использована последняя версия Visual Studio начиная с VS2022, за которой следуют VS2019, VS2017 и VS2015 в зависимости от того, какая версия установлена. Visual Studio 2013 не поддерживается. Для запуска тестов без необходимости использования Visual Studio в агенте воспользуйтесь параметром \"Установлено с помощью установщика инструментов\". Обязательно включите задачу \"Установщик платформы тестирования Visual Studio\", чтобы получить платформу тестирования от NuGet.", + "loc.input.label.vstestLocation": "Путь к vstest.console.exe", + "loc.input.help.vstestLocation": "При необходимости укажите путь к VSTest.", + "loc.input.label.runSettingsFile": "Файл параметров", + "loc.input.help.runSettingsFile": "Путь к файлу runsettings или testsettings для использования в тестах.", + "loc.input.label.overrideTestrunParameters": "Переопределить параметры тестового запуска", + "loc.input.help.overrideTestrunParameters": "Переопределите параметры, определенные в разделе \"TestRunParameters\" файла runsettings или в разделе \"Properties\" файла testsettings. Например, \"`-key1 value1 -key2 value2\". Примечание. К свойствам, указанным в файле testsettings, можно обратиться через TestContext, используя Visual Studio 2017 с обновлением 4 или более поздней версии. ", + "loc.input.label.pathtoCustomTestAdapters": "Путь к пользовательским адаптерам теста", + "loc.input.help.pathtoCustomTestAdapters": "Путь к каталогу с пользовательскими адаптерами теста. Адаптеры, находящееся в той же папке, что и тестовые сборки, определяются автоматически.", + "loc.input.label.runInParallel": "Запустить тесты параллельно на компьютерах с многоядерными процессорами", + "loc.input.help.runInParallel": "Если этот параметр установлен, тесты будут выполняться параллельно с использованием доступных на компьютере ядер. Этот параметр имеет приоритет над параметром MaxCpuCount, если он указан в файле runsettings. Дополнительные сведения о параллельном выполнении тестов [см. здесь](https://aka.ms/paralleltestexecution).", + "loc.input.label.runTestsInIsolation": "Запустить тесты в изолированных процессах", + "loc.input.help.runTestsInIsolation": "Тесты выполняются в изолированном процессе. Это снижает вероятность остановки процесса vstest.console.exe при возникновении ошибки тестирования, но выполнение тестов в этом случае может замедлиться. Данный параметр в настоящее время невозможно использовать при наличии настройки, подразумевающей задание с несколькими агентами.", + "loc.input.label.codeCoverageEnabled": "Оценка объемов протестированного кода включена.", + "loc.input.help.codeCoverageEnabled": "Сбор сведений об объемах протестированного кода из тестового запуска.", + "loc.input.label.otherConsoleOptions": "Другие параметры консоли", + "loc.input.help.otherConsoleOptions": "Другие параметры консоли, которые можно передать в vstest.console.exe, как описано здесь.

                          Эти параметры не поддерживаются и будут пропущены при параллельном запуске тестов для нескольких агентов, при запуске тестов с помощью параметра \"План тестирования\" или \"Тестовый запуск\" либо при выборе параметра настраиваемой пакетной обработки. Эти параметры также можно указать в файле параметров.

                          ", + "loc.input.label.distributionBatchType": "Тесты пакета", + "loc.input.help.distributionBatchType": "Пакет — это группа тестов. Тесты из пакета выполняются одновременно, а результаты публикуются для всего пакета. Если для задания, в рамках которого выполняется задача, настроено использование нескольких агентов, каждый агент выбирает доступные пакеты тестов для параллельного выполнения.

                          В зависимости от количества тестов и агентов: простая пакетная обработка в зависимости от количества тестов и агентов, участвующих в тестовом запуске.

                          В зависимости от времени выполнения тестов в прошлом: при такой пакетной обработке учитывается время выполнения в прошлом, в соответствии с которым формируются пакеты тестов с приблизительно равным временем выполнения.

                          В соответствии со сборками тестов: в пакет объединяются тесты, относящиеся к одной и той же сборке.", + "loc.input.label.batchingBasedOnAgentsOption": "Параметры пакета", + "loc.input.help.batchingBasedOnAgentsOption": "Простая пакетная обработка на основе количества тестов и агентов, участвующих в запуске теста. При автоматическом определении размера пакета каждый пакет содержит количество тестов, равное результату деления общего числа тестов на количество агентов. Если размер пакета указан, каждый пакет содержит указанное количество тестов.", + "loc.input.label.customBatchSizeValue": "Количество тестов в пакете", + "loc.input.help.customBatchSizeValue": "Укажите размер пакета", + "loc.input.label.batchingBasedOnExecutionTimeOption": "Параметры пакета", + "loc.input.help.batchingBasedOnExecutionTimeOption": "В этой пакетной обработке учитывается предыдущее время выполнения тестов. Это позволяет создавать пакеты тестов так, чтобы время выполнения пакетов было близким. Короткие тесты будут объединены в один пакет, а для длинных могут быть выделены отдельные пакеты. При использовании этого параметра с заданием с несколькими агентами общее время выполнения теста сводится к минимуму.", + "loc.input.label.customRunTimePerBatchValue": "Время выполнения пакета (с)", + "loc.input.help.customRunTimePerBatchValue": "Укажите время выполнения на пакет (с)", + "loc.input.label.dontDistribute": "Репликация тестов вместо распространения для задания с несколькими агентами", + "loc.input.help.dontDistribute": "Если этот параметр выбран, то тесты не будут распределяться по различным агентам при выполнении задачи в рамках задания с несколькими агентами.
                          Каждый из выбранных тестов будет выполнен в каждом агенте.
                          Этот параметр не применяется, если для задания агента указан параметр выполнения \"Без параллелизма\" или \"Множественная конфигурация\".", + "loc.input.label.testRunTitle": "Название тестового запуска", + "loc.input.help.testRunTitle": "Укажите имя для тестового запуска.", + "loc.input.label.platform": "Платформа сборки", + "loc.input.help.platform": "Платформа сборки, на основе которой создаются отчеты о тестировании. Если вы определили переменную для платформы в задаче сборки, используйте ее здесь.", + "loc.input.label.configuration": "Конфигурация сборки", + "loc.input.help.configuration": "Конфигурация сборки, на основе которой создаются отчеты о тестировании. Если вы определили переменную для конфигурации в задаче сборки, используйте ее здесь.", + "loc.input.label.publishRunAttachments": "Отправить тестовые вложения", + "loc.input.help.publishRunAttachments": "Участвовать или отказаться от участия в публикации вложений уровня запуска.", + "loc.input.label.failOnMinTestsNotRun": "Задача завершается сбоем, если не выполнено указанное минимальное количество тестов.", + "loc.input.help.failOnMinTestsNotRun": "Выбор этого параметра приведет к сбою задачи, если не выполнено указанное минимальное количество тестов.", + "loc.input.label.minimumExpectedTests": "Минимальное число тестов", + "loc.input.help.minimumExpectedTests": "Укажите минимальное число тестов, которые должны быть проведены для успешного выполнения задачи. Общее число выполненных тестов вычисляется как сумма пройденных, непройденных и прерванных тестов.", + "loc.input.label.diagnosticsEnabled": "Собирать расширенные диагностические данные в случае неустранимых ошибок", + "loc.input.help.diagnosticsEnabled": "Сбор расширенных диагностических данных в случае неустранимых ошибок.", + "loc.input.label.collectDumpOn": "Собрать дамп процесса и вложить его в отчет о тестовом запуске", + "loc.input.help.collectDumpOn": "Сбор дампа процесса и его вложение в отчет о тестовом запуске.", + "loc.input.label.rerunFailedTests": "Повторять неудачные тесты", + "loc.input.help.rerunFailedTests": "При выборе этого параметра все неудачные тесты будут повторяться до тех пор, пока они не будут пройдены или пока не будет достигнуто максимальное число попыток.", + "loc.input.label.rerunType": "Не запускать тесты повторно, если число неудачных тестов превышает заданный порог", + "loc.input.help.rerunType": "Используйте этот параметр, чтобы избежать повторного запуска тестов, когда доля неудачных тестовых случаев превышает заданное пороговое значение. Его можно использовать в тех случаях, когда проблемы со средой приводят к масштабным сбоям.
                          Вы можете указать процент неудачных тестов или число неудачных тестов в качестве порогового значения.", + "loc.input.label.rerunFailedThreshold": "Процент сбоев", + "loc.input.help.rerunFailedThreshold": "Используйте этот параметр, чтобы избежать повторного запуска тестов, когда доля неудачных тестовых случаев превышает заданное пороговое значение. Его можно использовать в тех случаях, когда проблемы со средой приводят к масштабным сбоям.", + "loc.input.label.rerunFailedTestCasesMaxLimit": "Число неудачных тестов", + "loc.input.help.rerunFailedTestCasesMaxLimit": "Используйте этот параметр, чтобы избежать повторного запуска тестов, когда число неудачных тестовых случаев превышает заданное ограничение. Его можно использовать в тех случаях, когда проблемы со средой приводят к масштабным сбоям.", + "loc.input.label.rerunMaxAttempts": "Максимальное число попыток", + "loc.input.help.rerunMaxAttempts": "Укажите максимальное число попыток повтора неудачного теста. Если тест завершается успешно до того, как будет достигнуто максимальное число попыток, он больше не будет повторяться.", + "loc.messages.VstestLocationDoesNotExist": "Расположение \"vstest.console.exe\", указанное как \"%s\", не существует.", + "loc.messages.VstestFailedReturnCode": "Сбой задачи VsTest.", + "loc.messages.VstestPassedReturnCode": "Задача VsTest выполнена успешно.", + "loc.messages.NoMatchingTestAssemblies": "Не найдены тестовые сборки, соответствующие шаблону: %s.", + "loc.messages.VstestNotFound": "Не удалось найти Visual Studio версии %d. Повторите попытку, используя версию, установленную на компьютере с агентом сборки.", + "loc.messages.NoVstestFound": "Платформа тестирования не найдена. Повторите попытку, установив ее на компьютере с агентом сборки.", + "loc.messages.VstestFailed": "Произошел сбой Vstest. Сведения об ошибках см. в журналах. Возможно, некоторые тесты не были пройдены.", + "loc.messages.VstestTIANotSupported": "Для запуска анализа влияния на тесты установите обновление 3 для Visual Studio 2015 либо Visual Studio 2017 RC или более поздней версии.", + "loc.messages.NoResultsToPublish": "Не найдено результатов для публикации.", + "loc.messages.ErrorWhileReadingRunSettings": "При чтении файла параметров запуска произошла ошибка: %s.", + "loc.messages.ErrorWhileReadingTestSettings": "При чтении файла параметров теста произошла ошибка: %s.", + "loc.messages.RunInParallelNotSupported": "Параллельное выполнение тестов на компьютерах с многоядерными процессорами не поддерживается с файлом параметров теста. Этот параметр будет пропущен.", + "loc.messages.InvalidSettingsFile": "Указанный файл параметров %s не существует или является недопустимым. Укажите допустимый файл параметров или очистите поле.", + "loc.messages.UpdateThreeOrHigherRequired": "Установите Visual Studio 2015 с обновлением 3 или более позднюю версию на компьютере агента сборки для параллельного выполнения тестов.", + "loc.messages.ErrorOccuredWhileSettingRegistry": "При задании раздела реестра произошла ошибка: %s.", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "При задании сборщика данных влияния на тесты в файле параметров теста произошла ошибка.", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "При задании сборщика данных влияния на тесты в файле параметров запуска произошла ошибка.", + "loc.messages.ErrorWhileCreatingResponseFile": "При создании файла ответов произошла ошибка. Для этого запуска будут выполнены все тесты.", + "loc.messages.ErrorWhileUpdatingResponseFile": "При обновлении файла ответов \"%s\" произошла ошибка. Для этого запуска будут выполнены все тесты.", + "loc.messages.ErrorWhilePublishingCodeChanges": "Произошла ошибка при публикации изменений кода. Все тесты будут выполнены для этого запуска.", + "loc.messages.ErrorWhileListingDiscoveredTests": "Ошибка при обнаружении тестов. Для данного запуска будут выполнены все тесты.", + "loc.messages.PublishCodeChangesPerfTime": "Общее время, затраченное на публикацию изменений в коде: %d мс.", + "loc.messages.GenerateResponseFilePerfTime": "Общее время, затраченное на получение файла ответов: %d мс.", + "loc.messages.UploadTestResultsPerfTime": "Общее время, затраченное на отправку результатов тестирования: %d мс.", + "loc.messages.ErrorReadingVstestVersion": "Ошибка при считывании версии vstest.console.exe.", + "loc.messages.UnexpectedVersionString": "Обнаружена неожиданная строка версии для файла vstest.console.exe: %s.", + "loc.messages.UnexpectedVersionNumber": "Обнаружена неожиданная версия файла vstest.console.exe: %s.", + "loc.messages.VstestDiagNotSupported": "Эта версия vstest.console.exe не поддерживает флаг /diag. Включите диагностику в файлах конфигурации exe.config", + "loc.messages.NoIncludePatternFound": "Не найден шаблон включения. Укажите хотя бы один шаблон включения для поиска тестовых сборок.", + "loc.messages.ErrorWhileUpdatingSettings": "Ошибка при обновлении файла параметров. Будет использован указанный файл параметров.", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "Video collector не поддерживается с параметрами выполнения.", + "loc.messages.runTestInIsolationNotSupported": "Выполнение тестов в изолированных процессах не поддерживается при использовании настройки, подразумевающей задание с несколькими агентами. Этот параметр будет пропущен.", + "loc.messages.overrideNotSupported": "Переопределение параметров тестового запуска поддерживается только для допустимого файла runsettings или testsettings. Этот параметр будет пропущен.", + "loc.messages.testSettingPropertiesNotSupported": "К свойствам, указанным в файле testsettings, можно обратиться через TestContext, используя Visual Studio 2017 с обновлением 4 или более поздней версии.", + "loc.messages.vstestVersionInvalid": "Указанная версия платформы тестирования %s не поддерживается.", + "loc.messages.configureDtaAgentFailed": "Настройка агента тестирования на сервере завершилась сбоем даже после нескольких повторных попыток (%d) с ошибкой %s", + "loc.messages.otherConsoleOptionsNotSupported": "Другие параметры консоли не поддерживаются для этой конфигурации задачи. Этот параметр будет проигнорирован.", + "loc.messages.distributedTestWorkflow": "В потоке распределенного тестирования", + "loc.messages.nonDistributedTestWorkflow": "Выполнение тестов с помощью средства выполнения vstest.console.exe.", + "loc.messages.dtaNumberOfAgents": "Распределенное выполнение теста, число агентов в задании: %s", + "loc.messages.testSelectorInput": "Выбранный тест: %s", + "loc.messages.searchFolderInput": "Папка поиска: %s", + "loc.messages.testFilterCriteriaInput": "Критерии фильтра теста: %s", + "loc.messages.runSettingsFileInput": "Файл параметров запуска: %s", + "loc.messages.runInParallelInput": "Запустить параллельно: %s", + "loc.messages.runInIsolationInput": "Запустить изолированно: %s", + "loc.messages.pathToCustomAdaptersInput": "Путь к настраиваемым адаптерам: %s", + "loc.messages.otherConsoleOptionsInput": "Другие параметры консоли: %s", + "loc.messages.codeCoverageInput": "Объем протестированного кода включен: %s", + "loc.messages.testPlanInput": "Идентификатор плана тестирования: %s", + "loc.messages.testplanConfigInput": "Идентификатор конфигурации плана тестирования: %s", + "loc.messages.testSuiteSelected": "Идентификатор выбранного набора тестов: %s", + "loc.messages.testAssemblyFilterInput": "Сборки теста: %s", + "loc.messages.vsVersionSelected": "Версия VisualStudio, выбранная для запуска теста: %s", + "loc.messages.runTestsLocally": "Запускать тесты локально с помощью %s", + "loc.messages.vstestLocationSpecified": "%s, указанное расположение: %s", + "loc.messages.uitestsparallel": "Параллельный запуск тестов пользовательского интерфейса на одном компьютере может привести к ошибкам. Попробуйте отключить параметр \"Запустить параллельно\" или запускать тесты пользовательского интерфейса в отдельной задаче. Дополнительные сведения: https://aka.ms/paralleltestexecution. ", + "loc.messages.pathToCustomAdaptersInvalid": "Путь к пользовательским адаптерам \"%s\" должен быть существующим каталогом.", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "Путь к пользовательским адаптерам \"%s\" не содержит адаптеры теста; укажите допустимый путь.", + "loc.messages.testAssembliesSelector": "Тестовые сборки", + "loc.messages.testPlanSelector": "План тестирования", + "loc.messages.testRunSelector": "Тестовый запуск", + "loc.messages.testRunIdInvalid": "Выбран тест \"Тестовый запуск\", но указанный ИД тестового запуска \"%s\" недопустим", + "loc.messages.testRunIdInput": "Идентификатор тестового запуска: \"%s\"", + "loc.messages.testSourcesFilteringFailed": "Не удалось подготовить исходный файл тестов. Ошибка: %s", + "loc.messages.noTestSourcesFound": "Не удалось обнаружить исходные файлы тестов, соответствующие указанному фильтру \"%s\"", + "loc.messages.DontShowWERUIDisabledWarning": "Если параметр Windows Error Reporting DontShowUI не установлен и в середине выполнения теста графического интерфейса открывается окно ошибок, то тест перестанет отвечать на запросы.", + "loc.messages.noVstestConsole": "Тесты не будут выполняться с помощью консоли vstest. Для запуска тестов с помощью консоли vstest установите Visual Studio 2017 RC или более позднюю версию.", + "loc.messages.numberOfTestCasesPerSlice": "Количество тестовых случаев в пакете: %s", + "loc.messages.invalidTestBatchSize": "Указан недопустимый размер пакета: %s", + "loc.messages.invalidRunTimePerBatch": "Недопустимое время выполнения пакета (с): %s", + "loc.messages.minimumRunTimePerBatchWarning": "Значение \"Время выполнения на пакет (в секундах)\" должно быть не менее \"%s\" сек. По умолчанию используется минимальное поддерживаемое значение.", + "loc.messages.RunTimePerBatch": "Время выполнения пакета (с): %s", + "loc.messages.searchLocationNotDirectory": "Папка поиска \"%s\" должна представлять собой существующий каталог.", + "loc.messages.rerunFailedTests": "Повтор неудачных тестов: %s", + "loc.messages.rerunFailedThreshold": "Предел повтора неудачных тестов: %s", + "loc.messages.invalidRerunFailedThreshold": "Недопустимый порог повтора неудачных тестов. Используется значение по умолчанию: 30%", + "loc.messages.rerunFailedTestCasesMaxLimit": "Максимальный предел повтора неудачных тестовых случаев: %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "Недопустимый предел числа повтора неудачных тестов. Используется значение по умолчанию: 5", + "loc.messages.rerunMaxAttempts": "Максимальное число повторов: %s", + "loc.messages.invalidRerunMaxAttempts": "Максимальное число попыток повтора недопустимо или превышено, используется значение по умолчанию: 3", + "loc.messages.rerunNotSupported": "Для повтора неудачных тестов установите Visual Studio 2015 с обновлением 3 или Visual Studio 2017.", + "loc.messages.toolsInstallerPathNotSet": "Папка платформы тестирования VsTest не найдена в кэше.", + "loc.messages.testImpactAndCCWontWork": "Средство сбора данных о влиянии на тесты (запускать только затронутые тесты) и сбора данных о покрытии кода не будет работать.", + "loc.messages.ToolsInstallerInstallationError": "Установщик инструментов платформы тестирования Visual Studio не был запущен, или установка не завершена успешно. Сведения об использовании установщика инструментов см. в блоге: https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "Переопределение поля UseVerifiableInstrumentation значением false в файле runsettings.", + "loc.messages.NoTestResultsDirectoryFound": "Каталог результатов теста не найден.", + "loc.messages.OnlyWindowsOsSupported": "Эта задача поддерживается только в агентах Windows и не может использоваться на других платформах.", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "Запуск по требованию не поддерживается для параметра Multi-Configuration. Используйте вариант параллелизма \"Нет\" или \"Несколько агентов\".", + "loc.messages.disabledRerun": "Отключается перезапуск тестов со сбоями, так как пороговое значение перезапуска — %s.", + "loc.messages.UpgradeAgentMessage": "Обновите версию агента. https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "Свойство VsTestVersion равно null или пусто", + "loc.messages.UserProvidedSourceFilter": "Фильтр источника: %s", + "loc.messages.UnableToGetFeatureFlag": "Не удалось получить флаг компонента: %s", + "loc.messages.diagnosticsInput": "Диагностика включена: %s", + "loc.messages.UncPathNotSupported": "Путь к папке поиска источников тестов не может быть UNC-путем. Укажите корневой путь или путь относительно $(System.DefaultWorkingDirectory).", + "loc.messages.LookingForBuildToolsInstalltion": "Выполняется попытка найти vstest.console из установки Visual Studio Build Tools с версией %s.", + "loc.messages.LookingForVsInstalltion": "Выполняется попытка найти vstest.console из установки Visual Studio с версией %s.", + "loc.messages.minTestsNotExecuted": "Указанное минимальное количество тестов %d не было выполнено в рамках тестового запуска.", + "loc.messages.actionOnThresholdNotMet": "Действие при несоблюдении минимального порога тестов: %s", + "loc.messages.minimumExpectedTests": "Ожидаемое минимальное число выполняемых тестов: %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Strings/resources.resjson/zh-CN/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/zh-CN/resources.resjson new file mode 100644 index 000000000000..3624a91e666e --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/zh-CN/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Visual Studio 测试", + "loc.helpMarkDown": "[详细了解此任务](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "使用 Visual Studio Test (VsTest)运行程序运行单元测试和功能测试(Selenium、Appium、编码的 UI 测试等)。可以运行 MsTest、xUnit、NUnit、Chutzpah (适用于使用 QUnit、Mocha 和 Jasmine 的 JavaScript 测试)等具有 Visual Studio 测试适配器的测试框架。使用此任务(版本 2)可使测试分布在多个代理上。", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
                          • 使用代理作业运行测试: 跨生成、版本和测试的统一代理也允许将自动代理用于测试目的。可使用多代理作业设置来分配测试。可使用多配置作业设置来复制不同配置中的测试。详细信息
                          • 测试影响分析: 自动选择和运行仅验证代码更改所需的测试。
                          • 使用 Visual Studio 测试平台安装程序任务运行测试,而无需完整地安装 Visual Studio。
                          ", + "loc.group.displayName.testSelection": "测试选择", + "loc.group.displayName.executionOptions": "执行选项", + "loc.group.displayName.advancedExecutionOptions": "高级执行选项", + "loc.group.displayName.reportingOptions": "报告选项", + "loc.input.label.testSelector": "通过以下方式选择测试", + "loc.input.help.testSelector": "
                          • 测试程序集: 使用此选项指定包含你的测试的一个或多个测试程序集。你可以有选择性地指定筛选条件以仅选择特定测试。
                          • 测试计划: 使用此选项从具有与之关联的自动测试方法的测试计划中运行测试。
                          • 测试运行: 在设置环境以从测试中心运行测试时,使用此选项。在持续集成 / 持续部署(CI/CD)管道中运行测试时,不应使用此选项。
                          • ", + "loc.input.label.testAssemblyVer2": "测试文件", + "loc.input.help.testAssemblyVer2": "从指定的文件运行测试。
                            可通过分别指定 .orderedtest 和 .webtest 文件来运行顺序测试和 Web 测试。若要运行 .webtest,需要 Visual Studio 2017 Update 4 或更高版本。

                            文件路径相对于搜索文件夹。支持多行 minimatch 模式。[详细信息](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "测试计划", + "loc.input.help.testPlan": "选择包含测试套件和自动测试用例的测试计划。", + "loc.input.label.testSuite": "测试套件", + "loc.input.help.testSuite": "选择一个或多个包含自动测试用例的测试套件。测试用例工作项必须与自动测试方法关联。[了解详细信息。](https://go.microsoft.com/fwlink/?linkid=847773", + "loc.input.label.testConfiguration": "测试配置", + "loc.input.help.testConfiguration": "选择测试配置。", + "loc.input.label.tcmTestRun": "测试运行", + "loc.input.help.tcmTestRun": "从测试中心触发自动测试运行时,使用基于测试运行的选项。该选项不可用于在 CI/CD 管道中运行测试。", + "loc.input.label.searchFolder": "搜索文件夹", + "loc.input.help.searchFolder": "用于搜索测试程序集的文件夹。", + "loc.input.label.resultsFolder": "测试结果文件夹", + "loc.input.help.resultsFolder": "用于存储测试结果的文件夹。未指定此输入时,结果默认存储在 $(Agent.TempDirectory)/TestResults 中,将在管道运行结束时对其进行清除。在测试运行之前,将始终在启动 vstest 时清除结果目录。相对文件夹路径(若提供)将被视为相对于 $(Agent.TempDirectory) 的路径", + "loc.input.label.testFiltercriteria": "测试筛选器标准", + "loc.input.help.testFiltercriteria": "从测试程序集中筛选测试的其他条件。例如: \"Priority=1|Name=MyTestMethod\"。[详细信息](https://msdn.microsoft.com/zh-cn/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "仅运行受影响的测试", + "loc.input.help.runOnlyImpactedTests": "自动选择和仅运行验证代码更改所需的测试。[详细信息](https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "运行所有测试前的生成数", + "loc.input.help.runAllTestsAfterXBuilds": "自动运行所有测试前的生成数。测试影响分析存储测试用例和源代码间的映射。建议通过定期运行所有测试来重新生成映射。", + "loc.input.label.uiTests": "测试组合包含 UI 测试", + "loc.input.help.uiTests": "若要运行 UI 测试,请确保将代理设置为在交互模式下运行。必须在对生成/发布进行排队之前,将代理设置为交互运行。选中此框不会自动在交互模式下配置代理。任务中的此选项仅作为对代理进行相应配置的提醒,以避免发生故障。

                            VS 2015 和 2017 池中的托管 Windows 代理可用于运行 UI 测试。
                            [详细信息](https://aka.ms/uitestmoreinfo)。", + "loc.input.label.vstestLocationMethod": "通过以下方式选择测试平台", + "loc.input.label.vsTestVersion": "测试平台版本", + "loc.input.help.vsTestVersion": "要使用的 Visual Studio 测试的版本。如果指定了最新版本,则会根据安装的内容选择从 VS2022 开始的最新 Visual Studio 版本,后跟 VS2019、VS2017 和 VS2015。不支持 Visual Studio 2013。若要运行测试而无需在代理上 Visual Studio,请使用“按工具安装安装程序”选项。请务必包括“Visual Studio 测试平台安装程序”任务,以便从 nuget 获取测试平台。", + "loc.input.label.vstestLocation": "vstest.console.exe 的路径", + "loc.input.help.vstestLocation": "可以提供 VSTest 的路径。", + "loc.input.label.runSettingsFile": "设置文件", + "loc.input.help.runSettingsFile": "要用于测试的 runsettings 或 testsettings 文件的路径。", + "loc.input.label.overrideTestrunParameters": "替代测试运行参数", + "loc.input.help.overrideTestrunParameters": "重写 runsettings 文件 `TestRunParameters` 部分或 testsettings 文件 `Properties` 部分中定义的参数。例如: `-key1 value1 -key2 value2`。注意: testsettings 文件中指定的属性可以通过使用 Visual Studio 2017 Update 4 或更高版本经由 TestContext 进行访问 ", + "loc.input.label.pathtoCustomTestAdapters": "自定义测试适配器的路径", + "loc.input.help.pathtoCustomTestAdapters": "自定义测试适配器的目录路径。可自动发现与测试程序集位于同一文件夹中的适配器。", + "loc.input.label.runInParallel": "在多核计算机上并行运行测试", + "loc.input.help.runInParallel": "设置后,测试将利用计算机的可用内核并行运行。如果在运行设置文件中指定,则这会替代 MaxCpuCount。[单击此处](https://aka.ms/paralleltestexecution)了解有关如何并行运行测试的详细信息。", + "loc.input.label.runTestsInIsolation": "以隔离方式运行测试", + "loc.input.help.runTestsInIsolation": "在隔离的进程中运行测试。这将减小 vstest.console.exe 进程因测试出错而停止的可能性,但可能降低测试运行速度。目前不支持在使用多代理作业设置运行时使用此选项。", + "loc.input.label.codeCoverageEnabled": "代码覆盖率已启用", + "loc.input.help.codeCoverageEnabled": "通过测试运行收集代码覆盖率信息。", + "loc.input.label.otherConsoleOptions": "其他控制台选项", + "loc.input.help.otherConsoleOptions": "可传递给 vstest.console.exe 的其他控制台选项,如此处所述。

                            使用代理作业的“多代理”平行设置运行测试、使用“测试计划”或“测试运行”选项运行测试或已选择自定义批处理选项时,这些选项不受支持且会被忽略。可改用设置文件指定这些选项。

                            ", + "loc.input.label.distributionBatchType": "批处理测试", + "loc.input.help.distributionBatchType": "批处理是一组测试。测试的批处理同时运行其测试,并且会发布该批处理的结果。如果将运行任务的作业设置为使用多个代理,那么每个代理可选取任意可用的测试批处理来并行运行。

                            基于测试和代理的数量: 基于参与测试运行的测试数和代理数的简单批处理。

                            基于以前的测试运行时间: 此类批处理会参考以前的运行时间来创建测试的批处理,以便每个批处理的运行时间大致相同。

                            基于测试程序集: 同一程序集中的测试将一同进行批处理。", + "loc.input.label.batchingBasedOnAgentsOption": "批处理选项", + "loc.input.help.batchingBasedOnAgentsOption": "基于参与测试运行的测试数和代理数的简单批处理。当自动确定批处理大小时,每个批处理将包含 `(测试总数/代理数)` 个测试。如果指定批处理大小,每个批处理将包含指定数量的测试。", + "loc.input.label.customBatchSizeValue": "每个批处理的测试数", + "loc.input.help.customBatchSizeValue": "指定批处理大小", + "loc.input.label.batchingBasedOnExecutionTimeOption": "批处理选项", + "loc.input.help.batchingBasedOnExecutionTimeOption": "此类批处理会参考以前的运行时间来创建测试的批处理,以便每个批处理的运行时间大致相同。快速运行的测试将同时进行批处理,而长时间运行的测试可能单独进行批处理。将此选项与多代理作业设置结合使用时,可最大限度缩短总测试时间。", + "loc.input.label.customRunTimePerBatchValue": "每个批处理的运行时间(秒)", + "loc.input.help.customRunTimePerBatchValue": "指定每个批处理的运行时间(秒)", + "loc.input.label.dontDistribute": "如果作业中使用多个代理,请复制测试而不是分发测试", + "loc.input.help.dontDistribute": "在多代理作业中运行任务时,选择此选项将不会向所有代理分发测试。
                            每个所选测试将在每个代理上重复。
                            将代理作业配置为不可并行运行或使用多配置选项运行时,此选项不适用。", + "loc.input.label.testRunTitle": "测试运行标题", + "loc.input.help.testRunTitle": "为测试运行提供一个名称。", + "loc.input.label.platform": "生成平台", + "loc.input.help.platform": "应对其报告测试的生成平台。如果在生成任务中为平台定义了变量,请在此处使用该变量。", + "loc.input.label.configuration": "生成配置", + "loc.input.help.configuration": "应对其报告测试的生成配置。如果在生成任务中为配置定义了变量,请在此处使用该变量。", + "loc.input.label.publishRunAttachments": "上传测试附件", + "loc.input.help.publishRunAttachments": "选择加入/退出发布运行级别附件。", + "loc.input.label.failOnMinTestsNotRun": "如果未运行最低数量的测试,则任务失败。", + "loc.input.help.failOnMinTestsNotRun": "选择此选项时,如果未运行指定最低数量的测试,任务将会失败。", + "loc.input.label.minimumExpectedTests": "最小测试数量", + "loc.input.help.minimumExpectedTests": "指定为使任务成功运行而应运行的最小测试数量。已执行的测试总数是已通过、已失败和已中止的测试数之和。", + "loc.input.label.diagnosticsEnabled": "出现灾难性故障时收集高级诊断", + "loc.input.help.diagnosticsEnabled": "出现灾难性故障时收集高级诊断。", + "loc.input.label.collectDumpOn": "收集进程转储并附加到测试运行报告", + "loc.input.help.collectDumpOn": "收集进程转储并附加到测试运行报告。", + "loc.input.label.rerunFailedTests": "重新运行失败的测试", + "loc.input.help.rerunFailedTests": "选择此选项将返回任何失败的测试,直到测试通过或达到最大尝试次数。", + "loc.input.label.rerunType": "如果测试失败次数超过指定的阈值,则不重新运行", + "loc.input.help.rerunType": "使用此选项可避免失败率超出指定阈值时重新运行测试。这适用于任何环境问题将导致大规模故障的情况。
                            可以指定失败百分比或失败测试数作为阈值。", + "loc.input.label.rerunFailedThreshold": "失败百分比", + "loc.input.help.rerunFailedThreshold": "使用此选项可避免失败率超出指定阈值时重新运行测试。这适用于任何环境问题将导致大规模故障的情况。", + "loc.input.label.rerunFailedTestCasesMaxLimit": "失败的测试数", + "loc.input.help.rerunFailedTestCasesMaxLimit": "使用此选项可避免失败的测试用例数超出指定的限制时重新运行测试。这适用于任何环境问题将导致大规模故障的情况。", + "loc.input.label.rerunMaxAttempts": "最大尝试次数", + "loc.input.help.rerunMaxAttempts": "指定失败测试的最大重试次数。如果测试在达到最大尝试次数前通过,将不再重新运行。", + "loc.messages.VstestLocationDoesNotExist": "指定的 \"vstest.console.exe\" 的位置 \"%s\" 不存在。", + "loc.messages.VstestFailedReturnCode": "VsTest 任务失败。", + "loc.messages.VstestPassedReturnCode": "VsTest 任务成功。", + "loc.messages.NoMatchingTestAssemblies": "找不到与模式 %s 匹配的程序集。", + "loc.messages.VstestNotFound": "找不到 Visual Studio %d。请使用生成代理计算机上存在的版本重试。", + "loc.messages.NoVstestFound": "找不到测试平台。请在生成代理计算机上安装它,然后重试。", + "loc.messages.VstestFailed": "Vstest 失败,出现错误。请检查日志是否具有失败信息。其中可能具有失败的测试。", + "loc.messages.VstestTIANotSupported": "安装 Visual Studio 2015 update 3 或 Visual Studio 2017 RC 或更高版本,以运行测试影响分析。", + "loc.messages.NoResultsToPublish": "找不到要发布的结果。", + "loc.messages.ErrorWhileReadingRunSettings": "在读取运行设置文件时发生错误。错误: %s。", + "loc.messages.ErrorWhileReadingTestSettings": "在读取测试设置文件时发生错误。错误: %s。", + "loc.messages.RunInParallelNotSupported": "testsettings 文件不支持在多核计算机上并行运行测试。将忽略此选项。", + "loc.messages.InvalidSettingsFile": "指定的设置文件 %s 无效或不存在。请提供有效的设置文件或清除此字段。", + "loc.messages.UpdateThreeOrHigherRequired": "在生成代理计算机上安装 Visual Studio 2015 Update 3 或更高版本,以便并行运行测试。", + "loc.messages.ErrorOccuredWhileSettingRegistry": "在设置注册表项时发生错误,错误: %s。", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "在测试设置文件中设置测试影响收集器时发生错误。", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "在运行设置文件中设置测试影响收集器时发生错误。", + "loc.messages.ErrorWhileCreatingResponseFile": "在创建响应文件时发生错误。将对此运行执行所有的测试。", + "loc.messages.ErrorWhileUpdatingResponseFile": "在更新响应文件 \"%s\" 时发生错误。将对此运行执行所有的测试。", + "loc.messages.ErrorWhilePublishingCodeChanges": "发布代码更改时出错。将对此运行执行所有的测试。", + "loc.messages.ErrorWhileListingDiscoveredTests": "查找测试时发生错误。将为此运行执行所有测试。", + "loc.messages.PublishCodeChangesPerfTime": "发布代码更改所用的总时间: %d 毫秒。", + "loc.messages.GenerateResponseFilePerfTime": "获取响应文件所用的总时间: %d 毫秒。", + "loc.messages.UploadTestResultsPerfTime": "上传测试结果所花的总时间: %d 毫秒。", + "loc.messages.ErrorReadingVstestVersion": "读取 vstest.console.exe 的版本时出错。", + "loc.messages.UnexpectedVersionString": "检测到 vstest.console.exe 的意外版本字符串: %s。", + "loc.messages.UnexpectedVersionNumber": "检测到 vstest.console.exe 的意外版本号: %s。", + "loc.messages.VstestDiagNotSupported": "vstest.console.exe 版本不支持 /diag 标记。请通过 exe.config 文件启用诊断", + "loc.messages.NoIncludePatternFound": "找不到包含模式。请指定至少一个包含模式以搜索测试程序集。", + "loc.messages.ErrorWhileUpdatingSettings": "更新设置文件时出错。请使用指定的设置文件。", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "运行设置不支持 Video collector。", + "loc.messages.runTestInIsolationNotSupported": "使用多代理作业设置时不支持隔离运行测试。将忽略此选项。", + "loc.messages.overrideNotSupported": "只有有效的 runsettings 或 testsettings 文件支持重写测试运行参数。将忽略此选项。", + "loc.messages.testSettingPropertiesNotSupported": "testsettings 文件中指定的属性可以通过使用 Visual Studio 2017 Update 4 或更高版本经由 TestContext 进行访问", + "loc.messages.vstestVersionInvalid": "不支持给定的测试平台版本 %s。", + "loc.messages.configureDtaAgentFailed": "使用服务器配置测试代理在重试 %d 次后失败,错误: %s", + "loc.messages.otherConsoleOptionsNotSupported": "此任务配置不支持其他控制台选项。此选项将被忽略。", + "loc.messages.distributedTestWorkflow": "在已发布测试流中", + "loc.messages.nonDistributedTestWorkflow": "使用 vstest.console.exe 运行程序运行测试。", + "loc.messages.dtaNumberOfAgents": "已发布测试执行,作业中的代理数: %s", + "loc.messages.testSelectorInput": "测试选择器: %s", + "loc.messages.searchFolderInput": "搜索文件夹: %s", + "loc.messages.testFilterCriteriaInput": "测试筛选器条件: %s", + "loc.messages.runSettingsFileInput": "运行设置文件: %s", + "loc.messages.runInParallelInput": "并行运行: %s", + "loc.messages.runInIsolationInput": "隔离运行: %s", + "loc.messages.pathToCustomAdaptersInput": "自定义适配器的路径: %s", + "loc.messages.otherConsoleOptionsInput": "其他控制台选项: %s", + "loc.messages.codeCoverageInput": "代码覆盖率已启用: %s", + "loc.messages.testPlanInput": "测试计划 ID: %s", + "loc.messages.testplanConfigInput": "测试计划配置 ID: %s", + "loc.messages.testSuiteSelected": "所选的测试套件 ID: %s", + "loc.messages.testAssemblyFilterInput": "测试程序集: %s", + "loc.messages.vsVersionSelected": "选择进行测试执行的 VisualStudio 版本: %s", + "loc.messages.runTestsLocally": "使用 %s 本地运行测试", + "loc.messages.vstestLocationSpecified": "%s,指定位置: %s", + "loc.messages.uitestsparallel": "在同一计算机上并行运行 UI 测试可能导致错误。请考虑禁用“并行运行”选项或使用单独任务运行 UI 测试。有关详细信息,请参阅 https://aka.ms/paralleltestexecution", + "loc.messages.pathToCustomAdaptersInvalid": "自定义适配器 \"%s\" 的路径应该是一个目录,且该目录应该存在。", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "自定义适配器 \"%s\" 的路径不包含任何测试适配器,请提供一个有效的路径。", + "loc.messages.testAssembliesSelector": "测试程序集", + "loc.messages.testPlanSelector": "测试计划", + "loc.messages.testRunSelector": "测试运行", + "loc.messages.testRunIdInvalid": "选择的测试是“测试运行”,但给出的测试运行 ID“%s”无效", + "loc.messages.testRunIdInput": "测试运行 ID:“%s”", + "loc.messages.testSourcesFilteringFailed": "准备测试源文件失败。错误: %s", + "loc.messages.noTestSourcesFound": "未找到匹配给定筛选器“%s”的测试源", + "loc.messages.DontShowWERUIDisabledWarning": "未设置 Windows Error Reporting DontShowUI,如果执行 UI 测试的过程中弹出 Windows 错误对话,则该测试会挂起", + "loc.messages.noVstestConsole": "不能使用 VSTest 控制台执行测试。请安装 Visual Studio 2017 RC 或以上版本以通过 VSTest 控制台运行测试。", + "loc.messages.numberOfTestCasesPerSlice": "每个批处理的测试用例数: %s", + "loc.messages.invalidTestBatchSize": "提供的批处理大小无效: %s", + "loc.messages.invalidRunTimePerBatch": "“每个批处理的运行时间(秒)”无效: %s", + "loc.messages.minimumRunTimePerBatchWarning": "“每个批处理的运行时间(秒)”应至少为“%s”秒。默认为支持的最小值。", + "loc.messages.RunTimePerBatch": "每个批处理的运行时间(秒): %s", + "loc.messages.searchLocationNotDirectory": "搜索文件夹“%s”应该是一个目录,且该目录应该存在。", + "loc.messages.rerunFailedTests": "重新运行失败的测试: %s", + "loc.messages.rerunFailedThreshold": "重新运行失败的测试阈值: %s", + "loc.messages.invalidRerunFailedThreshold": "重新运行失败的测试阈值无效,默认值为 30%", + "loc.messages.rerunFailedTestCasesMaxLimit": "重新运行失败测试案例的最大限制: %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "重新运行失败的测试用例限制无效,默认值为 5", + "loc.messages.rerunMaxAttempts": "重新运行的最大尝试次数: %s", + "loc.messages.invalidRerunMaxAttempts": "无效/已超过重新运行的最大尝试次数,默认值为 3", + "loc.messages.rerunNotSupported": "安装 Visual Studio 2015 update 3 或 Visual Studio 2017,重新运行失败的测试。", + "loc.messages.toolsInstallerPathNotSet": "缓存中找不到 VsTest 测试平台文件夹。", + "loc.messages.testImpactAndCCWontWork": "测试影响(仅运行受影响的测试)和代码覆盖率数据收集器不起作用。", + "loc.messages.ToolsInstallerInstallationError": "Visual Studio 测试平台工具安装程序未运行或未成功完成安装,请参考以下博客,了解如何使用该工具安装程序: https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "在 runsettings 文件中,将 UseVerifiableInstrumentation 字段替代为 false。", + "loc.messages.NoTestResultsDirectoryFound": "找不到测试结果目录。", + "loc.messages.OnlyWindowsOsSupported": "此任务仅在 Windows 代理上受支持,而无法用于其他平台。", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "“多配置”选项不支持按需运行。请使用“无”或“多代理”并行选项。", + "loc.messages.disabledRerun": "由于提供的重新运行阈值为 %s,因此禁用重新运行失败的测试", + "loc.messages.UpgradeAgentMessage": "请升级代理版本。https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "VsTestVersion 为 null 或为空", + "loc.messages.UserProvidedSourceFilter": "源筛选器: %s", + "loc.messages.UnableToGetFeatureFlag": "无法获取功能标志: %s", + "loc.messages.diagnosticsInput": "已启用诊断: %s", + "loc.messages.UncPathNotSupported": "测试资源搜索文件夹的路径不能是 UNC 路径。请提供根路径或相对于 $(System.DefaultWorkingDirectory)的路径。", + "loc.messages.LookingForBuildToolsInstalltion": "尝试从版本为 %s 的 Visual Studio 生成工具安装中查找 vstest.console。", + "loc.messages.LookingForVsInstalltion": "尝试从版本为 %s 的 Visual Studio 安装中查找 vstest.console。", + "loc.messages.minTestsNotExecuted": "测试运行中未执行所指定的最低数量的测试 %d。", + "loc.messages.actionOnThresholdNotMet": "未达到最低测试阈值时的操作: %s", + "loc.messages.minimumExpectedTests": "应运行的最小测试数量: %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Strings/resources.resjson/zh-TW/resources.resjson b/_generated/VsTestV2/Strings/resources.resjson/zh-TW/resources.resjson new file mode 100644 index 000000000000..395baf2e31ef --- /dev/null +++ b/_generated/VsTestV2/Strings/resources.resjson/zh-TW/resources.resjson @@ -0,0 +1,193 @@ +{ + "loc.friendlyName": "Visual Studio 測試", + "loc.helpMarkDown": "[深入了解此工作](https://go.microsoft.com/fwlink/?LinkId=835764)", + "loc.description": "使用 Visual Studio Test (VsTest) 執行器來執行單元和功能測試 (Selenium、Appium、自動程式化 UI 測試等)。可以執行具有 Visual Studio 測試配接器的測試架構,例如 MsTest、xUnit、NUnit、Chutzpah (適用於使用 QUnit、Mocha 和 Jasmine 的 JavaScript 測試) 等。使用此工作可讓測試分散在多個代理程式 (第 2 版)。", + "loc.instanceNameFormat": "VsTest - $(testSelector)", + "loc.releaseNotes": "
                            • 使用代理程式作業執行測試: 建置、發行與測試的統一代理程式可讓自動化代理程式也用來進行測試。您可以使用多代理程式作業設定來散發測試。多組態作業設定可用來在不同的組態中複寫測試。詳細資訊
                            • 測試影響分析: 僅自動選取和執行驗證程式碼變更所需的測試。
                            • 使用 Visual Studio 測試平台安裝程式工作不需完整安裝 Visual Studio,就可執行測試。
                            ", + "loc.group.displayName.testSelection": "測試選取項目", + "loc.group.displayName.executionOptions": "執行選項", + "loc.group.displayName.advancedExecutionOptions": "進階執行選項", + "loc.group.displayName.reportingOptions": "報告選項", + "loc.input.label.testSelector": "選取測試,使用", + "loc.input.help.testSelector": "
                            • 測試組件: 使用此選項可指定一或多個包含您測試的測試組件。您可選擇性地指定篩選準則,只選取特定的測試。
                            • 測試計劃: 使用此選項可從已與自動化測試方法相關聯的測試計劃,執行測試。
                            • 測試回合: 當您想要設定環境以從測試中樞執行測試時,請使用此選項。在持續整合/持續部署 (CI/CD) 管線中執行測試時,不應使用此選項。
                            • ", + "loc.input.label.testAssemblyVer2": "測試檔案", + "loc.input.help.testAssemblyVer2": "從指定的檔案執行測試。
                              分別指定 .orderedtest 與 .webtest 檔案即可執行已排序的測試與 Web 效能測試。若要執行 .webtest,需要 Visual Studio 2017 Update 4 或更高版本。

                              檔案路徑會相對於搜尋資料夾。支援多行 minimatch 模式。[詳細資訊](https://aka.ms/minimatchexamples)", + "loc.input.label.testPlan": "測試計劃", + "loc.input.help.testPlan": "選取含有測試套件的測試計劃,這些套件具有自動化測試案例。", + "loc.input.label.testSuite": "測試套件", + "loc.input.help.testSuite": "選取一或多個含有自動化測試案例的測試套件。測試案例工作項目必須與自動化測試方法相關聯。[深入了解。](https://go.microsoft.com/fwlink/?linkid=847773", + "loc.input.label.testConfiguration": "測試組態", + "loc.input.help.testConfiguration": "選取測試組態。", + "loc.input.label.tcmTestRun": "測試回合", + "loc.input.help.tcmTestRun": "當從測試中樞觸發自動化測試回合時,會使用測試回合相關的選項。執行 CI/CD 管線中的測試時,無法使用此選項。", + "loc.input.label.searchFolder": "搜尋資料夾", + "loc.input.help.searchFolder": "要在其中搜尋測試組件的資料夾。", + "loc.input.label.resultsFolder": "測試結果資料夾", + "loc.input.help.resultsFolder": "儲存測試結果的資料夾。若未指定此輸入,根據預設會將結果儲存在 $(Agent.TempDirectory)/TestResults 中,管線執行結束後會予以清除。執行測試前,一律會在 vstest 工作開始時清除結果目錄。如果提供相對資料夾路徑,則會視為相對於 $(Agent.TempDirectory) 的路徑", + "loc.input.label.testFiltercriteria": "測試篩選準則", + "loc.input.help.testFiltercriteria": "從測試組件篩選測試的其他準則。例如: `Priority=1|Name=MyTestMethod`。[詳細資訊](https://msdn.microsoft.com/zh-tw/library/jj155796.aspx)", + "loc.input.label.runOnlyImpactedTests": "僅執行受影響的測試", + "loc.input.help.runOnlyImpactedTests": "自動選取,並僅執行驗證程式碼變更所需的測試。[詳細資訊](https://aka.ms/tialearnmore)", + "loc.input.label.runAllTestsAfterXBuilds": "所有測試應在建置多少次後執行", + "loc.input.help.runAllTestsAfterXBuilds": "在這之後要自動執行所有測試的組建數目。測試影響分析會儲存測試案例和原始程式碼之間的對應。建議您定期執行所有測試以重新產生對應。", + "loc.input.label.uiTests": "測試混合包含 UI 測試", + "loc.input.help.uiTests": "若要執行 UI 測試,請確認代理程式已設定為在互動式模式中執行。再將組建 / 版本排入佇列前,必須先將代理程式設定為互動式執行。選取此方塊不會自動將代理程式設定為互動式模式。此選項在工作中僅作為適當設定代理程式以避免失敗的提醒。

                              VS 2015 和 2017 集區的託管 Windows 代理程式可用來執行 UI 測試。
                              [詳細資訊](https://aka.ms/uitestmoreinfo)。", + "loc.input.label.vstestLocationMethod": "選取測試平台,使用", + "loc.input.label.vsTestVersion": "測試平台版本", + "loc.input.help.vsTestVersion": "要使用的 Visual Studio 測試版本。若指定最新版本,它會選擇最新的 Visual Studio 版本,從 VS2022 開始,然後是 VS2019、VS2017 和 VS2015,具體取決於安裝的版本。不支援 Visual Studio 2013。若希望在代理程式上沒有 Visual Studio 時也能執行測試,請使用 [由工具安裝程式安裝] 選項。請務必包含 [Visual Studio 測試平台安裝程式] 工作以從 NuGet 取得測試平台。", + "loc.input.label.vstestLocation": "vstest.console.exe 的路徑", + "loc.input.help.vstestLocation": "選擇性地提供 VSTest 的路徑。", + "loc.input.label.runSettingsFile": "設定檔案", + "loc.input.help.runSettingsFile": "要在測試中使用之 runsettings 或 testsettings 檔案的路徑。", + "loc.input.label.overrideTestrunParameters": "覆寫測試回合參數", + "loc.input.help.overrideTestrunParameters": "覆寫在 runsettings 檔案 `TestRunParameters` 區段或 testsettings 檔案的 `Properties` 區段中定義的參數。例如: `-key1 value1 -key2 value2`。注意: 在 testsettings 檔案中指定的屬性可以透過使用 Visual Studio 2017 Update 4 更高版本的 TestContext 存取 ", + "loc.input.label.pathtoCustomTestAdapters": "自訂測試配接器的路徑", + "loc.input.help.pathtoCustomTestAdapters": "自訂測試配接器的目錄路徑。自動探索與測試組件在同一個資料夾內的配接器。", + "loc.input.label.runInParallel": "在多核心電腦上平行執行測試", + "loc.input.help.runInParallel": "如有設定,將會運用機器所能使用的核心數,平行執行測試。這會覆寫 RunSettings 檔案中指定的 MaxCpuCount。如需深入了解如何平行執行測試,[請按一下這裡](https://aka.ms/paralleltestexecution)。", + "loc.input.label.runTestsInIsolation": "獨立執行測試", + "loc.input.help.runTestsInIsolation": "在獨立的處理序中執行測試。這有利於降低 vstest.console.exe 處理序在測試發生錯誤時停止的可能性,但測試的速度可能會變慢。目前,這個選項無法在使用多重代理程式作業設定執行時使用。", + "loc.input.label.codeCoverageEnabled": "程式碼涵蓋範圍已啟用", + "loc.input.help.codeCoverageEnabled": "從測試回合收集程式碼涵蓋範圍資訊。", + "loc.input.label.otherConsoleOptions": "其他主控台選項", + "loc.input.help.otherConsoleOptions": "可傳遞至 vstest.console.exe 的其他主控台選項,如這裡所述。

                              這些選項不受支援,而且會在使用代理程式作業的 [多重代理程式] 平行設定執行測試時,或於自訂批次選項受到選取時使用 [測試計劃]/[測試回合] 選項執行測試時予以忽略。可改用設定檔案指定這些選項。

                              ", + "loc.input.label.distributionBatchType": "批次測試", + "loc.input.help.distributionBatchType": "批次是一組測試。測試批次會同時執行其測試,然後為該批次發佈結果。若工作執行所在的作業設定為使用多個代理程式,每個代理程式會挑選任何可用測試批次來平行執行。

                              依測試和代理程式的數目分批: 簡易批次,依參與測試回合的測試和代理程式數目分批。

                              依過去的測試執行時間分批: 這會考量過去的執行時間來建立測試批次,使每個批次的執行時間都大概相等。

                              依測試組件分批: 來自同一個組件的測試分在同一批。", + "loc.input.label.batchingBasedOnAgentsOption": "批次選項", + "loc.input.help.batchingBasedOnAgentsOption": "以測試回合中參與的測試數及代理程式數為依據的簡易批次。在自動判斷批次大小時,每個批次各包含 `(測試總數 / 代理程式數)` 個測試。如果指定了批次大小,每個批次各包含指定的測試數。", + "loc.input.label.customBatchSizeValue": "各批次的測試數", + "loc.input.help.customBatchSizeValue": "指定批次大小", + "loc.input.label.batchingBasedOnExecutionTimeOption": "批次選項", + "loc.input.help.batchingBasedOnExecutionTimeOption": "此批次會考量過去的執行時間來建立測試批次,如此一來,每個批次就會有幾乎相等的執行時間。快速執行的測試會放在同一批次,而執行時間較長的測試可能另屬不同批次。搭配多重代理程式作業設定使用此選項時,會將測試時間總計降到最低。", + "loc.input.label.customRunTimePerBatchValue": "各批次的執行時間 (秒)", + "loc.input.help.customRunTimePerBatchValue": "指定各批次執行時間 (秒)", + "loc.input.label.dontDistribute": "在作業中使用多代理程式時複寫測試,而不散發", + "loc.input.help.dontDistribute": "選擇此選項不會在工作正於多代理程式作業中執行時,在代理程式間散發測試。
                              選取的每個測試都會在每個代理程式上重複執行。
                              當代理程式作業已設定為不使用平行處理或多組態選項執行時,不適用此選項。", + "loc.input.label.testRunTitle": "測試回合標題", + "loc.input.help.testRunTitle": "提供測試回合的名稱。", + "loc.input.label.platform": "組建平台", + "loc.input.help.platform": "測試應回報的建置平台。若您已為您的建置工作平台定義了設定變數,請在此使用。", + "loc.input.label.configuration": "組建設定", + "loc.input.help.configuration": "測試應回報的建置設定。若您已為您的建置工作定義了設定變數,請在此使用。", + "loc.input.label.publishRunAttachments": "上傳測試附件", + "loc.input.help.publishRunAttachments": "選擇加入/退出發行測試回合層級附件。", + "loc.input.label.failOnMinTestsNotRun": "如未執行到最小測試數,就會讓工作失敗。", + "loc.input.help.failOnMinTestsNotRun": "選取此選項後,如未執行到指定的最小測試數,就會讓工作失敗。", + "loc.input.label.minimumExpectedTests": "最小測試數", + "loc.input.help.minimumExpectedTests": "指定最少應執行多少測試,工作才會成功。執行的測試總數為通過、失敗及中止的測試數總和。", + "loc.input.label.diagnosticsEnabled": "在發生嚴重失敗時收集進階診斷", + "loc.input.help.diagnosticsEnabled": "在發生嚴重失敗時收集進階診斷。", + "loc.input.label.collectDumpOn": "收集處理序傾印並附加到測試回合報表", + "loc.input.help.collectDumpOn": "收集處理序傾印並附加到測試回合報表。", + "loc.input.label.rerunFailedTests": "重新執行失敗的測試", + "loc.input.help.rerunFailedTests": "選取此選項會重新執行所有失敗的測試,直到這些測試通過或是達到 # 的嘗試次數上限。", + "loc.input.label.rerunType": "如果測試失敗超過指定的閾值,就不重新執行", + "loc.input.help.rerunType": "使用此選項可在失敗率超過指定閾值時避免重新執行測試。這在有任何環境問題導致大量失敗時適用。
                              您可以將失敗率或失敗的測試數指定為閾值。", + "loc.input.label.rerunFailedThreshold": "失敗百分比", + "loc.input.help.rerunFailedThreshold": "使用此選項可在失敗率超過指定閾值時避免重新執行測試。這在有任何環境問題導致大量失敗時適用。", + "loc.input.label.rerunFailedTestCasesMaxLimit": "失敗測試的數量", + "loc.input.help.rerunFailedTestCasesMaxLimit": "使用此選項可在失敗測試案例數超過指定上限時避免重新執行測試。這在有任何環境問題導致大量失敗時適用。", + "loc.input.label.rerunMaxAttempts": "嘗試次數上限", + "loc.input.help.rerunMaxAttempts": "指定已失敗測試應重試的次數上限 #。若測試在達到嘗試次數上限 # 前通過,之後就不會重新執行。", + "loc.messages.VstestLocationDoesNotExist": "'vstest.console.exe' 位置指定的 '%s' 不存在。", + "loc.messages.VstestFailedReturnCode": "VsTest 工作失敗。", + "loc.messages.VstestPassedReturnCode": "VsTest 工作成功。", + "loc.messages.NoMatchingTestAssemblies": "找不到符合模式的測試組件: %s。", + "loc.messages.VstestNotFound": "找不到 Visual Studio %d。請使用建置代理式電腦上的版本再試一次。", + "loc.messages.NoVstestFound": "找不到測試平台。將其安裝在組建代理程式電腦上後,再試一次。", + "loc.messages.VstestFailed": "Vstest 失敗,並發生錯誤。請檢查記錄檔中是否發生失敗。可能有失敗的測試。", + "loc.messages.VstestTIANotSupported": "請安裝 Visual Studio 2015 Update 3 或 Visual Studio 2017 RC 或更高版本,以執行測試影響分析。", + "loc.messages.NoResultsToPublish": "找不到要發佈的結果。", + "loc.messages.ErrorWhileReadingRunSettings": "讀取執行設定的檔案時發生錯誤。錯誤: %s。", + "loc.messages.ErrorWhileReadingTestSettings": "讀取測試設定的檔案時發生錯誤。錯誤: %s。", + "loc.messages.RunInParallelNotSupported": "無法使用 testsettings 檔案在多核心電腦上平行執行測試。此選項將予忽略。", + "loc.messages.InvalidSettingsFile": "指定的設定檔 %s 無效或不存在。請提供有效的設定檔或清除此欄位。", + "loc.messages.UpdateThreeOrHigherRequired": "若要平行執行測試,請在您的組建代理程式電腦上安裝 Visual Studio 2015 Update 3 或更新版。", + "loc.messages.ErrorOccuredWhileSettingRegistry": "設定登錄機碼時發生錯誤,錯誤: %s。", + "loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings": "在測試設定檔中設定測試影響收集器時發生錯誤。", + "loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings": "在回合設定檔中設定測試影響收集器時發生錯誤。", + "loc.messages.ErrorWhileCreatingResponseFile": "建立回應檔時發生錯誤。將會執行此回合的所有測試。", + "loc.messages.ErrorWhileUpdatingResponseFile": "更新回應檔 '%s' 時發生錯誤。將會執行此回合的所有測試。", + "loc.messages.ErrorWhilePublishingCodeChanges": "發佈程式碼變更時發生錯誤。將執行此回合的所有測試。", + "loc.messages.ErrorWhileListingDiscoveredTests": "探索測試時發生錯誤。將會為此執行進行所有測試。", + "loc.messages.PublishCodeChangesPerfTime": "發佈程式碼變更所花費的時間總計: %d 毫秒。", + "loc.messages.GenerateResponseFilePerfTime": "取得回應檔所花費的時間總計: %d 毫秒。", + "loc.messages.UploadTestResultsPerfTime": "上傳測試結果所花費的時間總計: %d 毫秒。", + "loc.messages.ErrorReadingVstestVersion": "讀取 vstest.console.exe 的版本時發生錯誤。", + "loc.messages.UnexpectedVersionString": "偵測到未預期的 vstest.console.exe 版本字串: %s。", + "loc.messages.UnexpectedVersionNumber": "偵測到未預期的 vstest.console.exe 版本號碼: %s。", + "loc.messages.VstestDiagNotSupported": "vstest.console.exe 版本不支援 /diag 旗標。請透過 exe.config 檔案啟用診斷", + "loc.messages.NoIncludePatternFound": "找不到任何 include 模式。請至少指定一個 include 模式以搜尋測試組件。", + "loc.messages.ErrorWhileUpdatingSettings": "更新設定檔案時發生錯誤。將使用指定的設定檔案。", + "loc.messages.VideoCollectorNotSupportedWithRunSettings": "回合設定不支援 Video collector。", + "loc.messages.runTestInIsolationNotSupported": "使用多重代理程式作業設定時,不支援獨立執行測試。系統會忽略此選項。", + "loc.messages.overrideNotSupported": "只有有效的 runsettings 或 testsettings 檔案才支援覆寫測試回合參數。系統會忽略這個選項。", + "loc.messages.testSettingPropertiesNotSupported": "在 testsettings 檔案中指定的屬性可以透過使用 Visual Studio 2017 Update 4 更高版本的 TestContext 存取", + "loc.messages.vstestVersionInvalid": "不支援指定的測試平台版本 %s。", + "loc.messages.configureDtaAgentFailed": "嘗試了 %d 次之後,為伺服器設定測試代理程式仍然失敗。錯誤: %s", + "loc.messages.otherConsoleOptionsNotSupported": "這項工作設定不支援其他主控台選項。將會忽略此選項。", + "loc.messages.distributedTestWorkflow": "在分散式測試流程中", + "loc.messages.nonDistributedTestWorkflow": "正在使用 vstest.console.exe 執行器執行測試。", + "loc.messages.dtaNumberOfAgents": "分散式測試執行,作業中的代理程式數目: %s", + "loc.messages.testSelectorInput": "測試選取器: %s", + "loc.messages.searchFolderInput": "搜尋資料夾: %s", + "loc.messages.testFilterCriteriaInput": "測試篩選準則: %s", + "loc.messages.runSettingsFileInput": "回合設定檔: %s", + "loc.messages.runInParallelInput": "平行執行: %s", + "loc.messages.runInIsolationInput": "單獨執行: %s", + "loc.messages.pathToCustomAdaptersInput": "自訂配接器的路徑: %s", + "loc.messages.otherConsoleOptionsInput": "其他主控台選項: %s", + "loc.messages.codeCoverageInput": "已啟用程式碼涵蓋範圍: %s", + "loc.messages.testPlanInput": "測試計劃識別碼: %s", + "loc.messages.testplanConfigInput": "測試計劃設定識別碼: %s", + "loc.messages.testSuiteSelected": "已選取測試套件識別碼: %s", + "loc.messages.testAssemblyFilterInput": "測試組件: %s", + "loc.messages.vsVersionSelected": "選取用於測試執行的 Visual Studio 版本: %s", + "loc.messages.runTestsLocally": "使用 %s 在本機執行測試", + "loc.messages.vstestLocationSpecified": "%s,指定的位置: %s", + "loc.messages.uitestsparallel": "在相同的機器上平行執行 UI 測試可能會造成錯誤。請考慮停用 [平行執行] 選項,或使用不同的工作來執行 UI 測試。如需詳細資訊,請參閱 https://aka.ms/paralleltestexecution ", + "loc.messages.pathToCustomAdaptersInvalid": "自訂配接器 '%s' 的路徑應為存在的目錄。", + "loc.messages.pathToCustomAdaptersContainsNoAdapters": "自訂配接器 '%s' 的路徑不包含任何測試配接器,請提供有效的路徑。", + "loc.messages.testAssembliesSelector": "測試組件", + "loc.messages.testPlanSelector": "測試計劃", + "loc.messages.testRunSelector": "測試回合", + "loc.messages.testRunIdInvalid": "測試選取項目為 'Test run',但提供的測試回合識別碼 '%s' 無效", + "loc.messages.testRunIdInput": "測試回合識別碼: '%s'", + "loc.messages.testSourcesFilteringFailed": "準備測試來源檔案失敗。錯誤: %s", + "loc.messages.noTestSourcesFound": "找不到與指定篩選 '%s' 相符的測試來源", + "loc.messages.DontShowWERUIDisabledWarning": "未設定 Windows 錯誤報告 DontShowUI,如果 UI 測試執行期間彈出 Windows 錯誤對話方塊,該測試將會停止回應", + "loc.messages.noVstestConsole": "測試不會透過 vstest 主控台執行。請安裝 Visual Studio 2017 RC 或更新版本,以透過 vstest 主控台執行測試。", + "loc.messages.numberOfTestCasesPerSlice": "各批次測試案例數: %s", + "loc.messages.invalidTestBatchSize": "提供的批次大小 %s 無效", + "loc.messages.invalidRunTimePerBatch": "[各批次執行時間 (秒)] %s 無效", + "loc.messages.minimumRunTimePerBatchWarning": "「每批次的執行時間 (秒)」至少應為 '%s' 秒。預設為支援的最小值。", + "loc.messages.RunTimePerBatch": "各批次執行時間 (秒): %s", + "loc.messages.searchLocationNotDirectory": "搜尋資料夾: '%s' 應為存在的目錄。", + "loc.messages.rerunFailedTests": "重新執行失敗的測試: %s", + "loc.messages.rerunFailedThreshold": "重新執行失敗的測試閾值: %s", + "loc.messages.invalidRerunFailedThreshold": "重新執行已失敗測試的閾值無效,預設為 30%", + "loc.messages.rerunFailedTestCasesMaxLimit": "重新執行失敗測試案例的次數上限: %s", + "loc.messages.invalidRerunFailedTestCasesMaxLimit": "重新執行已失敗測試案例的限制無效,預設為 5", + "loc.messages.rerunMaxAttempts": "重新執行嘗試次數上限: %s", + "loc.messages.invalidRerunMaxAttempts": "無效或超過重新執行嘗試次數上限,預設為 3", + "loc.messages.rerunNotSupported": "請安裝 Visual Studio 2015 update 3 或 Visual Studio 2017 以重新執行失敗的測試。", + "loc.messages.toolsInstallerPathNotSet": "無法在快取中找到 VsTest 測試平台資料夾。", + "loc.messages.testImpactAndCCWontWork": "測試影響 (僅執行受影響的測試) 與程式碼涵蓋範圍資料收集器將無法運作。", + "loc.messages.ToolsInstallerInstallationError": "Visual Studio 測試平台工具安裝程式未執行,或是未成功完成安裝,請參閱下列部落格以取得如何使用工具安裝程式的資訊: https://aka.ms/vstesttoolsinstaller", + "loc.messages.OverrideUseVerifiableInstrumentation": "正在將 runsettings 檔案中的 UseVerifiableInstrumentation 欄位覆寫為 false。", + "loc.messages.NoTestResultsDirectoryFound": "找不到測試結果目錄。", + "loc.messages.OnlyWindowsOsSupported": "只有 Windows 代理程式支援此工作,而無法用於其他平台。", + "loc.messages.MultiConfigNotSupportedWithOnDemand": "不支援以 Multi-Configuration 選項配合進行指定的執行。請使用 'None' 或 'Multi-agent' 平行處理原則選項。", + "loc.messages.disabledRerun": "因為提供的重新執行閾值為 %s,所以正在停用重新執行失敗的測試", + "loc.messages.UpgradeAgentMessage": "請升級代理程式版本。https://github.com/Microsoft/vsts-agent/releases", + "loc.messages.VsTestVersionEmpty": "VsTestVersion 為 null 或空白", + "loc.messages.UserProvidedSourceFilter": "來源篩選: %s", + "loc.messages.UnableToGetFeatureFlag": "無法取得功能旗標: %s", + "loc.messages.diagnosticsInput": "已啟用診斷: %s", + "loc.messages.UncPathNotSupported": "測試來源搜尋資料夾的路徑不能是 UNC 路徑。請提供根路徑或 $(System.DefaultWorkingDirectory) 的相對路徑。", + "loc.messages.LookingForBuildToolsInstalltion": "正在嘗試從第 %s 版的 Visual Studio Build Tools 安裝中尋找 vstest.console。", + "loc.messages.LookingForVsInstalltion": "正在嘗試從第 %s 版的 Visual Studio 安裝中尋找 vstest.console。", + "loc.messages.minTestsNotExecuted": "此測試回合執行的測試次數未達指定的下限 %d。", + "loc.messages.actionOnThresholdNotMet": "不符合最小測試數閾值時需採取的動作: %s", + "loc.messages.minimumExpectedTests": "應執行的最小測試數: %d" +} \ No newline at end of file diff --git a/_generated/VsTestV2/Tests/L0.ts b/_generated/VsTestV2/Tests/L0.ts new file mode 100644 index 000000000000..5a7632ef8073 --- /dev/null +++ b/_generated/VsTestV2/Tests/L0.ts @@ -0,0 +1,84 @@ +import * as path from 'path'; +import * as assert from 'assert'; +import * as tl from 'azure-pipelines-task-lib'; +import * as fs from 'fs'; + +describe('VsTest Suite', function() { + this.timeout(10000); + + if (!tl.osType().match(/^Win/)) { + return; + } + + before((done) => { + done(); + }); + + it('InputDataContract parity between task and dtaExecutionhost', (done: Mocha.Done) => { + console.log('TestCaseName: InputDataContract parity between task and dtaExecutionhost'); + + console.log('\n'); + + // Read the output of the parity tool and get the json representation of the C# data contract class + const inputDataContractParityTool = tl.tool(path.join(__dirname, './InputDataContractParityTool.exe')); + inputDataContractParityTool.arg('../_build/Tasks/VsTestV2/Modules/MS.VS.TestService.Common.dll'); + const inputDataContractParityToolOutput = JSON.parse(inputDataContractParityTool.execSync().stdout); + + // Read the typescript representation of the data contract interface + const inputDataContractInterfaceFileContents = fs.readFileSync('../Tasks/VsTestV2/inputdatacontract.ts', 'utf8').toString(); + const listOfInterfaces = inputDataContractInterfaceFileContents.replace(/export interface (.*) \{([\s][^{}]*)+\}(\s)*/g, '$1 ').trim().split(' '); + + const interfacesDictionary : { [key: string] : any } = <{ [key: string] : any} >{}; + + listOfInterfaces.forEach(interfaceName => { + const regex = new RegExp(interfaceName + ' \\{\\s([\\s][^\\{\\}]*)+\\}'); + const interfaceContents = inputDataContractInterfaceFileContents.match(regex)[1]; + + const interfaceProperties = interfaceContents.replace(/(\w+) \: (\w+([\[\]])*)\;/g, '$1 $2').split('\n'); + const interfacePropertiesDictionary : { [key: string] : string } = <{ [key: string] : string }>{}; + interfaceProperties.forEach(property => { + property = property.trim(); + interfacePropertiesDictionary[property.split(' ')[0]] = property.split(' ')[1]; + }); + + interfacesDictionary[interfaceName] = interfacePropertiesDictionary; + }); + + console.log('#######################################################################################################################'); + console.log('Ensure that the interfaces file is well formatted without extra newlines or whitespaces as the parser this test uses depends on the correct formatting of the inputdatacontract.ts file'); + console.log('#######################################################################################################################'); + + checkParity(inputDataContractParityToolOutput, interfacesDictionary, interfacesDictionary.InputDataContract); + + function checkParity(dataContractObject: any, interfacesDictionary: any, subInterface: any) { + + if (dataContractObject === null || dataContractObject === undefined ) { + return; + } + + const keys = Object.keys(dataContractObject); + + for (const index in Object.keys(dataContractObject)) { + + if (typeof dataContractObject[keys[index]] !== 'object') { + + //console.log(`${keys[index]}:${dataContractObject[keys[index]]} ===> ${subInterface.hasOwnProperty(keys[index])}, ${subInterface[keys[index]] === dataContractObject[keys[index]]}`); + assert(subInterface.hasOwnProperty(keys[index]), `${keys[index]} not present in the typescript version of the data contract.`); + assert(subInterface[keys[index]] === dataContractObject[keys[index]], `Data type of ${keys[index]} in typescript is ${subInterface[keys[index]]} and in C# is ${dataContractObject[keys[index]]}`); + delete subInterface[keys[index]]; + + } else { + //console.log(`${keys[index]}:${JSON.stringify(dataContractObject[keys[index]])} ===> ${subInterface.hasOwnProperty(keys[index])}`); + assert(subInterface.hasOwnProperty(keys[index]), `${keys[index]} not present in the typescript version of the data contract.`); + checkParity(dataContractObject[keys[index]], interfacesDictionary, interfacesDictionary[keys[index]]); + delete subInterface[keys[index]]; + } + } + + //console.log(JSON.stringify(subInterface)); + assert(Object.keys(subInterface).length === 1, `${JSON.stringify(subInterface)} properties are not present in the C# data contract.`); + } + + done(); + }); +}); diff --git a/_generated/VsTestV2/Tests/package-lock.json b/_generated/VsTestV2/Tests/package-lock.json new file mode 100644 index 000000000000..9c948274612e --- /dev/null +++ b/_generated/VsTestV2/Tests/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "vsts-tasks-vstest", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@types/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + } + } +} diff --git a/_generated/VsTestV2/Tests/package.json b/_generated/VsTestV2/Tests/package.json new file mode 100644 index 000000000000..5ac9d2eb39b6 --- /dev/null +++ b/_generated/VsTestV2/Tests/package.json @@ -0,0 +1,18 @@ +{ + "name": "vsts-tasks-vstest", + "description": "Azure Pipelines VSTEST Task", + "main": "VSTest.js", + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/azure-pipelines-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/azure-pipelines-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/azure-pipelines-tasks#readme", + "devDependencies": { + "@types/mocha": "^5.2.0" + } +} diff --git a/_generated/VsTestV2/cieventlogger.ts b/_generated/VsTestV2/cieventlogger.ts new file mode 100644 index 000000000000..462bf84fcd11 --- /dev/null +++ b/_generated/VsTestV2/cieventlogger.ts @@ -0,0 +1,29 @@ +import * as tl from 'azure-pipelines-task-lib/task'; + +const area: string = 'TestExecution'; +const feature: string = 'TestExecutionTask'; + +function getDefaultProps() { + return { + releaseuri: tl.getVariable('Release.ReleaseUri'), + releaseid: tl.getVariable('Release.ReleaseId'), + builduri: tl.getVariable('Build.BuildUri'), + buildid: tl.getVariable('Build.Buildid') + }; +} + +export function publishEvent(properties: { [key: string]: any }): void { + try { + tl.assertAgent('2.125.0'); + publishTelemetry(area, feature, Object.assign(getDefaultProps(), properties)); + + } catch (err) { + tl.debug('Unable to publish telemetry due to lower agent version.'); + } +} + +export function publishTelemetry(area: string, feature: string, properties: { [key: string]: any }): void { + const data = JSON.stringify(properties); + tl.debug('telemetry area: ' + area + ' feature: ' + feature + ' data: ' + data); + tl.command('telemetry.publish', { 'area': area, 'feature': feature }, data); +} \ No newline at end of file diff --git a/_generated/VsTestV2/constants.ts b/_generated/VsTestV2/constants.ts new file mode 100644 index 000000000000..09cbf1e1347c --- /dev/null +++ b/_generated/VsTestV2/constants.ts @@ -0,0 +1,50 @@ +export module AreaCodes { + export const PUBLISHRESULTS = 'PublishResults'; + export const INVOKEVSTEST = 'InvokeVsTest'; + export const RUNTESTSLOCALLY = 'RunTestsLocally'; + export const INVALIDSETTINGSFILE = 'InvalidSettingsFile'; + export const EXECUTEVSTEST = 'ExecuteVsTest'; + export const GETVSTESTTESTSLISTINTERNAL = 'GetVsTestTestsListInternal'; + export const UPDATERESPONSEFILE = 'UpdateResponseFile'; + export const RESPONSECONTAINSNOTESTS = 'ResponseContainsNoTests'; + export const GENERATERESPONSEFILE = 'GenerateResponseFile'; + export const GETVSTESTTESTSLIST = 'GetVsTestTestsList'; + export const TIACONFIG = 'TiaConfig'; + export const TESTRUNUPDATIONFAILED = 'TestRunUpdationFailed'; + export const UPLOADTESTRESULTS = 'UploadTestResults'; + export const RUNVSTEST = 'RunVsTest'; + export const SPECIFIEDVSVERSIONNOTFOUND = 'SpecifiedVsVersionNotFound'; + export const TOOLSINSTALLERCACHENOTFOUND = 'ToolsInstallerCacheNotFound'; +} + +export module ResultMessages { + export const UPLOADTESTRESULTSRETURNED = 'uploadTestResults returned '; + export const EXECUTEVSTESTRETURNED = 'executeVstest returned '; + export const TESTRUNUPDATIONFAILED = 'testRunupdation failed'; +} + +export module VsTestToolsInstaller { + export const PathToVsTestToolVariable = 'VsTestToolsInstallerInstalledToolLocation'; +} + +export module DistributionTypes { + export const EXECUTIONTIMEBASED = 'TestExecutionTimes'; + export const ASSEMBLYBASED = 'TestAssemblies'; + export const NUMBEROFTESTMETHODSBASED = 'numberoftestmethods'; +} + +export module ServerTypes { + export const HOSTED = 'hosted'; +} + +export module ActionOnThresholdNotMet { + export const DONOTHING = 'donothing'; +} + +export module BackDoorVariables { + export const FORCE_HYDRA = 'Force_Hydra'; +} + +export module AgentVariables { + export const AGENT_TEMPDIRECTORY = 'Agent.TempDirectory'; +} \ No newline at end of file diff --git a/_generated/VsTestV2/distributedtest.ts b/_generated/VsTestV2/distributedtest.ts new file mode 100644 index 000000000000..bba29cf5e6a3 --- /dev/null +++ b/_generated/VsTestV2/distributedtest.ts @@ -0,0 +1,137 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as tl from 'azure-pipelines-task-lib/task'; +import * as tr from 'azure-pipelines-task-lib/toolrunner'; +import * as inputdatacontract from './inputdatacontract'; +import * as utils from './helpers'; +import * as os from 'os'; +import * as ci from './cieventlogger'; +import { TestSelectorInvoker } from './testselectorinvoker'; +import { writeFileSync } from 'fs'; +import * as uuid from 'uuid'; + +const testSelector = new TestSelectorInvoker(); + +export class DistributedTest { + constructor(inputDataContract: inputdatacontract.InputDataContract) { + this.dtaPid = -1; + this.inputDataContract = inputDataContract; + } + + public runDistributedTest() { + this.invokeDtaExecutionHost(); + } + + private async invokeDtaExecutionHost() { + try { + const exitCode = await this.startDtaExecutionHost(); + tl.debug('DtaExecutionHost finished'); + + if (exitCode !== 0) { + tl.debug('Modules/DTAExecutionHost.exe process exited with code ' + exitCode); + tl.setResult(tl.TaskResult.Failed, 'Modules/DTAExecutionHost.exe process exited with code ' + exitCode, true); + } else { + tl.debug('Modules/DTAExecutionHost.exe exited'); + tl.setResult(tl.TaskResult.Succeeded, 'Task succeeded', true); + } + } catch (error) { + ci.publishEvent({ environmenturi: this.inputDataContract.RunIdentifier, error: error }); + tl.setResult(tl.TaskResult.Failed, error, true); + } + } + + private async startDtaExecutionHost(): Promise { + let envVars: { [key: string]: string; } = process.env; + + // Overriding temp with agent temp + utils.Helper.addToProcessEnvVars(envVars, 'temp', utils.Helper.GetTempFolder()); + + this.inputDataContract.TestSelectionSettings.TestSourcesFile = this.createTestSourcesFile(); + + // Temporary solution till this logic can move to the test platform itself + if (this.inputDataContract.UsingXCopyTestPlatformPackage) { + envVars = utils.Helper.setProfilerVariables(envVars); + } + + // Pass the acess token as an environment variable for security purposes + utils.Helper.addToProcessEnvVars(envVars, 'DTA.AccessToken', tl.getEndpointAuthorization('SystemVssConnection', true).parameters.AccessToken); + + if (this.inputDataContract.ExecutionSettings.DiagnosticsSettings.Enabled) { + utils.Helper.addToProcessEnvVars(envVars, 'PROCDUMP_PATH', path.join(__dirname, 'ProcDump')); + } + + // Invoke DtaExecutionHost with the input json file + const inputFilePath = utils.Helper.GenerateTempFile('input_' + uuid.v1() + '.json'); + utils.Helper.removeEmptyNodes(this.inputDataContract); + + try { + writeFileSync(inputFilePath, JSON.stringify(this.inputDataContract)); + } catch (e) { + tl.setResult(tl.TaskResult.Failed, `Failed to write to the input json file ${inputFilePath} with error ${e}`); + } + + const dtaExecutionHostTool = tl.tool(path.join(__dirname, 'Modules/DTAExecutionHost.exe')); + dtaExecutionHostTool.arg(['--inputFile', inputFilePath]); + const code = await dtaExecutionHostTool.exec({ ignoreReturnCode: this.inputDataContract.TestReportingSettings.ExecutionStatusSettings.IgnoreTestFailures, env: envVars }); + + //hydra: add consolidated ci for inputs in C# layer for now + const consolidatedCiData = { + agentFailure: false + }; + + if (code !== 0) { + consolidatedCiData.agentFailure = true; + } else { + tl.debug('Modules/DTAExecutionHost.exe exited'); + } + ci.publishEvent(consolidatedCiData); + return code; + } + + private createTestSourcesFile(): string { + try { + let sourceFilter = tl.getDelimitedInput('testAssemblyVer2', '\n', true); + console.log(tl.loc('UserProvidedSourceFilter', sourceFilter.toString())); + + if (this.inputDataContract.TestSelectionSettings.TestSelectionType.toLowerCase() !== 'testassemblies') { + sourceFilter = ['**\\*', '!**\\obj\\**']; + } + const telemetryProps: { [key: string]: any; } = { MiniMatchLines: sourceFilter.length }; + telemetryProps.ExecutionFlow = 'Distributed'; + const start = new Date().getTime(); + const sources = tl.findMatch(this.inputDataContract.TestSelectionSettings.SearchFolder, sourceFilter); + tl.debug(`${sources.length} files matched the given minimatch filter`); + const timeTaken = new Date().getTime() - start; + tl.debug(`Time taken for applying the minimatch pattern to filter out the sources ${timeTaken} ms`); + telemetryProps.TimeToSearchDLLsInMilliSeconds = timeTaken; + ci.publishTelemetry('TestExecution', 'MinimatchFilterPerformance', telemetryProps); + const filesMatching = []; + sources.forEach(function (match: string) { + if (!fs.lstatSync(match).isDirectory()) { + filesMatching.push(match); + } + }); + + tl.debug('Files matching count :' + filesMatching.length); + if (filesMatching.length === 0) { + tl.warning(tl.loc('noTestSourcesFound', sourceFilter.toString())); + if (this.inputDataContract.TestReportingSettings.ExecutionStatusSettings.ActionOnThresholdNotMet.toLowerCase() === 'fail') { + throw new Error(tl.loc('minTestsNotExecuted', this.inputDataContract.TestReportingSettings.ExecutionStatusSettings.MinimumExecutedTestsExpected)); + } else { + tl.setResult(tl.TaskResult.Succeeded, tl.loc('noTestSourcesFound', sourceFilter.toString()), true); + process.exit(0); + } + } + + const tempFile = utils.Helper.GenerateTempFile('testSources_' + uuid.v1() + '.src'); + fs.writeFileSync(tempFile, filesMatching.join(os.EOL)); + tl.debug('Test Sources file :' + tempFile); + return tempFile; + } catch (error) { + throw new Error(tl.loc('testSourcesFilteringFailed', error)); + } + } + + private inputDataContract: inputdatacontract.InputDataContract; + private dtaPid: number; +} \ No newline at end of file diff --git a/_generated/VsTestV2/helpers.ts b/_generated/VsTestV2/helpers.ts new file mode 100644 index 000000000000..fa4a10bb7377 --- /dev/null +++ b/_generated/VsTestV2/helpers.ts @@ -0,0 +1,288 @@ +import * as fs from 'fs'; +import * as tl from 'azure-pipelines-task-lib/task'; +import * as tr from 'azure-pipelines-task-lib/toolrunner'; +import * as path from 'path'; +import * as Q from 'q'; +import * as os from 'os'; +import * as ci from './cieventlogger'; +import * as constants from './constants'; + +const str = require('string'); +const uuid = require('uuid'); +const xml2js = require('xml2js'); +const parser = new xml2js.Parser(); +const builder = new xml2js.Builder(); + +export class Constants { + public static vsTestVersionString = 'version'; + public static vsTestLocationString = 'location'; + public static systemDefaultWorkingDirectory = tl.getVariable('System.DefaultWorkingDirectory'); +} + +export class Helper { + public static addToProcessEnvVars(envVars: { [key: string]: string; }, name: string, value: string) { + if (!this.isNullEmptyOrUndefined(value)) { + if (!name.includes('AccessToken')) { + tl.debug('Setting the process env var: ' + name + ' to: ' + value); + } + envVars[name] = value; + } + } + + public static setEnvironmentVariableToString(envVars: { [key: string]: string; }, name: string, value: any) { + if (!this.isNullEmptyOrUndefined(value)) { + envVars[name] = value.toString(); + } + } + + public static isNullEmptyOrUndefined(obj) { + return obj === null || obj === '' || obj === undefined; + } + + public static isNullOrUndefined(obj) { + return obj === null || obj === '' || obj === undefined; + } + + public static isNullOrWhitespace(input) { + if (typeof input === 'undefined' || input === null) { + return true; + } + return input.replace(/\s/g, '').length < 1; + } + + public static trimString(input: string): string { + if (input) { + return input.replace(/^(?=\n)$|^\s*|\s*$|\n\n+/gm, ''); + } + return input; + } + + public static isToolsInstallerFlow(config: any) { + return config.toolsInstallerConfig && config.toolsInstallerConfig.isToolsInstallerInUse; + } + + public static pathExistsAsFile(path: string) { + return tl.exist(path) && tl.stats(path).isFile(); + } + + public static pathExistsAsDirectory(path: string) { + return tl.exist(path) && tl.stats(path).isDirectory(); + } + + public static isDebugEnabled(): boolean { + const sysDebug = tl.getVariable('System.Debug'); + if (sysDebug === undefined) { + return false; + } + return sysDebug.toLowerCase() === 'true'; + } + + public static publishEventToCi(areaCode: string, message: string, tracePoint: number, isUserError: boolean) { + const taskProps = { areacode: '', result: '', tracepoint: 0, isusererror: false }; + taskProps.areacode = areaCode; + taskProps.result = message; + taskProps.tracepoint = tracePoint; + taskProps.isusererror = isUserError; + ci.publishEvent(taskProps); + } + + public static getXmlContents(filePath: string): Q.Promise { + const defer = Q.defer(); + Helper.readFileContents(filePath, 'utf-8') + .then(function (xmlContents) { + parser.parseString(xmlContents, function (err, result) { + if (err) { + defer.resolve(null); + } else { + defer.resolve(result); + } + }); + }) + .fail(function (err) { + defer.reject(err); + }); + return defer.promise; + } + + public static saveToFile(fileContents: string, extension: string): Q.Promise { + const defer = Q.defer(); + const tempFile = Helper.GenerateTempFile(uuid.v1() + extension); + fs.writeFile(tempFile, fileContents, function (err) { + if (err) { + defer.reject(err); + } + tl.debug('Temporary file created at ' + tempFile); + defer.resolve(tempFile); + }); + return defer.promise; + } + + public static GenerateTempFile(fileName: string): string { + return path.join(Helper.GetTempFolder(), fileName); + } + + public static GetTempFolder(): string { + try { + tl.assertAgent('2.115.0'); + const tmpDir = tl.getVariable('Agent.TempDirectory'); + return tmpDir; + } catch (err) { + tl.warning(tl.loc('UpgradeAgentMessage')); + return os.tmpdir(); + } + } + + public static readFileContents(filePath: string, encoding: BufferEncoding): Q.Promise { + const defer = Q.defer(); + fs.readFile(filePath, encoding, (err, data: string) => { + if (err) { + defer.reject(new Error('Could not read file (' + filePath + '): ' + err.message)); + } else { + defer.resolve(data); + } + }); + return defer.promise; + } + + public static readFileContentsSync(filePath: string, encoding: BufferEncoding): string { + return fs.readFileSync(filePath, encoding); + } + + public static writeXmlFile(result: any, settingsFile: string, fileExt: string): Q.Promise { + const defer = Q.defer(); + let runSettingsContent = builder.buildObject(result); + runSettingsContent = str(runSettingsContent).replaceAll(' ', '').s; + //This is to fix carriage return any other special chars will not be replaced + Helper.saveToFile(runSettingsContent, fileExt) + .then(function (fileName) { + defer.resolve(fileName); + return defer.promise; + }) + .fail(function (err) { + defer.reject(err); + }); + return defer.promise; + } + + public static getVSVersion(versionNum: number) { + switch (versionNum) { + case 12: return '2013'; + case 14: return '2015'; + case 15: return '2017'; + case 16: return '2019'; + case 17: return '2022'; + default: return 'selected'; + } + } + + public static printMultiLineLog(multiLineString: string, logFunction: Function) { + const lines = multiLineString.toString().split('\n'); + lines.forEach(function (line: string) { + if (line.trim().length === 0) { + return; + } + logFunction(line); + }); + } + + public static modifyVsTestConsoleArgsForResponseFile(argument: string): string { + if (argument) { + if (!argument.startsWith('/')) { + return '\"' + argument + '\"'; + } else { + // we need to add quotes to args we are passing after : as the arg value can have spaces + // we dont need to changes the guy who is creating the args as toolrunner already takes care of this + // for response file we need to take care of this ourselves + // eg: /settings:c:\a b\1.settings should become /settings:"C:\a b\1.settings" + let indexOfColon = argument.indexOf(':'); // find if args has ':' + if (indexOfColon > 0 && argument[indexOfColon + 1] !== '\"') { // only process when quotes are not there + let modifyString = argument.substring(0, indexOfColon + 1); // get string till colon + modifyString = modifyString + '\"' + argument.substring(indexOfColon + 1) + '\"'; // append '"' and rest of the string + return modifyString; + } + } + } + + return argument; + } + + public static setProfilerVariables(envVars: { [key: string]: string; }) : { [key: string]: string; } { + const vsTestPackageLocation = tl.getVariable(constants.VsTestToolsInstaller.PathToVsTestToolVariable); + + // get path to Microsoft.IntelliTrace.ProfilerProxy.dll (amd64) + let amd64ProfilerProxy = tl.findMatch(vsTestPackageLocation, '**\\amd64\\Microsoft.IntelliTrace.ProfilerProxy.dll'); + if (amd64ProfilerProxy && amd64ProfilerProxy.length !== 0) { + + envVars.COR_PROFILER_PATH_64 = amd64ProfilerProxy[0]; + } else { + // Look in x64 also for Microsoft.IntelliTrace.ProfilerProxy.dll (x64) + amd64ProfilerProxy = tl.findMatch(vsTestPackageLocation, '**\\x64\\Microsoft.IntelliTrace.ProfilerProxy.dll'); + if (amd64ProfilerProxy && amd64ProfilerProxy.length !== 0) { + + envVars.COR_PROFILER_PATH_64 = amd64ProfilerProxy[0]; + } else { + Helper.publishEventToCi(constants.AreaCodes.TOOLSINSTALLERCACHENOTFOUND, tl.loc('testImpactAndCCWontWork'), 1043, false); + tl.warning(tl.loc('testImpactAndCCWontWork')); + } + + Helper.publishEventToCi(constants.AreaCodes.TOOLSINSTALLERCACHENOTFOUND, tl.loc('testImpactAndCCWontWork'), 1042, false); + tl.warning(tl.loc('testImpactAndCCWontWork')); + } + + // get path to Microsoft.IntelliTrace.ProfilerProxy.dll (x86) + const x86ProfilerProxy = tl.findMatch(vsTestPackageLocation, '**\\x86\\Microsoft.IntelliTrace.ProfilerProxy.dll'); + if (x86ProfilerProxy && x86ProfilerProxy.length !== 0) { + envVars.COR_PROFILER_PATH_32 = x86ProfilerProxy[0]; + } else { + Helper.publishEventToCi(constants.AreaCodes.TOOLSINSTALLERCACHENOTFOUND, tl.loc('testImpactAndCCWontWork'), 1044, false); + tl.warning(tl.loc('testImpactAndCCWontWork')); + } + + return envVars; + } + + // set the console code page to "UTF-8" + public static setConsoleCodePage() { + tl.debug("Changing active code page to UTF-8"); + const chcp = tl.tool(path.resolve(process.env.windir, "system32", "chcp.com")); + chcp.arg(["65001"]); + chcp.execSync({ silent: true } as tr.IExecSyncOptions); + } + + public static stringToBool(inputString : string) : boolean { + return !this.isNullEmptyOrUndefined(inputString) && inputString.toLowerCase() === 'true'; + } + + public static uploadFile(file: string): void { + try { + if (Helper.pathExistsAsFile(file)) { + const stats = fs.statSync(file); + tl.debug('File exists. Size: ' + stats.size + ' Bytes'); + console.log('##vso[task.uploadfile]' + file); + } + } catch (err) { + tl.debug(`Failed to upload file ${file} with error ${err}`); + } + } + + // Utility function used to remove empty or spurious nodes from the input json file + public static removeEmptyNodes(obj: any) { + if (obj === null || obj === undefined ) { + return; + } + if (typeof obj !== 'object' && typeof obj !== undefined) { + return; + } + const keys = Object.keys(obj); + for (var index in Object.keys(obj)) { + // should call if object is not empty + if (obj[keys[index]] && Object.keys(obj[keys[index]]).length != 0) { + Helper.removeEmptyNodes(obj[keys[index]]); + } + if (obj[keys[index]] == undefined || obj[keys[index]] == null || (typeof obj[keys[index]] == "object" && Object.keys(obj[keys[index]]).length == 0)) { + tl.debug(`Removing node ${keys[index]} as its value is ${obj[keys[index]]}.`); + delete obj[keys[index]]; + } + } + } +} \ No newline at end of file diff --git a/_generated/VsTestV2/icon.png b/_generated/VsTestV2/icon.png new file mode 100644 index 000000000000..6865419ec88b Binary files /dev/null and b/_generated/VsTestV2/icon.png differ diff --git a/_generated/VsTestV2/icon.svg b/_generated/VsTestV2/icon.svg new file mode 100644 index 000000000000..d05e696288a5 --- /dev/null +++ b/_generated/VsTestV2/icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/_generated/VsTestV2/inputdatacontract.ts b/_generated/VsTestV2/inputdatacontract.ts new file mode 100644 index 000000000000..9a4fbd740596 --- /dev/null +++ b/_generated/VsTestV2/inputdatacontract.ts @@ -0,0 +1,144 @@ +export interface InputDataContract { + AgentName : string; + AccessToken : string; + AccessTokenType : string; + CollectionUri : string; + RunIdentifier : string; + TeamProject : string; + TestSelectionSettings : TestSelectionSettings; + VsTestConsolePath : string; + UsingXCopyTestPlatformPackage : boolean; + EnableSingleAgentAPIFlow : boolean; + TestReportingSettings : TestReportingSettings; + TfsSpecificSettings : TfsSpecificSettings; + TargetBinariesSettings : TargetBinariesSettings; + TestSpecificSettings : TestSpecificSettings; + ProxySettings : ProxySettings; + DistributionSettings : DistributionSettings; + ExecutionSettings : ExecutionSettings; + Logging : Logging; + SourcesDirectory : string; + ServerType : string; +} + +export interface TestReportingSettings { + TestRunTitle : string; + TestResultsDirectory : string; + TestRunSystem : string; + TestSourceSettings : TestSourceSettings; + ExecutionStatusSettings : ExecutionStatusSettings; +} + +export interface TestSelectionSettings { + TestSelectionType : string; + TestPlanTestSuiteSettings : TestPlanTestSuiteSettings; + SearchFolder : string; + TestCaseFilter : string; + TestSourcesFile : string; +} + +export interface TestPlanTestSuiteSettings { + OnDemandTestRunId : number; + Testplan : number; + TestPlanConfigId : number; + TestSuites : number[]; +} + +export interface TfsSpecificSettings { + BuildDefinitionId : number; + ReleaseDefinitionId : number; + BuildId : number; + BuildUri : string; + ReleaseId : number; + ReleaseUri : string; + ReleaseEnvironmentUri : string; + WorkFolder : string; + PhaseName : string; + PhaseAttempt : number; + StageName : string; + StageAttempt : number; + JobName : string; + JobAttempt : number; +} + +export interface TestSpecificSettings { + TestCaseAccessToken : string; +} + +export interface TargetBinariesSettings { + BuildConfig : string; + BuildPlatform : string; +} + +export interface ProxySettings { + ProxyUrl : string; + ProxyUsername : string; + ProxyPassword : string; + ProxyBypassHosts : string; +} + +export interface RerunSettings { + RerunFailedTests : boolean; + RerunType : string; + RerunFailedTestCasesMaxLimit : number; + RerunFailedThreshold : number; + RerunMaxAttempts : number; +} + +export interface DistributionSettings { + DistributeTestsBasedOn : string; + NumberOfTestAgents : number; + RunTimePerSlice : number; + NumberOfTestCasesPerSlice : number; +} + +export interface ExecutionSettings { + TestPlatformExecutionMode : string; + DefaultTestBatchSize : number; + AssemblyLevelParallelism : boolean; + CodeCoverageEnabled : boolean; + PathToCustomTestAdapters : string; + ProceedAfterAbortedTestCase : boolean; + PathToCustomVsTestConsoleWrapperAssembly : string; + SettingsFile : string; + AdditionalConsoleParameters : string; + OverridenParameters : string; + RerunSettings : RerunSettings; + RunTestsInIsolation : boolean; + TiaSettings : TiaSettings; + TempFolder : string; + VideoDataCollectorEnabled : boolean; + DiagnosticsSettings : DiagnosticsSettings; +} + +export interface TestSourceSettings { + PullRequestTargetBranchName : string; +} + +export interface ExecutionStatusSettings { + IgnoreTestFailures : boolean; + MinimumExecutedTestsExpected : number; + ActionOnThresholdNotMet : string; +} + +export interface DiagnosticsSettings { + Enabled : boolean; + DumpCollectionType : string; +} + +export interface TiaSettings { + Enabled : boolean; + DisableDataCollection : boolean; + RebaseLimit : number; + SourcesDirectory : string; + FileLevel : boolean; + FilterPaths : string; + UserMapFile : string; + IsPrFlow : boolean; + UseTestCaseFilterInResponseFile : boolean; +} + +export interface Logging { + DebugLogging : boolean; + EnableConsoleLogs : boolean; +} diff --git a/_generated/VsTestV2/inputparser.ts b/_generated/VsTestV2/inputparser.ts new file mode 100644 index 000000000000..1b80cef02b77 --- /dev/null +++ b/_generated/VsTestV2/inputparser.ts @@ -0,0 +1,687 @@ +import * as path from 'path'; +import * as tl from 'azure-pipelines-task-lib/task'; +import * as tr from 'azure-pipelines-task-lib/toolrunner'; +import * as utils from './helpers'; +import * as constants from './constants'; +import * as ci from './cieventlogger'; +import { AreaCodes, DistributionTypes } from './constants'; +import * as idc from './inputdatacontract'; +import * as Q from "q"; +import * as isUncPath from 'is-unc-path'; +const regedit = require('regedit'); + +let serverBasedRun = false; +let enableDiagnosticsSettings = false; + +// TODO: refactor all log messages to a separate function +// replace else if ladders with switch if possible +// unravel long else if chains + +export function parseInputsForDistributedTestRun() : idc.InputDataContract { + let inputDataContract = {} as idc.InputDataContract; + + inputDataContract = getTestSelectionInputs(inputDataContract); + inputDataContract = getTfsSpecificSettings(inputDataContract); + inputDataContract = getTargetBinariesSettings(inputDataContract); + inputDataContract = getTestReportingSettings(inputDataContract); + inputDataContract = getTestPlatformSettings(inputDataContract); + inputDataContract = getLoggingSettings(inputDataContract); + inputDataContract = getProxySettings(inputDataContract); + inputDataContract = getDistributionSettings(inputDataContract); + inputDataContract = getExecutionSettings(inputDataContract); + + inputDataContract.TeamProject = tl.getVariable('System.TeamProject'); + inputDataContract.CollectionUri = tl.getVariable('System.TeamFoundationCollectionUri'); + inputDataContract.AgentName = tl.getVariable('Agent.MachineName') + '-' + tl.getVariable('Agent.Name') + '-' + tl.getVariable('Agent.Id'); + inputDataContract.AccessTokenType = 'jwt'; + inputDataContract.RunIdentifier = getRunIdentifier(); + inputDataContract.SourcesDirectory = tl.getVariable('Build.SourcesDirectory'); + inputDataContract.ServerType = tl.getVariable('System.ServerType'); + + logWarningForWER(tl.getBoolInput('uiTests')); + ci.publishEvent({ 'UiTestsOptionSelected': tl.getBoolInput('uiTests')} ); + + return inputDataContract; +} + +export function parseInputsForNonDistributedTestRun() : idc.InputDataContract { + let inputDataContract = {} as idc.InputDataContract; + + // hydra: should i create a separate function since testplan and testrun are never scenarios for local test? + inputDataContract = getTestSelectionInputs(inputDataContract); + inputDataContract = getTfsSpecificSettings(inputDataContract); + inputDataContract = getTargetBinariesSettings(inputDataContract); + inputDataContract = getTestReportingSettings(inputDataContract); + inputDataContract = getTestPlatformSettings(inputDataContract); + inputDataContract = getLoggingSettings(inputDataContract); + inputDataContract = getProxySettings(inputDataContract); + inputDataContract = getExecutionSettings(inputDataContract); + + inputDataContract.TeamProject = tl.getVariable('System.TeamProject'); + inputDataContract.CollectionUri = tl.getVariable('System.TeamFoundationCollectionUri'); + inputDataContract.AccessToken = tl.getEndpointAuthorization('SystemVssConnection', true).parameters.AccessToken; + inputDataContract.AccessTokenType = 'jwt'; + inputDataContract.AgentName = tl.getVariable('Agent.MachineName') + '-' + tl.getVariable('Agent.Name') + '-' + tl.getVariable('Agent.Id'); + inputDataContract.RunIdentifier = getRunIdentifier(); + inputDataContract.EnableSingleAgentAPIFlow = utils.Helper.stringToBool(tl.getVariable('Hydra.EnableApiFlow')); + inputDataContract.SourcesDirectory = tl.getVariable('Build.SourcesDirectory'); + inputDataContract.ServerType = tl.getVariable('System.ServerType'); + + logWarningForWER(tl.getBoolInput('uiTests')); + + return inputDataContract; +} + +function getTestSelectionInputs(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + inputDataContract.TestSelectionSettings = {}; + inputDataContract.TestSelectionSettings.TestSelectionType = tl.getInput('testSelector').toLowerCase(); + switch (inputDataContract.TestSelectionSettings.TestSelectionType) { + + case 'testplan': + inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings = {}; + console.log(tl.loc('testSelectorInput', tl.loc('testPlanSelector'))); + + inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.Testplan = parseInt(tl.getInput('testPlan')); + console.log(tl.loc('testPlanInput', inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.Testplan)); + + inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.TestPlanConfigId = parseInt(tl.getInput('testConfiguration')); + console.log(tl.loc('testplanConfigInput', inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.TestPlanConfigId)); + + const testSuiteStrings = tl.getDelimitedInput('testSuite', ',', true); + inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.TestSuites = new Array(); + testSuiteStrings.forEach(element => { + const testSuiteId = parseInt(element); + console.log(tl.loc('testSuiteSelected', testSuiteId)); + inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.TestSuites.push(testSuiteId); + }); + + break; + + case 'testassemblies': + console.log(tl.loc('testSelectorInput', tl.loc('testAssembliesSelector'))); + + inputDataContract.TestSelectionSettings.TestCaseFilter = tl.getInput('testFiltercriteria'); + console.log(tl.loc('testFilterCriteriaInput', inputDataContract.TestSelectionSettings.TestCaseFilter)); + break; + + case 'testrun': + inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings = {}; + + console.log(tl.loc('testSelectorInput', tl.loc('testRunSelector'))); + inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.OnDemandTestRunId = parseInt(tl.getInput('tcmTestRun')); + + if (inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.OnDemandTestRunId <= 0) { + throw new Error(tl.loc('testRunIdInvalid', inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.OnDemandTestRunId)); + } + console.log(tl.loc('testRunIdInput', inputDataContract.TestSelectionSettings.TestPlanTestSuiteSettings.OnDemandTestRunId)); + + break; + } + + inputDataContract.TestSelectionSettings.SearchFolder = tl.getInput('searchFolder'); + if (!utils.Helper.isNullOrWhitespace(inputDataContract.TestSelectionSettings.SearchFolder)) { + inputDataContract.TestSelectionSettings.SearchFolder = path.resolve(inputDataContract.TestSelectionSettings.SearchFolder); + } + + if (inputDataContract.TestSelectionSettings.SearchFolder && !utils.Helper.pathExistsAsDirectory(inputDataContract.TestSelectionSettings.SearchFolder)) { + throw new Error(tl.loc('searchLocationNotDirectory', inputDataContract.TestSelectionSettings.SearchFolder)); + } + + if (isUncPath(inputDataContract.TestSelectionSettings.SearchFolder)) { + throw new Error(tl.loc('UncPathNotSupported')); + } + + console.log(tl.loc('searchFolderInput', inputDataContract.TestSelectionSettings.SearchFolder)); + + return inputDataContract; +} + +function getTfsSpecificSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + inputDataContract.TfsSpecificSettings = {}; + inputDataContract.TfsSpecificSettings.BuildDefinitionId = utils.Helper.isNullEmptyOrUndefined(tl.getVariable('Release.DefinitionId')) ? Number(tl.getVariable('System.DefinitionId')) : Number(tl.getVariable('Build.DefinitionId')); + inputDataContract.TfsSpecificSettings.ReleaseDefinitionId = utils.Helper.isNullEmptyOrUndefined(tl.getVariable('Release.DefinitionId')) ? null : Number(tl.getVariable('Release.DefinitionId')); + inputDataContract.TfsSpecificSettings.BuildId = utils.Helper.isNullEmptyOrUndefined(tl.getVariable('Build.Buildid')) ? null : Number(tl.getVariable('Build.Buildid')); + inputDataContract.TfsSpecificSettings.BuildUri = tl.getVariable('Build.BuildUri'); + inputDataContract.TfsSpecificSettings.ReleaseId = utils.Helper.isNullEmptyOrUndefined(tl.getVariable('Release.ReleaseId')) ? null : Number(tl.getVariable('Release.ReleaseId')); + inputDataContract.TfsSpecificSettings.ReleaseUri = tl.getVariable('Release.ReleaseUri'); + inputDataContract.TfsSpecificSettings.ReleaseEnvironmentUri = tl.getVariable('Release.EnvironmentUri'); + inputDataContract.TfsSpecificSettings.WorkFolder = tl.getVariable('System.DefaultWorkingDirectory'); + inputDataContract.TfsSpecificSettings.PhaseName = tl.getVariable('System.PhaseName'); + inputDataContract.TfsSpecificSettings.PhaseAttempt = utils.Helper.isNullEmptyOrUndefined(tl.getVariable('System.PhaseAttempt')) ? null : Number(tl.getVariable('System.PhaseAttempt')); + inputDataContract.TfsSpecificSettings.StageName = tl.getVariable('System.StageName'); + inputDataContract.TfsSpecificSettings.StageAttempt = utils.Helper.isNullEmptyOrUndefined(tl.getVariable('System.StageAttempt')) ? null : Number(tl.getVariable('System.StageAttempt')); + inputDataContract.TfsSpecificSettings.JobName = tl.getVariable('System.JobName'); + inputDataContract.TfsSpecificSettings.JobAttempt = utils.Helper.isNullEmptyOrUndefined(tl.getVariable('System.JobAttempt')) ? null : Number(tl.getVariable('System.JobAttempt')); + + return inputDataContract; +} + +function getTargetBinariesSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + inputDataContract.TargetBinariesSettings = {}; + inputDataContract.TargetBinariesSettings.BuildConfig = tl.getInput('configuration'); + inputDataContract.TargetBinariesSettings.BuildPlatform = tl.getInput('platform'); + return inputDataContract; +} + +function getTestReportingSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + inputDataContract.TestReportingSettings = {}; + inputDataContract.TestReportingSettings.TestRunTitle = tl.getInput('testRunTitle'); + inputDataContract.TestReportingSettings.TestRunSystem = 'VSTS - vstest'; + + const resultsDir = path.resolve(tl.getVariable('Agent.TempDirectory'), tl.getInput('resultsFolder')); + inputDataContract.TestReportingSettings.TestResultsDirectory = resultsDir; + tl.debug("TestResultsFolder: " + resultsDir); + addResultsDirectoryToTelemetry(resultsDir); + + inputDataContract.TestReportingSettings.TestSourceSettings = {}; + inputDataContract.TestReportingSettings.TestSourceSettings.PullRequestTargetBranchName = tl.getVariable('System.PullRequest.TargetBranch'); + inputDataContract.TestReportingSettings.ExecutionStatusSettings = {}; + inputDataContract.TestReportingSettings.ExecutionStatusSettings.MinimumExecutedTestsExpected = 0; + inputDataContract.TestReportingSettings.ExecutionStatusSettings.ActionOnThresholdNotMet = "donothing"; + inputDataContract.TestReportingSettings.ExecutionStatusSettings.IgnoreTestFailures = utils.Helper.stringToBool(tl.getVariable('vstest.ignoretestfailures')); + if (utils.Helper.isNullEmptyOrUndefined(inputDataContract.TestReportingSettings.TestRunTitle)) { + + let definitionName = tl.getVariable('BUILD_DEFINITIONNAME'); + let buildOrReleaseName = tl.getVariable('BUILD_BUILDNUMBER'); + + if (inputDataContract.TfsSpecificSettings.ReleaseUri) { + definitionName = tl.getVariable('RELEASE_DEFINITIONNAME'); + buildOrReleaseName = tl.getVariable('RELEASE_RELEASENAME'); + } + + inputDataContract.TestReportingSettings.TestRunTitle = `TestRun_${definitionName}_${buildOrReleaseName}`; + } + + const actionOnThresholdNotMet = tl.getBoolInput('failOnMinTestsNotRun'); + if (actionOnThresholdNotMet) + { + inputDataContract.TestReportingSettings.ExecutionStatusSettings.ActionOnThresholdNotMet = "fail"; + const minimumExpectedTests = parseInt(tl.getInput('minimumExpectedTests')); + if (!isNaN(minimumExpectedTests)) { + inputDataContract.TestReportingSettings.ExecutionStatusSettings.MinimumExecutedTestsExpected = minimumExpectedTests; + } else { + throw new Error(tl.loc('invalidMinimumExpectedTests :' + tl.getInput('minimumExpectedTests'))); + } + } + + console.log(tl.loc('actionOnThresholdNotMet', inputDataContract.TestReportingSettings.ExecutionStatusSettings.ActionOnThresholdNotMet)) + console.log(tl.loc('minimumExpectedTests', inputDataContract.TestReportingSettings.ExecutionStatusSettings.MinimumExecutedTestsExpected)); + return inputDataContract; +} + +function getTestPlatformSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + const vsTestLocationMethod = tl.getInput('vstestLocationMethod'); + if (vsTestLocationMethod === utils.Constants.vsTestVersionString) { + const vsTestVersion = tl.getInput('vsTestVersion'); + if (utils.Helper.isNullEmptyOrUndefined(vsTestVersion)) { + console.log(tl.loc('VsTestVersionEmpty')); + throw new Error(tl.loc('VsTestVersionEmpty')); + } else if (vsTestVersion.toLowerCase() === 'toolsinstaller') { + tl.debug('Trying VsTest installed by tools installer.'); + ci.publishEvent({ subFeature: 'ToolsInstallerSelected', isToolsInstallerPackageLocationSet: !utils.Helper.isNullEmptyOrUndefined(tl.getVariable(constants.VsTestToolsInstaller.PathToVsTestToolVariable)) }); + + inputDataContract.UsingXCopyTestPlatformPackage = true; + + const vsTestPackageLocation = tl.getVariable(constants.VsTestToolsInstaller.PathToVsTestToolVariable); + tl.debug('Path to VsTest from tools installer: ' + vsTestPackageLocation); + + // get path to vstest.console.exe + const matches = tl.findMatch(vsTestPackageLocation, '**\\vstest.console.exe'); + if (matches && matches.length !== 0) { + inputDataContract.VsTestConsolePath = path.dirname(matches[0]); + } else { + utils.Helper.publishEventToCi(AreaCodes.TOOLSINSTALLERCACHENOTFOUND, tl.loc('toolsInstallerPathNotSet'), 1041, false); + throw new Error(tl.loc('toolsInstallerPathNotSet')); + } + + // if Tools installer is not there throw. + if (utils.Helper.isNullOrWhitespace(inputDataContract.VsTestConsolePath)) { + ci.publishEvent({ subFeature: 'ToolsInstallerInstallationError' }); + utils.Helper.publishEventToCi(AreaCodes.SPECIFIEDVSVERSIONNOTFOUND, 'Tools installer task did not complete successfully.', 1040, true); + throw new Error(tl.loc('ToolsInstallerInstallationError')); + } + + ci.publishEvent({ subFeature: 'ToolsInstallerInstallationSuccessful' }); + + } else if ((vsTestVersion !== '17.0') + && (vsTestVersion !== '16.0') + && (vsTestVersion !== '15.0') + && (vsTestVersion !== '14.0') + && (vsTestVersion.toLowerCase() !== 'latest')) { + throw new Error(tl.loc('vstestVersionInvalid', vsTestVersion)); + } else if (vsTestLocationMethod === utils.Constants.vsTestVersionString && vsTestVersion === '12.0') { + throw (tl.loc('vs2013NotSupportedInDta')); + } else { + console.log(tl.loc('vsVersionSelected', vsTestVersion)); + inputDataContract.VsTestConsolePath = getTestPlatformPath(inputDataContract); + } + } else { + // hydra: should it be full path or directory above? + inputDataContract.VsTestConsolePath = tl.getInput('vsTestLocation'); + console.log(tl.loc('vstestLocationSpecified', 'vstest.console.exe', inputDataContract.VsTestConsolePath)); + if (inputDataContract.VsTestConsolePath.endsWith('vstest.console.exe')) { + inputDataContract.VsTestConsolePath = path.dirname(inputDataContract.VsTestConsolePath); + } + } + + return inputDataContract; +} + +function getLoggingSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + // InputDataContract.Logging + inputDataContract.Logging = {}; + inputDataContract.Logging.EnableConsoleLogs = true; + if (utils.Helper.isDebugEnabled()) { + inputDataContract.Logging.DebugLogging = true; + } + return inputDataContract; +} + +function getProxySettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + // Get proxy details + inputDataContract.ProxySettings = {}; + inputDataContract.ProxySettings.ProxyUrl = tl.getVariable('agent.proxyurl'); + inputDataContract.ProxySettings.ProxyUsername = tl.getVariable('agent.proxyusername'); + inputDataContract.ProxySettings.ProxyPassword = tl.getVariable('agent.proxypassword'); + inputDataContract.ProxySettings.ProxyBypassHosts = tl.getVariable('agent.proxybypasslist'); + return inputDataContract; +} + +function getDistributionSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + inputDataContract.DistributionSettings = {}; + inputDataContract.DistributionSettings.NumberOfTestAgents = 1; + + const totalJobsInPhase = parseInt(tl.getVariable('SYSTEM_TOTALJOBSINPHASE')); + if (!isNaN(totalJobsInPhase)) { + inputDataContract.DistributionSettings.NumberOfTestAgents = totalJobsInPhase; + } + console.log(tl.loc('dtaNumberOfAgents', inputDataContract.DistributionSettings.NumberOfTestAgents)); + + const distributionType = tl.getInput('distributionBatchType'); + + switch (distributionType) { + + case 'basedOnTestCases': + inputDataContract.DistributionSettings.DistributeTestsBasedOn = DistributionTypes.NUMBEROFTESTMETHODSBASED; + const distributeByAgentsOption = tl.getInput('batchingBasedOnAgentsOption'); + + if (distributeByAgentsOption && distributeByAgentsOption === 'customBatchSize') { + const batchSize = parseInt(tl.getInput('customBatchSizeValue')); + if (!isNaN(batchSize) && batchSize > 0) { + inputDataContract.DistributionSettings.NumberOfTestCasesPerSlice = batchSize; + console.log(tl.loc('numberOfTestCasesPerSlice', inputDataContract.DistributionSettings.NumberOfTestCasesPerSlice)); + } else { + throw new Error(tl.loc('invalidTestBatchSize', batchSize)); + } + } + break; + + case 'basedOnExecutionTime': + inputDataContract.DistributionSettings.DistributeTestsBasedOn = DistributionTypes.EXECUTIONTIMEBASED; + const batchBasedOnExecutionTimeOption = tl.getInput('batchingBasedOnExecutionTimeOption'); + + if (batchBasedOnExecutionTimeOption && batchBasedOnExecutionTimeOption === 'customTimeBatchSize') { + const batchExecutionTimeInSec = parseInt(tl.getInput('customRunTimePerBatchValue')); + if (isNaN(batchExecutionTimeInSec) || batchExecutionTimeInSec <= 0) { + throw new Error(tl.loc('invalidRunTimePerBatch', batchExecutionTimeInSec)); + } + inputDataContract.DistributionSettings.RunTimePerSlice = batchExecutionTimeInSec; + console.log(tl.loc('RunTimePerBatch', inputDataContract.DistributionSettings.RunTimePerSlice)); + } + break; + + case 'basedOnAssembly': + inputDataContract.DistributionSettings.DistributeTestsBasedOn = DistributionTypes.ASSEMBLYBASED; + break; + } + + return inputDataContract; +} + +function getExecutionSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + inputDataContract.ExecutionSettings = {}; + + if (tl.filePathSupplied('runSettingsFile')) { + inputDataContract.ExecutionSettings.SettingsFile = path.resolve(tl.getPathInput('runSettingsFile')); + console.log(tl.loc('runSettingsFileInput', inputDataContract.ExecutionSettings.SettingsFile)); + } + + inputDataContract.ExecutionSettings.TempFolder = utils.Helper.GetTempFolder(); + + inputDataContract.ExecutionSettings.OverridenParameters = tl.getInput('overrideTestrunParameters'); + tl.debug(`OverrideTestrunParameters set to ${inputDataContract.ExecutionSettings.OverridenParameters}`); + + inputDataContract.ExecutionSettings.AssemblyLevelParallelism = tl.getBoolInput('runInParallel'); + console.log(tl.loc('runInParallelInput', inputDataContract.ExecutionSettings.AssemblyLevelParallelism)); + + inputDataContract.ExecutionSettings.RunTestsInIsolation = tl.getBoolInput('runTestsInIsolation'); + console.log(tl.loc('runInIsolationInput', inputDataContract.ExecutionSettings.RunTestsInIsolation)); + + if (serverBasedRun && inputDataContract.ExecutionSettings.RunTestsInIsolation) { + inputDataContract.ExecutionSettings.RunTestsInIsolation = null; + tl.warning(tl.loc('runTestInIsolationNotSupported')); + } + + inputDataContract.ExecutionSettings.PathToCustomTestAdapters = tl.getInput('pathtoCustomTestAdapters'); + + if (!utils.Helper.isNullOrWhitespace(inputDataContract.ExecutionSettings.PathToCustomTestAdapters)) { + inputDataContract.ExecutionSettings.PathToCustomTestAdapters = path.resolve(inputDataContract.ExecutionSettings.PathToCustomTestAdapters); + } + + if (inputDataContract.ExecutionSettings.PathToCustomTestAdapters && + !utils.Helper.pathExistsAsDirectory(inputDataContract.ExecutionSettings.PathToCustomTestAdapters)) { + throw new Error(tl.loc('pathToCustomAdaptersInvalid', inputDataContract.ExecutionSettings.PathToCustomTestAdapters)); + } + console.log(tl.loc('pathToCustomAdaptersInput', inputDataContract.ExecutionSettings.PathToCustomTestAdapters)); + + inputDataContract.ExecutionSettings.ProceedAfterAbortedTestCase = false; + if (tl.getVariable('ProceedAfterAbortedTestCase') && tl.getVariable('ProceedAfterAbortedTestCase').toUpperCase() === 'TRUE') { + inputDataContract.ExecutionSettings.ProceedAfterAbortedTestCase = true; + } + tl.debug('ProceedAfterAbortedTestCase is set to : ' + inputDataContract.ExecutionSettings.ProceedAfterAbortedTestCase); + + // hydra: Maybe move all warnings to a diff function + if (tl.getBoolInput('uiTests') && inputDataContract.ExecutionSettings.AssemblyLevelParallelism) { + tl.warning(tl.loc('uitestsparallel')); + } + + inputDataContract.ExecutionSettings.AdditionalConsoleParameters = tl.getInput('otherConsoleOptions'); + console.log(tl.loc('otherConsoleOptionsInput', inputDataContract.ExecutionSettings.AdditionalConsoleParameters)); + + if (serverBasedRun && inputDataContract.ExecutionSettings.AdditionalConsoleParameters) { + tl.warning(tl.loc('otherConsoleOptionsNotSupported')); + inputDataContract.ExecutionSettings.AdditionalConsoleParameters = null; + } + + inputDataContract.ExecutionSettings.CodeCoverageEnabled = tl.getBoolInput('codeCoverageEnabled'); + console.log(tl.loc('codeCoverageInput', inputDataContract.ExecutionSettings.CodeCoverageEnabled)); + + inputDataContract = getDiagnosticsSettings(inputDataContract); + console.log(tl.loc('diagnosticsInput', inputDataContract.ExecutionSettings.DiagnosticsSettings.Enabled)); + + // Custom console wrapper settings + inputDataContract.ExecutionSettings.PathToCustomVsTestConsoleWrapperAssembly = tl.getVariable('vstest.customConsoleWrapperAssemblyLocation'); + + inputDataContract = getTiaSettings(inputDataContract); + inputDataContract = getRerunSettings(inputDataContract); + + return inputDataContract; +} + +function getDiagnosticsSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + inputDataContract.ExecutionSettings.DiagnosticsSettings = {}; + if (enableDiagnosticsSettings) { + inputDataContract.ExecutionSettings.DiagnosticsSettings.Enabled = tl.getBoolInput('diagnosticsEnabled'); + inputDataContract.ExecutionSettings.DiagnosticsSettings.DumpCollectionType = tl.getInput('collectDumpOn').toLowerCase(); + } else { + inputDataContract.ExecutionSettings.DiagnosticsSettings.Enabled = false; + } + return inputDataContract; +} + +function getTiaSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + // TIA stuff + if (tl.getBoolInput('runOnlyImpactedTests') === false) { + return inputDataContract; + } + + inputDataContract.ExecutionSettings.TiaSettings = {}; + inputDataContract.ExecutionSettings.TiaSettings.Enabled = tl.getBoolInput('runOnlyImpactedTests'); + inputDataContract.ExecutionSettings.TiaSettings.RebaseLimit = +tl.getInput('runAllTestsAfterXBuilds'); + inputDataContract.ExecutionSettings.TiaSettings.FileLevel = getTIALevel(tl.getVariable('tia.filelevel')); + inputDataContract.ExecutionSettings.TiaSettings.SourcesDirectory = tl.getVariable('build.sourcesdirectory'); + inputDataContract.ExecutionSettings.TiaSettings.FilterPaths = tl.getVariable('TIA_IncludePathFilters'); + + // User map file + inputDataContract.ExecutionSettings.TiaSettings.UserMapFile = tl.getVariable('tia.usermapfile'); + + // disable editing settings file to switch on data collector + inputDataContract.ExecutionSettings.TiaSettings.DisableDataCollection = utils.Helper.stringToBool(tl.getVariable('tia.disabletiadatacollector')); + + // This option gives the user ability to add Fully Qualified name filters for test impact. Does not work with XUnit + inputDataContract.ExecutionSettings.TiaSettings.UseTestCaseFilterInResponseFile = utils.Helper.stringToBool(tl.getVariable('tia.useTestCaseFilterInResponseFile')); + + // A legacy switch to disable test impact from build variables + inputDataContract.ExecutionSettings.TiaSettings.Enabled = !utils.Helper.stringToBool(tl.getVariable('DisableTestImpactAnalysis')); + + const buildReason = tl.getVariable('Build.Reason'); + + // https://www.visualstudio.com/en-us/docs/build/define/variables + // PullRequest -> This is the case for TfsGit PR flow + // CheckInShelveset -> This is the case for TFVC Gated Checkin + if (buildReason && (buildReason === 'PullRequest' || buildReason === 'CheckInShelveset')) { + inputDataContract.ExecutionSettings.TiaSettings.IsPrFlow = true; + } else { + inputDataContract.ExecutionSettings.TiaSettings.IsPrFlow = utils.Helper.stringToBool(tl.getVariable('tia.isPrFlow')); + } + + return inputDataContract; +} + +function getRerunSettings(inputDataContract : idc.InputDataContract) : idc.InputDataContract { + + if (tl.getBoolInput('rerunFailedTests') === false) { + return inputDataContract; + } + + inputDataContract.ExecutionSettings.RerunSettings = {}; + inputDataContract.ExecutionSettings.RerunSettings.RerunFailedTests = tl.getBoolInput('rerunFailedTests'); + console.log(tl.loc('rerunFailedTests', inputDataContract.ExecutionSettings.RerunSettings.RerunFailedTests)); + const rerunType = tl.getInput('rerunType') || 'basedOnTestFailurePercentage'; + inputDataContract.ExecutionSettings.RerunSettings.RerunType = rerunType; + + if (rerunType === 'basedOnTestFailureCount') { + const rerunFailedTestCasesMaxLimit = parseInt(tl.getInput('rerunFailedTestCasesMaxLimit')); + if (!isNaN(rerunFailedTestCasesMaxLimit)) { + inputDataContract.ExecutionSettings.RerunSettings.RerunFailedTestCasesMaxLimit = rerunFailedTestCasesMaxLimit; + console.log(tl.loc('rerunFailedTestCasesMaxLimit', inputDataContract.ExecutionSettings.RerunSettings.RerunFailedTestCasesMaxLimit)); + } else { + tl.warning(tl.loc('invalidRerunFailedTestCasesMaxLimit')); + } + } else { + const rerunFailedThreshold = parseInt(tl.getInput('rerunFailedThreshold')); + if (!isNaN(rerunFailedThreshold)) { + inputDataContract.ExecutionSettings.RerunSettings.RerunFailedThreshold = rerunFailedThreshold; + console.log(tl.loc('rerunFailedThreshold', inputDataContract.ExecutionSettings.RerunSettings.RerunFailedThreshold)); + } else { + tl.warning(tl.loc('invalidRerunFailedThreshold')); + } + } + + const rerunMaxAttempts = parseInt(tl.getInput('rerunMaxAttempts')); + if (!isNaN(rerunMaxAttempts)) { + inputDataContract.ExecutionSettings.RerunSettings.RerunMaxAttempts = rerunMaxAttempts; + console.log(tl.loc('rerunMaxAttempts', inputDataContract.ExecutionSettings.RerunSettings.RerunMaxAttempts)); + } else { + tl.warning(tl.loc('invalidRerunMaxAttempts')); + } + + return inputDataContract; +} + +function getRunIdentifier(): string { + let runIdentifier: string = ''; + const taskInstanceId = getDtaInstanceId(); + const dontDistribute = tl.getBoolInput('dontDistribute'); + const releaseId = tl.getVariable('Release.ReleaseId'); + const jobId = tl.getVariable('System.JobPositionInPhase'); + const parallelExecution = tl.getVariable('System.ParallelExecutionType'); + const phaseId = utils.Helper.isNullEmptyOrUndefined(releaseId) ? + tl.getVariable('System.PhaseId') : tl.getVariable('Release.DeployPhaseId'); + if ((!utils.Helper.isNullEmptyOrUndefined(parallelExecution) && parallelExecution.toLowerCase() === 'multiconfiguration') + || dontDistribute) { + runIdentifier = `${phaseId}/${jobId}/${taskInstanceId}`; + } else { + runIdentifier = `${phaseId}/${taskInstanceId}`; + } + + return runIdentifier; +} + +// hydra: rename function and maybe refactor and add logic inline +function getTIALevel(fileLevel: string) { + if (fileLevel && fileLevel.toUpperCase() === 'FALSE') { + return false; + } + return true; +} + +function getTestPlatformPath(inputDataContract : idc.InputDataContract) { + const vsTestVersion = tl.getInput('vsTestVersion'); + + if (vsTestVersion.toLowerCase() === 'latest') { + tl.debug('Searching for latest Visual Studio.'); + let vstestconsolePath = getVSTestConsolePath('17.0', '18.0'); + if (vstestconsolePath) { + return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform'); + } + vstestconsolePath = getVSTestConsolePath('16.0', '17.0'); + if (vstestconsolePath) { + return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform'); + } + + vstestconsolePath = getVSTestConsolePath('15.0', '16.0'); + if (vstestconsolePath) { + return path.join(vstestconsolePath, 'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'TestWindow'); + } + + // fallback + tl.debug('Unable to find an instance of Visual Studio 2017 or higher.'); + tl.debug('Searching for Visual Studio 2015..'); + return getVSTestLocation(14); + } + + const vsVersion: number = parseFloat(vsTestVersion); + + if (vsVersion === 17.0) { + const vstestconsolePath = getVSTestConsolePath('17.0', '18.0'); + if (vstestconsolePath) { + return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform'); + } + throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion)))); + } + + if (vsVersion === 16.0) { + const vstestconsolePath = getVSTestConsolePath('16.0', '17.0'); + if (vstestconsolePath) { + return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform'); + } + throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion)))); + } + + if (vsVersion === 15.0) { + const vstestconsolePath = getVSTestConsolePath('15.0', '16.0'); + if (vstestconsolePath) { + return path.join(vstestconsolePath, 'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'TestWindow'); + } + throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion)))); + } + + tl.debug('Searching for Visual Studio ' + vsVersion.toString()); + return getVSTestLocation(vsVersion); +} + +function getVSTestConsolePath(versionLowerLimit : string, versionUpperLimit : string): string { + let vswhereTool = tl.tool(path.join(__dirname, 'vswhere.exe')); + + console.log(tl.loc('LookingForVsInstalltion', `[${versionLowerLimit},${versionUpperLimit})`)); + vswhereTool.line(`-version [${versionLowerLimit},${versionUpperLimit}) -latest -products * -requires Microsoft.VisualStudio.PackageGroup.TestTools.Core -property installationPath`); + let vsPath = vswhereTool.execSync({ silent: true } as tr.IExecSyncOptions).stdout; + vsPath = utils.Helper.trimString(vsPath); + + if (!utils.Helper.isNullOrWhitespace(vsPath)) { + tl.debug('Visual Studio 15.0 or higher installed path: ' + vsPath); + return vsPath; + } + + // Look for build tool installation if full VS not present + console.log(tl.loc('LookingForBuildToolsInstalltion', `[${versionLowerLimit},${versionUpperLimit})`)); + vswhereTool = tl.tool(path.join(__dirname, 'vswhere.exe')); + vswhereTool.line(`-version [${versionLowerLimit},${versionUpperLimit}) -latest -products * -requires Microsoft.VisualStudio.Component.TestTools.BuildTools -property installationPath`); + vsPath = vswhereTool.execSync({ silent: true } as tr.IExecSyncOptions).stdout; + vsPath = utils.Helper.trimString(vsPath); + if (!utils.Helper.isNullOrWhitespace(vsPath)) { + tl.debug('Build tools installed path: ' + vsPath); + return vsPath; + } + + return null; +} + +export function getVSTestLocation(vsVersion: number): string { + const vsCommon: string = tl.getVariable('VS' + vsVersion + '0COMNTools'); + if (!vsCommon) { + throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion)))); + } + return path.join(vsCommon, '..\\IDE\\CommonExtensions\\Microsoft\\TestWindow'); +} + +async function logWarningForWER(runUITests: boolean) { + if (!runUITests) { + return; + } + + const regPathHKLM = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting'; + const regPathHKCU = 'HKCU\\SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting'; + + const isEnabledInHKCU = await isDontShowUIRegKeySet(regPathHKCU); + const isEnabledInHKLM = await isDontShowUIRegKeySet(regPathHKLM); + + if (!isEnabledInHKCU && !isEnabledInHKLM) { + tl.warning(tl.loc('DontShowWERUIDisabledWarning')); + } +} + +function isDontShowUIRegKeySet(regPath: string): Q.Promise { + const defer = Q.defer(); + const regValue = 'DontShowUI'; + regedit.list(regPath).on('data', (entry) => { + if (entry && entry.data && entry.data.values && + entry.data.values[regValue] && (entry.data.values[regValue].value === 1)) { + defer.resolve(true); + } + defer.resolve(false); + }); + return defer.promise; +} + +function addResultsDirectoryToTelemetry(resultsDir: string){ + + if (resultsDir.startsWith(path.join(tl.getVariable('Agent.TempDirectory'), 'TestResults'))) { + ci.publishTelemetry('TestExecution', 'ResultsDirectory', { 'TestResultsFolderUi': '$(Agent.TempDirectory)/TestResults' } ); + } + else if (resultsDir.startsWith(tl.getVariable('Agent.TempDirectory'))) { + ci.publishTelemetry('TestExecution', 'ResultsDirectory', { 'TestResultsFolderUi': '$(Agent.TempDirectory)' } ); + } + else if (resultsDir.startsWith(tl.getVariable('Common.TestResultsDirectory'))) { + ci.publishTelemetry('TestExecution', 'ResultsDirectory', { 'TestResultsFolderUi': '$(Common.TestResultsDirectory)' }) + } + else if (resultsDir.startsWith(tl.getVariable('System.DefaultWorkingDirectory'))) { + ci.publishTelemetry('TestExecution', 'ResultsDirectory', { 'TestResultsFolderUi': '$(System.DefaultWorkingDirectory)' }) + } + else { + ci.publishTelemetry('TestExecution', 'ResultsDirectory', { 'TestResultsFolderUi': 'Custom Directory' }) + } +} + +export function setIsServerBasedRun(isServerBasedRun: boolean) { + serverBasedRun = isServerBasedRun; +} + +export function setEnableDiagnosticsSettings(enableDiagnosticsSettingsFF: boolean) { + enableDiagnosticsSettings = enableDiagnosticsSettingsFF; + tl.debug('Diagnostics feature flag is set to: ' + enableDiagnosticsSettingsFF); +} + +export function getDtaInstanceId(): number { + const taskInstanceIdString = tl.getVariable('DTA_INSTANCE_ID'); + let taskInstanceId: number = 1; + if (taskInstanceIdString) { + const instanceId: number = Number(taskInstanceIdString); + if (!isNaN(instanceId)) { + taskInstanceId = instanceId + 1; + } + } + tl.setVariable('DTA_INSTANCE_ID', taskInstanceId.toString()); + return taskInstanceId; +} diff --git a/_generated/VsTestV2/make.json b/_generated/VsTestV2/make.json new file mode 100644 index 000000000000..24fda5eb1455 --- /dev/null +++ b/_generated/VsTestV2/make.json @@ -0,0 +1,43 @@ +{ + "externals": { + "archivePackages": [ + { + "url": "https://testselectorv2.blob.core.windows.net/testselector/7841796/TestSelector.zip", + "dest": "./" + }, + { + "url": "https://testexecution.blob.core.windows.net/testexecution/25847670/TestAgent.zip", + "dest": "./Modules" + }, + { + "url": "https://testselectorv2.blob.core.windows.net/testselector/InputDataContractParityTool/InputDataContractParityTool.zip", + "dest": "./Tests" + }, + { + "url": "https://testselectorv2.blob.core.windows.net/testselector/TestImpactCollector/TestImpactCollector.zip", + "dest": "./TestSelector" + }, + { + "url": "https://procdump.blob.core.windows.net/procdump/procdump.zip", + "dest": "./ProcDump" + } + ], + "files": [ + { + "url": "https://github.com/Microsoft/vswhere/releases/download/1.0.62/vswhere.exe", + "dest": "./vswhere.exe" + } + ] + }, + "rm": [ + { + "items": [ + "Modules/*.pdb", + "Tests/*.pdb", + "TestSelector/*.pdb", + "TestSelector/14.0/*.pdb" + ], + "options": "-Rf" + } + ] +} diff --git a/_generated/VsTestV2/models.ts b/_generated/VsTestV2/models.ts new file mode 100644 index 000000000000..544daa0acb68 --- /dev/null +++ b/_generated/VsTestV2/models.ts @@ -0,0 +1,122 @@ +import * as version from './vstestversion'; + +export interface TestConfigurations { + testSelection: string; + + // ranjanar : TODO : Plan for better modelling of these + // Test Assembly Related Properties + sourceFilter: string[]; + testcaseFilter: string; + + // Test Plan related Properties + testplan: number; + testSuites: number[]; + testPlanConfigId: number; + + // Test Run Related Properties + onDemandTestRunId: string; + + // Common Properties + settingsFile: string; + testDropLocation: string; // search folder + overrideTestrunParameters: string; + codeCoverageEnabled: boolean; + videoCoverageEnabled: boolean; + buildConfig: string; + buildPlatform: string; + testRunTitle: string; + vsTestLocationMethod: string; + vsTestVersion: string; + vsTestLocation: string; + vsTestVersionDetails: version.VSTestVersion; + pathtoCustomTestAdapters: string; + tiaConfig: TiaConfiguration; + runInParallel: boolean; + runTestsInIsolation: boolean; + otherConsoleOptions: string; + taskInstanceIdentifier: string; + runUITests: boolean; + ignoreTestFailures: string; + rerunFailedTests: boolean; + rerunType: string; + rerunFailedThreshold: number; + rerunFailedTestCasesMaxLimit: number; + rerunMaxAttempts: number; + toolsInstallerConfig: ToolsInstallerConfiguration; + proxyConfiguration: ProxyConfiguration; + diagnosticsConfiguration: DiagnosticsConfiguration +} + +export interface DtaTestConfigurations extends TestConfigurations { + testConfigurationMapping: string; // TODO : What is this? + customSlicingenabled: boolean; + dtaEnvironment: DtaEnvironment; + numberOfAgentsInPhase: number; + useVsTestConsole: string; + numberOfTestCasesPerSlice: number; + batchingType: BatchingType; + runningTimePerBatchInMs: number; + proceedAfterAbortedTestCase: boolean; +} + +export interface ProxyConfiguration { + proxyUrl: string; + proxyUserName: string; + proxyPassword: string; + proxyBypassHosts: string; +} + +export interface DtaEnvironment { + tfsCollectionUrl: string; + patToken: string; + environmentUri: string; + dtaHostLogFilePath: string; + agentName: string; +} + +export interface VsTestConfigurations extends TestConfigurations { + publishRunAttachments: string; + vstestDiagFile: string; + responseFile: string; + isResponseFileRun: boolean; + responseSupplementryFile: string; + vstestArgsFile: string; + responseFileSupported: boolean; + publishTestResultsInTiaMode: boolean; +} + +export interface DiagnosticsConfiguration { + enabled: boolean; + dumpCollectionType: string; +} + +export interface TiaConfiguration { + tiaEnabled: boolean; + tiaRebaseLimit: string; + tiaFilterPaths: string; + fileLevel: string; + sourcesDir: string; + runIdFile: string; + baseLineBuildIdFile: string; + responseFile: string; + useNewCollector: boolean; + isPrFlow: string; + context: string; + useTestCaseFilterInResponseFile: string; + userMapFile: string; + disableEnablingDataCollector: boolean; +} + +export interface ToolsInstallerConfiguration { + vsTestPackageLocation: string; // root of the package downloaded by Tools installer + vsTestConsolePathFromPackageLocation: string; // path to vstest.console.exe + x86ProfilerProxyDLLLocation: string; + x64ProfilerProxyDLLLocation: string; + isToolsInstallerInUse: boolean; +} + +export enum BatchingType { + TestCaseBased, + TestExecutionTimeBased, + AssemblyBased +} \ No newline at end of file diff --git a/_generated/VsTestV2/nondistributedtest.ts b/_generated/VsTestV2/nondistributedtest.ts new file mode 100644 index 000000000000..2ed5164553d1 --- /dev/null +++ b/_generated/VsTestV2/nondistributedtest.ts @@ -0,0 +1,140 @@ +import * as tl from 'azure-pipelines-task-lib/task'; +import * as tr from 'azure-pipelines-task-lib/toolrunner'; +import * as path from 'path'; +import * as utils from './helpers'; +import * as ci from './cieventlogger'; +import * as outStream from './outputstream'; +import * as os from 'os'; +import * as uuid from 'uuid'; +import * as fs from 'fs'; +import * as process from 'process'; +import { InputDataContract } from './inputdatacontract'; + +export class NonDistributedTest { + constructor(inputDataContract: InputDataContract) { + this.inputDataContract = inputDataContract; + } + + public runNonDistributedTest() { + this.invokeDtaExecutionHost(); + } + + private async invokeDtaExecutionHost() { + try { + console.log(tl.loc('runTestsLocally', 'vstest.console.exe')); + console.log('========================================================'); + const exitCode = await this.startDtaExecutionHost(); + tl.debug('DtaExecutionHost finished'); + + if (exitCode !== 0 && !this.inputDataContract.TestReportingSettings.ExecutionStatusSettings.IgnoreTestFailures) { + tl.debug('Modules/DTAExecutionHost.exe process exited with code ' + exitCode); + tl.setResult(tl.TaskResult.Failed, tl.loc('VstestFailed'), true); + return; + } else { + if (exitCode !== 0) { + console.log('Task marked as success because IgnoreTestFailures is enabled'); + } + tl.debug(`Modules/DTAExecutionHost.exe exited with code ${exitCode}`); + tl.setResult(tl.TaskResult.Succeeded, 'Task succeeded', true); + } + + } catch (err) { + tl.setResult(tl.TaskResult.Failed, tl.loc('VstestFailedReturnCode'), true); + } + } + + private async startDtaExecutionHost(): Promise { + let dtaExecutionHostTool = tl.tool(path.join(this.inputDataContract.VsTestConsolePath, 'vstest.console.exe')); + + this.inputDataContract.TestSelectionSettings.TestSourcesFile = this.createTestSourcesFile(); + tl.cd(this.inputDataContract.TfsSpecificSettings.WorkFolder); + let envVars: { [key: string]: string; } = process.env; + dtaExecutionHostTool = tl.tool(path.join(__dirname, 'Modules/DTAExecutionHost.exe')); + + // Invoke DtaExecutionHost with the input json file + const inputFilePath = utils.Helper.GenerateTempFile('input_' + uuid.v1() + '.json'); + utils.Helper.removeEmptyNodes(this.inputDataContract); + + try { + fs.writeFileSync(inputFilePath, JSON.stringify(this.inputDataContract)); + } catch (e) { + tl.setResult(tl.TaskResult.Failed, `Failed to write to the input json file ${inputFilePath} with error ${e}`); + } + + dtaExecutionHostTool.arg(['--inputFile', inputFilePath]); + + utils.Helper.addToProcessEnvVars(envVars, 'DTA.AccessToken', tl.getEndpointAuthorization('SystemVssConnection', true).parameters.AccessToken); + + if (this.inputDataContract.ExecutionSettings.DiagnosticsSettings.Enabled) { + utils.Helper.addToProcessEnvVars(envVars, 'PROCDUMP_PATH', path.join(__dirname, 'ProcDump')); + } + + // hydra: See which of these are required in C# layer. Do we want this for telemetry?? + // utils.Helper.addToProcessEnvVars(envVars, 'DTA.AgentVersion', tl.getVariable('AGENT.VERSION')); + + if (this.inputDataContract.UsingXCopyTestPlatformPackage) { + envVars = utils.Helper.setProfilerVariables(envVars); + } + + const execOptions: tr.IExecOptions = { + IgnoreTestFailures: this.inputDataContract.TestReportingSettings.ExecutionStatusSettings.IgnoreTestFailures, + env: envVars, + failOnStdErr: false, + // In effect this will not be called as failOnStdErr is false + // Keeping this code in case we want to change failOnStdErr + errStream: new outStream.StringErrorWritable({ decodeStrings: false }) + }; + + // The error codes return below are not the same as tl.TaskResult which follows a different convention. + // Here we are returning the code as returned to us by vstest.console in case of complete run + // In case of a failure 1 indicates error to our calling function + try { + return await dtaExecutionHostTool.exec(execOptions); + } catch (err) { + tl.warning(tl.loc('VstestFailed')); + tl.error(err); + return 1; + } + } + private createTestSourcesFile(): string { + try { + console.log(tl.loc('UserProvidedSourceFilter', this.sourceFilter.toString())); + const telemetryProps: { [key: string]: any; } = { MiniMatchLines: this.sourceFilter.length }; + telemetryProps.ExecutionFlow = 'NonDistributed'; + const start = new Date().getTime(); + const sources = tl.findMatch(this.inputDataContract.TestSelectionSettings.SearchFolder, this.sourceFilter); + const timeTaken = new Date().getTime() - start; + tl.debug(`Time taken for applying the minimatch pattern to filter out the sources ${timeTaken} ms`); + telemetryProps.TimeToSearchDLLsInMilliSeconds = timeTaken; + tl.debug(`${sources.length} files matched the given minimatch filter`); + ci.publishTelemetry('TestExecution','MinimatchFilterPerformance', telemetryProps); + const filesMatching = []; + sources.forEach(function (match: string) { + if (!fs.lstatSync(match).isDirectory()) { + filesMatching.push(match); + } + }); + + tl.debug('Files matching count :' + filesMatching.length); + if (filesMatching.length === 0) { + tl.warning(tl.loc('noTestSourcesFound', this.sourceFilter.toString())); + if (this.inputDataContract.TestReportingSettings.ExecutionStatusSettings.ActionOnThresholdNotMet.toLowerCase() === 'fail') { + throw new Error(tl.loc('minTestsNotExecuted', this.inputDataContract.TestReportingSettings.ExecutionStatusSettings.MinimumExecutedTestsExpected)); + } else { + tl.setResult(tl.TaskResult.Succeeded, tl.loc('noTestSourcesFound', this.sourceFilter.toString()), true); + process.exit(0); + } + } + + const tempFile = utils.Helper.GenerateTempFile('testSources_' + uuid.v1() + '.src'); + fs.writeFileSync(tempFile, filesMatching.join(os.EOL)); + tl.debug('Test Sources file :' + tempFile); + return tempFile; + } catch (error) { + throw new Error(tl.loc('testSourcesFilteringFailed', error)); + } + } + + private inputDataContract: InputDataContract; + private sourceFilter: string[] = tl.getDelimitedInput('testAssemblyVer2', '\n', true); +} \ No newline at end of file diff --git a/_generated/VsTestV2/outputstream.ts b/_generated/VsTestV2/outputstream.ts new file mode 100644 index 000000000000..b7dd1a0778ca --- /dev/null +++ b/_generated/VsTestV2/outputstream.ts @@ -0,0 +1,33 @@ +import * as stream from 'stream'; +import * as os from 'os'; +import * as tl from 'azure-pipelines-task-lib/task'; + +export class StringErrorWritable extends stream.Writable { + private value: string = ''; + + constructor(options: any) { + super(options); + } + + _write(data: any, encoding: string, callback: Function): void { + this.value += data; + + let errorString: string = data.toString(); + let n = errorString.indexOf(os.EOL); + while (n > -1) { + const line = errorString.substring(0, n); + tl.error(line); + + // the rest of the string ... + errorString = errorString.substring(n + os.EOL.length); + n = errorString.indexOf(os.EOL); + } + if (callback) { + callback(); + } + } + + toString(): string { + return this.value; + } +} \ No newline at end of file diff --git a/_generated/VsTestV2/package-lock.json b/_generated/VsTestV2/package-lock.json new file mode 100644 index 000000000000..ffd87f974669 --- /dev/null +++ b/_generated/VsTestV2/package-lock.json @@ -0,0 +1,854 @@ +{ + "name": "vsts-tasks-vstest", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "requires": { + "@types/node": "*" + } + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "16.18.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.4.tgz", + "integrity": "sha512-9qGjJ5GyShZjUfx2ArBIGM+xExdfLvvaCyQR0t6yRXKPcWCVYF/WemtX/uIU3r7FYECXRXkIiw2Vnhn6y8d+pw==" + }, + "@types/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.1.tgz", + "integrity": "sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "azure-pipelines-task-lib": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-4.1.0.tgz", + "integrity": "sha512-8CNC9PcP+4eS76QcIDmPmBfrrao9xpy/M0Uts4TWk3chfr3uOXFGf0DYHVTJGF9180g51kyVXYTObicouq0KZQ==", + "requires": { + "minimatch": "3.0.5", + "mockery": "^2.1.0", + "q": "^1.5.1", + "semver": "^5.1.0", + "shelljs": "^0.8.5", + "sync-request": "6.1.0", + "uuid": "^3.0.1" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "requires": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + } + }, + "http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "requires": { + "@types/node": "^10.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "if-async": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/if-async/-/if-async-3.7.4.tgz", + "integrity": "sha1-VYaN6wCT08Z79xZudFNT+5vLIaI=", + "optional": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "optional": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mockery": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mockery/-/mockery-2.1.0.tgz", + "integrity": "sha512-9VkOmxKlWXoDO/h1jDZaS4lH33aWfRiJiNT/tKj+8OGzrcFDLo8d0syGdbsc3Bc4GvRXPb+NMMvojotmuGJTvA==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "optional": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "requires": { + "asap": "~2.0.6" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "requires": { + "resolve": "^1.1.6" + } + }, + "regedit": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/regedit/-/regedit-2.2.6.tgz", + "integrity": "sha1-yZszMCqKuuDjIhfqSPYXZdTk14k=", + "optional": true, + "requires": { + "debug": "^2.1.1", + "if-async": "^3.7.4", + "stream-slicer": "0.0.6", + "through2": "^0.6.3" + } + }, + "request": { + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + }, + "dependencies": { + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + } + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "sshpk": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz", + "integrity": "sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stream-slicer": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stream-slicer/-/stream-slicer-0.0.6.tgz", + "integrity": "sha1-+GsqxcJEC3oKh7cfM2ZcB4gEYTg=", + "optional": true + }, + "string": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/string/-/string-3.3.1.tgz", + "integrity": "sha1-jSdX7BwObFJnlvu2sUA2pAmDmLc=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "optional": true + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "requires": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + } + }, + "sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "requires": { + "get-port": "^3.1.0" + } + }, + "then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "requires": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "dependencies": { + "@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" + } + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "optional": true, + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "^1.4.1" + } + }, + "tunnel": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", + "integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "typescript": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + }, + "underscore": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.3.tgz", + "integrity": "sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vso-node-api": { + "version": "6.0.4-preview", + "resolved": "https://registry.npmjs.org/vso-node-api/-/vso-node-api-6.0.4-preview.tgz", + "integrity": "sha1-TqD5hSzRXIU/4yMBkHDuu6dZLcc=", + "requires": { + "q": "^1.0.1", + "tunnel": "0.0.4", + "underscore": "^1.8.3" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "xml2js": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.16.tgz", + "integrity": "sha1-+C/M0vlUDX4Km12sFj50cRlcnbM=", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "^4.1.0" + } + }, + "xmlbuilder": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", + "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", + "requires": { + "lodash": "^4.0.0" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "optional": true + } + } +} diff --git a/_generated/VsTestV2/package.json b/_generated/VsTestV2/package.json new file mode 100644 index 000000000000..812b7187244b --- /dev/null +++ b/_generated/VsTestV2/package.json @@ -0,0 +1,34 @@ +{ + "name": "vsts-tasks-vstest", + "description": "Azure Pipelines VSTEST Task", + "main": "VSTest.js", + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/azure-pipelines-tasks.git" + }, + "author": "Microsoft Corporation", + "license": "MIT", + "bugs": { + "url": "https://github.com/Microsoft/azure-pipelines-tasks/issues" + }, + "homepage": "https://github.com/Microsoft/azure-pipelines-tasks#readme", + "dependencies": { + "is-unc-path": "^1.0.0", + "performance-now": "0.2.0", + "request": "2.87.0", + "string": "3.3.1", + "uuid": "3.1.0", + "vso-node-api": "6.0.4-preview", + "azure-pipelines-task-lib": "^4.1.0", + "xml2js": "0.4.16", + "@types/node": "^16.11.39", + "@types/mocha": "^5.2.7", + "@types/q": "^1.5.0" + }, + "optionalDependencies": { + "regedit": "2.2.6" + }, + "devDependencies": { + "typescript": "4.0.2" + } +} diff --git a/_generated/VsTestV2/parameterparser.ts b/_generated/VsTestV2/parameterparser.ts new file mode 100644 index 000000000000..9527a92b3e79 --- /dev/null +++ b/_generated/VsTestV2/parameterparser.ts @@ -0,0 +1,121 @@ +import tl = require('azure-pipelines-task-lib/task'); +// resusing from https://github.com/Microsoft/azure-pipelines-tasks/tree/04293a25f9ecc7d91cecd2c4f130904bdbf3544d/Tasks/AzureResourceGroupDeployment + +export function parse(input: string) { + var result = {}; + var index = 0; + var obj = { name: "", value: "" }; + while (index < input.length) { + var literalData = findLiteral(input, index); + var nextIndex = literalData.currentPosition; + var specialCharacterFlag = literalData.specialCharacterFlag; + var literal = input.substr(index, nextIndex - index).trim(); + if (isName(literal, specialCharacterFlag)) { + if (obj.name) { + result[obj.name] = { value: obj.value }; + obj = { name: "", value: "" }; + } + obj.name = literal.substr(1, literal.length); + } else { + obj.value = literal; + result[obj.name] = { value: obj.value }; + obj = { name: "", value: "" }; + } + index = nextIndex + 1; + } + if (obj.name) { + result[obj.name] = { value: obj.value }; + } + for (var name in result) { + result[name].value = result[name].value.replace(/^"(.*)"$/, "$1"); + tl.debug("Name : "+ name + " Value : " + result[name].value); + } + return result; +} + +function isName(literal: string, specialCharacterFlag: boolean): boolean { + return literal[0] === "-" && !specialCharacterFlag; +} + +function findLiteral(input, currentPosition) { + var specialCharacterFlag = false; + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] === " " || input[currentPosition] === "\t") { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition + 1] !== " " || input[currentPosition + 1] !== "\t") { + break; + } + } + break; + } else if (input[currentPosition] === "(") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, ")"); + specialCharacterFlag = true; + } else if (input[currentPosition] === "[") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "]"); + specialCharacterFlag = true; + } else if (input[currentPosition] === "{") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "}"); + specialCharacterFlag = true; + } else if (input[currentPosition] === "\"") { + // keep going till this one closes + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "\""); + specialCharacterFlag = true; + } else if (input[currentPosition] === "'") { + // keep going till this one closes + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "'"); + specialCharacterFlag = true; + } else if (input[currentPosition] === "`") { + currentPosition++; + specialCharacterFlag = true; + if (currentPosition >= input.length) { + break; + } + } + } + return { currentPosition: currentPosition, specialCharacterFlag: specialCharacterFlag }; +} + +function findClosingBracketIndex(input, currentPosition, closingBracket): number { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] === closingBracket) { + break; + } + else if (input[currentPosition] === "(") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, ")"); + } + else if (input[currentPosition] === "[") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "]"); + } + else if (input[currentPosition] === "{") { + currentPosition = findClosingBracketIndex(input, currentPosition + 1, "}"); + } + else if (input[currentPosition] === "\"") { + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "\""); + } + else if (input[currentPosition] === "'") { + currentPosition = findClosingQuoteIndex(input, currentPosition + 1, "'"); + } + else if (input[currentPosition] === "`") { + currentPosition++; + if (currentPosition >= input.length) { + break; + } + } + } + return currentPosition; +} + +function findClosingQuoteIndex(input, currentPosition, closingQuote) { + for (; currentPosition < input.length; currentPosition++) { + if (input[currentPosition] === closingQuote) { + break; + } + else if (input[currentPosition] === "`") { + currentPosition++; + if (currentPosition >= input.length) { + break; + } + } + } + return currentPosition; +} \ No newline at end of file diff --git a/_generated/VsTestV2/runvstest.ts b/_generated/VsTestV2/runvstest.ts new file mode 100644 index 000000000000..32cf2311cd72 --- /dev/null +++ b/_generated/VsTestV2/runvstest.ts @@ -0,0 +1,199 @@ +import * as tl from 'azure-pipelines-task-lib/task'; +import * as nondistributedtest from './nondistributedtest'; +import * as path from 'path'; +import * as distributedTest from './distributedtest'; +import * as ci from './cieventlogger'; +import * as utils from './helpers'; +import * as inputParser from './inputparser'; +import * as os from 'os'; +import * as localtest from './vstest'; +import { InputDataContract } from './inputdatacontract'; +import { ServerTypes, ActionOnThresholdNotMet, BackDoorVariables, AgentVariables } from './constants'; + +const request = require('request'); +const osPlat: string = os.platform(); + +tl.setResourcePath(path.join(__dirname, 'task.json')); + +async function execute() { + const taskProps: { [key: string]: string; } = { state: 'started'}; + ci.publishEvent(taskProps); + + const enableApiExecution = await isFeatureFlagEnabled(tl.getVariable('System.TeamFoundationCollectionUri'), + 'TestExecution.EnableTranslationApi', tl.getEndpointAuthorization('SystemVssConnection', true).parameters.AccessToken); + + try { + utils.Helper.setConsoleCodePage(); + const blockRun = isMultiConfigOnDemandRun(); + if (blockRun) { + tl.setResult(tl.TaskResult.Failed, tl.loc('MultiConfigNotSupportedWithOnDemand')); + } + const serverBasedRun = isServerBasedRun(); + inputParser.setIsServerBasedRun(serverBasedRun); + + const enableDiagnostics = await isFeatureFlagEnabled(tl.getVariable('System.TeamFoundationCollectionUri'), + 'TestExecution.EnableDiagnostics', tl.getEndpointAuthorization('SystemVssConnection', true).parameters.AccessToken); + inputParser.setEnableDiagnosticsSettings(enableDiagnostics); + + if (serverBasedRun) { + + ci.publishEvent({ + runmode: 'distributedtest', parallelism: tl.getVariable('System.ParallelExecutionType'), + testtype: tl.getInput('testSelector') + }); + + console.log(tl.loc('distributedTestWorkflow')); + console.log('======================================================'); + const inputDataContract = inputParser.parseInputsForDistributedTestRun(); + console.log('======================================================'); + const test = new distributedTest.DistributedTest(inputDataContract); + test.runDistributedTest(); + + } else { + ci.publishEvent({ runmode: 'nondistributed' }); + console.log(tl.loc('nonDistributedTestWorkflow')); + console.log('======================================================'); + const inputDataContract = inputParser.parseInputsForNonDistributedTestRun(); + const enableHydra = isHydraFlowToBeEnabled(inputDataContract); + + if (enableHydra || inputDataContract.EnableSingleAgentAPIFlow || (inputDataContract.ExecutionSettings + && inputDataContract.ExecutionSettings.RerunSettings + && inputDataContract.ExecutionSettings.RerunSettings.RerunFailedTests)) { + if (enableApiExecution) { + console.log('================== API Execution ====================='); + inputDataContract.ExecutionSettings.TestPlatformExecutionMode = 'api'; + } + const test = new nondistributedtest.NonDistributedTest(inputDataContract); + test.runNonDistributedTest(); + } else { + localtest.startTest(); + } + console.log('======================================================'); + } + } catch (error) { + tl.setResult(tl.TaskResult.Failed, error); + taskProps.result = error.message; + } + finally { + taskProps.state = 'completed'; + ci.publishEvent(taskProps); + } +} + +function isHydraFlowToBeEnabled(inputDataContract: InputDataContract) { + try { + if ((inputDataContract.ServerType && inputDataContract.ServerType.toLowerCase() === ServerTypes.HOSTED)) { + + tl.debug('Enabling Hydra flow since serverType is hosted.'); + return true; + } + + if (tl.getVariable(BackDoorVariables.FORCE_HYDRA) && tl.getVariable(BackDoorVariables.FORCE_HYDRA).toLowerCase() === 'true') { + + tl.debug(`Enabling Hydra flow since ${BackDoorVariables.FORCE_HYDRA} build variable is set to true.`); + return true; + } + + if (inputDataContract.TestReportingSettings && inputDataContract.TestReportingSettings.ExecutionStatusSettings + && !utils.Helper.isNullEmptyOrUndefined(inputDataContract.TestReportingSettings.ExecutionStatusSettings.ActionOnThresholdNotMet) + && inputDataContract.TestReportingSettings.ExecutionStatusSettings.ActionOnThresholdNotMet !== ActionOnThresholdNotMet.DONOTHING) { + + tl.debug('Enabling Hydra flow since the minimum test executed feature is being used.'); + return true; + } + + if (inputDataContract.TestReportingSettings + && !utils.Helper.isNullEmptyOrUndefined(inputDataContract.TestReportingSettings.TestResultsDirectory) + && inputDataContract.TestReportingSettings.TestResultsDirectory.toLowerCase() + !== path.join(tl.getVariable(AgentVariables.AGENT_TEMPDIRECTORY), 'TestResults').toLowerCase()) { + + tl.debug('Enabling Hydra flow since the override results directory feature is being used.'); + return true; + } + + } catch (e) { + tl.debug(`Unexpected error occurred while trying to check if hydra flow is enabled ${e}`); + ci.publishEvent({'FailedToCheckIfHydraEnabled': 'true', 'Exception': e}); + } + + return false; +} + +function isFeatureFlagEnabled(collectionUri: string, featureFlag: string, token: string): Promise { + let state = false; + const options = { + url: collectionUri + '/_apis/FeatureFlags/' + featureFlag, + json: true, + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + token + } + }; + + return new Promise((resolve, reject) => { + request(options, (err, res, faModel) => { + if (err) { + tl.warning(tl.loc('UnableToGetFeatureFlag', featureFlag)); + tl.debug('Unable to get feature flag ' + featureFlag + ' Error:' + err.message); + resolve(state); + } + if (faModel && faModel.effectiveState) { + state = ('on' === faModel.effectiveState.toLowerCase()); + tl.debug(' Final feature flag state: ' + state); + } + resolve(state); + }); + }); +} + +function isMultiConfigOnDemandRun(): boolean { + const testType = tl.getInput('testSelector'); + const parallelExecution = tl.getVariable('System.ParallelExecutionType'); + + if (testType && testType.toLowerCase() === 'testrun' && parallelExecution && parallelExecution.toLowerCase() === 'multiconfiguration') { + return true; + } + + return false; +} + +function isServerBasedRun(): boolean { + const batchType = tl.getInput('distributionBatchType'); + if (batchType && batchType === 'basedOnTestCases') { + const batchSize = tl.getInput('batchingBasedOnAgentsOption'); + if (batchSize && batchSize === 'customBatchSize') { + return true; + } + } else if (batchType && batchType === 'basedOnExecutionTime') { + return true; + } else if (batchType && batchType === 'basedOnAssembly') { + return true; + } + + const testType = tl.getInput('testSelector'); + tl.debug('Value of Test Selector :' + testType); + if (testType.toLowerCase() === 'testplan' || testType.toLowerCase() === 'testrun') { + return true; + } + + const parallelExecution = tl.getVariable('System.ParallelExecutionType'); + tl.debug('Value of ParallelExecutionType :' + parallelExecution); + + if (parallelExecution && parallelExecution.toLowerCase() === 'multimachine') { + const dontDistribute = tl.getBoolInput('dontDistribute'); + if (dontDistribute) { + return false; + } + return true; + } + + return false; +} + +if (osPlat !== 'win32') { + // Fail the task if os is not windows + tl.setResult(tl.TaskResult.Failed, tl.loc('OnlyWindowsOsSupported')); +} else { + //Starting the VsTest execution + execute(); +} diff --git a/_generated/VsTestV2/settingshelper.ts b/_generated/VsTestV2/settingshelper.ts new file mode 100644 index 000000000000..7805a1ffefa6 --- /dev/null +++ b/_generated/VsTestV2/settingshelper.ts @@ -0,0 +1,490 @@ +import * as tl from 'azure-pipelines-task-lib/task'; +import * as path from 'path'; +import * as Q from 'q'; +import * as models from './models'; +import * as utils from './helpers'; +import * as parameterParser from './parameterparser' +import * as version from './vstestversion'; +import * as fs from 'fs'; + +const xml2js = require('./node_modules/xml2js'); +const uuid = require('uuid'); + +const parser = new xml2js.Parser(); +const builder = new xml2js.Builder(); +const headlessBuilder = new xml2js.Builder({ headless: true }); + +const runSettingsExtension = '.runsettings'; +const testSettingsExtension = '.testsettings'; + +const testSettingsAgentNameTag = 'agent-5d76a195-1e43-4b90-a6ce-4ec3de87ed25'; +const testSettingsNameTag = 'testSettings-5d76a195-1e43-4b90-a6ce-4ec3de87ed25'; +const testSettingsIDTag = '5d76a195-1e43-4b90-a6ce-4ec3de87ed25'; +const testSettingsXmlnsTag = 'http://microsoft.com/schemas/VisualStudio/TeamTest/2010' + +//TestImpact collector +const testImpactFriendlyName = 'Test Impact'; +const testImpactDataCollectorTemplate = ''; + +//Video collector +const videoCollectorFriendlyName = 'Screen and Voice Recorder'; +const videoDataCollectorTemplate = ''; + +//Parallel configuration +const runSettingsForParallel = '0'; + +// TIA on for DTA Run +const runSettingsForTIAOn = ''; + +const codeCoverageFriendlyName = 'Code Coverage'; +const codeCoverageTemplate = ' .*\.dll$ .*\.exe$ .*CPPUnitTestFramework.* ^Fabrikam\.UnitTest\..* ^std::.* ^ATL::.* .*::__GetTestMethodInfo.* ^Microsoft::VisualStudio::CppCodeCoverageFramework::.* ^Microsoft::VisualStudio::CppUnitTestFramework::.* ^System\.Diagnostics\.DebuggerHiddenAttribute$ ^System\.Diagnostics\.DebuggerNonUserCodeAttribute$ ^System\.Runtime\.CompilerServices.CompilerGeneratedAttribute$ ^System\.CodeDom\.Compiler.GeneratedCodeAttribute$ ^System\.Diagnostics\.CodeAnalysis.ExcludeFromCodeCoverageAttribute$ .*\\atlmfc\\.* .*\\vctools\\.* .*\\public\\sdk\\.* .*\\microsoft sdks\\.* .*\\vc\\include\\.* .*microsoft.* ^B77A5C561934E089$ ^B03F5F7F11D50A3A$ ^31BF3856AD364E35$ ^89845DCD8080CC91$ ^71E9BCE111E9429C$ ^8F50407C4E9E73B6$ ^E361AF139669C375$ False True True False '; + +const testSettingsTemplate = ` + + + + + + + + `; + +const runSettingsTemplate = ` `; + +export async function updateSettingsFileAsRequired(settingsFile: string, isParallelRun: boolean, tiaConfig: models.TiaConfiguration, vsVersion: version.VSTestVersion, videoCollector: boolean, overrideParametersString: string, isDistributedRun: boolean, codeCoverageToolsInstallerFlow: boolean): Promise { + const defer = Q.defer(); + let result: any; + + if (!isParallelRun && !videoCollector && !tiaConfig.tiaEnabled && !overrideParametersString && !codeCoverageToolsInstallerFlow) { + defer.resolve(settingsFile); + return defer.promise; + } + + //Get extension of settings file and contents + let settingsExt = null; + if (settingsFile && fs.lstatSync(settingsFile).isFile() && settingsFile.split('.').pop().toLowerCase() === 'testsettings') { + settingsExt = testSettingsExtension; + result = await utils.Helper.getXmlContents(settingsFile); + if (!result || result.TestSettings === undefined) { + tl.warning(tl.loc('InvalidSettingsFile', settingsFile)); + settingsExt = null; + } + } else if (settingsFile && utils.Helper.pathExistsAsFile(settingsFile)) { + settingsExt = runSettingsExtension; + result = await utils.Helper.getXmlContents(settingsFile); + if (!result || result.RunSettings === undefined) { + tl.warning(tl.loc('InvalidSettingsFile', settingsFile)); + settingsExt = null; + } + } + + if (settingsExt === testSettingsExtension && result.TestSettings && + result.TestSettings.Properties && result.TestSettings.Properties[0] && + result.TestSettings.Properties[0].Property && vsVersion && !vsVersion.isTestSettingsPropertiesSupported()) { + tl.warning(tl.loc('testSettingPropertiesNotSupported')); + } + + if (overrideParametersString) { + if (settingsExt === runSettingsExtension || settingsExt === testSettingsExtension) { + result = updateSettingsWithParameters(result, overrideParametersString); + } else { + tl.warning(tl.loc('overrideNotSupported')); + } + } + + if (isParallelRun) { + if (settingsExt === testSettingsExtension) { + tl.warning(tl.loc('RunInParallelNotSupported')); + } else if (settingsExt === runSettingsExtension) { + tl.debug('Enabling run in parallel by editing given runsettings.'); + result = setupRunSettingsWithRunInParallel(result); + } else { + tl.debug('Enabling run in parallel by creating new runsettings.'); + settingsExt = runSettingsExtension; + result = await CreateSettings(runSettingsForParallel); + } + } + + if (videoCollector) { + //Enable video collector only in test settings. + let videoCollectorNode = null; + parser.parseString(videoDataCollectorTemplate, function (err, data) { + if (err) { + defer.reject(err); + } + videoCollectorNode = data; + }); + if (settingsExt === testSettingsExtension) { + tl.debug('Enabling video data collector by editing given testsettings.') + result = updateTestSettingsWithDataCollector(result, videoCollectorFriendlyName, videoCollectorNode); + } else if (settingsExt === runSettingsExtension) { + tl.warning(tl.loc('VideoCollectorNotSupportedWithRunSettings')); + } else { + tl.debug('Enabling video data collection by creating new test settings.') + settingsExt = testSettingsExtension; + result = await CreateSettings(testSettingsTemplate); + result = updateTestSettingsWithDataCollector(result, videoCollectorFriendlyName, videoCollectorNode) + } + } + + if (tiaConfig.tiaEnabled && !tiaConfig.disableEnablingDataCollector) { + let testImpactCollectorNode = null; + parser.parseString(testImpactDataCollectorTemplate, function (err, data) { + if (err) { + defer.reject(err); + } + + // Make both into an array to maintain parity with scenario where these are read from the xml file in which case they will be treated as arrays + testImpactCollectorNode = [ data ]; + testImpactCollectorNode[0].DataCollector = [ testImpactCollectorNode[0].DataCollector ]; + + if (tiaConfig.useNewCollector) { + testImpactCollectorNode[0].DataCollector[0].$.codebase = getTraceCollectorUri(vsVersion.majorVersion); + } + + testImpactCollectorNode[0].DataCollector[0].Configuration[0].ImpactLevel = getTIALevel(tiaConfig); + testImpactCollectorNode[0].DataCollector[0].Configuration[0].LogFilePath = 'true'; + + if (tiaConfig.context === 'CD') { + testImpactCollectorNode[0].DataCollector[0].Configuration[0].RootPath = ''; + } else { + testImpactCollectorNode[0].DataCollector[0].Configuration[0].RootPath = tiaConfig.sourcesDir; + } + }); + + if (settingsExt === testSettingsExtension) { + tl.debug('Enabling Test Impact collector by editing given testsettings.'); + result = updateTestSettingsWithDataCollector(result, testImpactFriendlyName, testImpactCollectorNode); + } else if (settingsExt === runSettingsExtension) { + tl.debug('Enabling Test Impact collector by editing given runsettings.'); + result = updateRunSettingsWithDataCollector(result, testImpactFriendlyName, testImpactCollectorNode); + } else { + tl.debug('Enabling test impact data collection by creating new runsettings.'); + settingsExt = runSettingsExtension; + result = await CreateSettings(runSettingsTemplate); + result = updateRunSettingsWithDataCollector(result, testImpactFriendlyName, testImpactCollectorNode); + } + } + + if (isDistributedRun && tiaConfig.tiaEnabled) { + let baseLineRunId = utils.Helper.readFileContentsSync(tiaConfig.baseLineBuildIdFile, 'utf-8'); + if (settingsExt === testSettingsExtension) { + tl.debug('Enabling tia in testsettings.'); + result = setupTestSettingsWithTestImpactOn(result, baseLineRunId); + } else if (settingsExt === runSettingsExtension) { + tl.debug('Enabling tia in runsettings.'); + result = setupRunSettingsWithTestImpactOn(result, baseLineRunId); + } else { + tl.debug('Enabling tia by creating new runsettings.'); + settingsExt = runSettingsExtension; + var runsettingsWithBaseLineRunId = runSettingsForTIAOn.replace("{0}", baseLineRunId); + result = await CreateSettings(runsettingsWithBaseLineRunId); + } + } + + if (codeCoverageToolsInstallerFlow) { + let codeCoverageNode = null; + tl.debug('Code coverage enabled in tools installer flow.'); + parser.parseString(codeCoverageTemplate, function (err, data) { + if (err) { + defer.reject(err); + } + codeCoverageNode = [ data ]; + codeCoverageNode[0].DataCollector = [ codeCoverageNode[0].DataCollector ]; + }); + + if (settingsExt === testSettingsExtension) { + tl.warning('Code coverage not supported with testsettings file when using tools installer.'); + } else if (settingsExt === runSettingsExtension) { + tl.debug('Adding code coverage settings details to runsettings file.'); + updateRunSettingsWithCodeCoverageDetails(result, codeCoverageNode, settingsFile); + tl.debug('Successfully added code coverage settings details to runsettings file.'); + } else { + tl.debug('Enabling code coverage by creating new run settings.'); + settingsExt = runSettingsExtension; + result = await CreateSettings(runSettingsTemplate); + result = updateRunSettingsWithCodeCoverageDetails(result, codeCoverageNode, settingsFile); + tl.debug('Successfully added code coverage settings details to runsettings file.'); + } + } + + if (result) { + utils.Helper.writeXmlFile(result, settingsFile, settingsExt) + .then(function (filename) { + defer.resolve(filename); + }); + } else { + tl.debug('Not editing settings file. Using specified file as it is.') + defer.resolve(settingsFile); + } + return defer.promise; +} + +function updateRunSettingsWithCodeCoverageDetails(result: any, codeCoverageNode: any, settingsFile: string) { + if (!result.RunSettings) { + tl.debug('Updating runsettings file from RunSettings node'); + result.RunSettings = { DataCollectionRunSettings: { DataCollectors: codeCoverageNode } }; + } else if (!result.RunSettings.DataCollectionRunSettings) { + tl.debug('Updating runsettings file from DataCollectionSettings node'); + result.RunSettings.DataCollectionRunSettings = { DataCollectors: codeCoverageNode }; + } else if (!result.RunSettings.DataCollectionRunSettings[0].DataCollectors) { + tl.debug('Updating runsettings file from DataCollectors node'); + result.RunSettings.DataCollectionRunSettings[0] = { DataCollectors: codeCoverageNode }; + } else { + var dataCollectorArray; + dataCollectorArray = result.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector; + if (!dataCollectorArray) { + tl.debug('Updating runsettings file from DataCollectors node'); + result.RunSettings.DataCollectionRunSettings[0] = { DataCollectors: codeCoverageNode }; + } else { + if (!isDataCollectorPresent(dataCollectorArray, codeCoverageFriendlyName)) { + tl.debug('Updating runsettings file, adding a DataCollector node'); + dataCollectorArray.push(codeCoverageNode[0].DataCollector[0]); + } + else { + try { + setUseVerifiableInstrumentationToFalse(dataCollectorArray); + } catch (error) { + throw new Error(tl.loc('InvalidSettingsFile', settingsFile)); + } + } + } + } + return result; +} + +function updateSettingsWithParameters(result: any, overrideParametersString: string) { + const overrideParameters = parameterParser.parse(overrideParametersString); + var parametersArray; + if (result.RunSettings) { + if (result.RunSettings.TestRunParameters && result.RunSettings.TestRunParameters[0] && + result.RunSettings.TestRunParameters[0].Parameter) { + tl.debug('Overriding test run parameters for run settings.'); + parametersArray = result.RunSettings.TestRunParameters[0].Parameter; + } + } + else if (result.TestSettings) { + if (result.TestSettings.Properties && result.TestSettings.Properties[0] && + result.TestSettings.Properties[0].Property) { + tl.debug('Overriding test run parameters for test settings.'); + parametersArray = result.TestSettings.Properties[0].Property; + } + } + + if (parametersArray) { + parametersArray.forEach(function (parameter) { + const key = parameter.$.Name || parameter.$.name; + if (overrideParameters[key] && overrideParameters[key].value) { + tl.debug('Overriding value for parameter : ' + key); + if (parameter.$.Value) { + parameter.$.Value = overrideParameters[key].value; + } else { + parameter.$.value = overrideParameters[key].value; + } + } + }); + } + + return result; +} + +function updateRunSettingsWithDataCollector(result: any, dataCollectorFriendlyName: string, dataCollectorNodeToAdd) { + if (!result.RunSettings) { + tl.debug('Updating runsettings file from RunSettings node'); + result.RunSettings = { DataCollectionRunSettings: { DataCollectors: dataCollectorNodeToAdd } }; + } else if (!result.RunSettings.DataCollectionRunSettings) { + tl.debug('Updating runsettings file from DataCollectionSettings node'); + result.RunSettings.DataCollectionRunSettings = { DataCollectors: dataCollectorNodeToAdd }; + } else if (!result.RunSettings.DataCollectionRunSettings[0].DataCollectors) { + tl.debug('Updating runsettings file from DataCollectors node'); + result.RunSettings.DataCollectionRunSettings[0] = { DataCollectors: dataCollectorNodeToAdd }; + } else { + var dataCollectorArray; + dataCollectorArray = result.RunSettings.DataCollectionRunSettings[0].DataCollectors[0].DataCollector; + if (!dataCollectorArray) { + tl.debug('Updating runsettings file from DataCollectors node'); + result.RunSettings.DataCollectionRunSettings[0] = { DataCollectors: dataCollectorNodeToAdd }; + } else { + if (!isDataCollectorPresent(dataCollectorArray, dataCollectorFriendlyName)) { + tl.debug('Updating runsettings file, adding a DataCollector node'); + dataCollectorArray.push(dataCollectorNodeToAdd[0].DataCollector[0]); + } + } + } + return result; +} + +function isDataCollectorPresent(dataCollectorArray, dataCollectorFriendlyName: string): Boolean { + let found = false; + for (const node of dataCollectorArray) { + if (node.$.friendlyName && node.$.friendlyName.toUpperCase() === dataCollectorFriendlyName.toUpperCase()) { + tl.debug('Data collector already present, will not add the node.'); + found = true; + break; + } + } + return found; +} + +function setUseVerifiableInstrumentationToFalse(dataCollectorArray: any) { + for (const node of dataCollectorArray) { + if (node.$.friendlyName && node.$.friendlyName.toUpperCase() === codeCoverageFriendlyName.toUpperCase()) { + if (utils.Helper.isNullEmptyOrUndefined(node.Configuration)) { + tl.debug('Updating runsettings file from CodeCoverage node'); + node.Configuration = { CodeCoverage: { UseVerifiableInstrumentation: 'False' } }; + } else if (utils.Helper.isNullEmptyOrUndefined(node.Configuration[0].CodeCoverage)) { + node.Configuration.CodeCoverage = { UseVerifiableInstrumentation: 'False' }; + tl.debug('Updating runsettings file from UseVerifiableInstrumentation node'); + } else { + node.Configuration[0].CodeCoverage[0].UseVerifiableInstrumentation = 'False'; + console.log(tl.loc('OverrideUseVerifiableInstrumentation')); + } + } + } +} + +function updateTestSettingsWithDataCollector(result: any, dataCollectorFriendlyName: string, dataCollectorNodeToAdd) { + if (!result.TestSettings) { + tl.debug('Updating testsettings file from TestSettings node'); + result.TestSettings = { Execution: { AgentRule: { DataCollectors: dataCollectorNodeToAdd } } }; + result.TestSettings.Execution.AgentRule.$ = { name: testSettingsAgentNameTag }; + result.TestSettings.$ = { name: testSettingsNameTag, id: testSettingsIDTag, xmlns: testSettingsXmlnsTag }; + } else if (!result.TestSettings.Execution) { + tl.debug('Updating testsettings file from Execution node'); + result.TestSettings.Execution = { AgentRule: { DataCollectors: dataCollectorNodeToAdd } }; + result.TestSettings.Execution.AgentRule.$ = { name: testSettingsAgentNameTag }; + } else if (!result.TestSettings.Execution[0].AgentRule) { + tl.debug('Updating testsettings file from AgentRule node'); + result.TestSettings.Execution[0] = { AgentRule: { DataCollectors: dataCollectorNodeToAdd } }; + result.TestSettings.Execution[0].AgentRule.$ = { name: testSettingsAgentNameTag }; + } else if (!result.TestSettings.Execution[0].AgentRule[0].DataCollectors) { + tl.debug('Updating testsettings file from DataCollectors node'); + result.TestSettings.Execution[0].AgentRule[0] = { DataCollectors: dataCollectorNodeToAdd }; + result.TestSettings.Execution[0].AgentRule.$ = { name: testSettingsAgentNameTag }; + } else { + var dataCollectorArray; + dataCollectorArray = result.TestSettings.Execution[0].AgentRule[0].DataCollectors[0].DataCollector; + if (!dataCollectorArray) { + tl.debug('Updating testsettings file from DataCollector node'); + result.TestSettings.Execution[0].AgentRule[0].DataCollectors[0] = dataCollectorNodeToAdd; + } else { + if (!isDataCollectorPresent(dataCollectorArray, dataCollectorFriendlyName)) { + tl.debug('Updating testsettings file, adding a DataCollector node'); + dataCollectorArray.push(dataCollectorNodeToAdd.DataCollector); + } + } + } + return result; +} + +function CreateSettings(runSettingsContents: string): Q.Promise { + const defer = Q.defer(); + parser.parseString(runSettingsContents, function (err, result) { + if (err) { + defer.reject(err); + } + defer.resolve(result); + }); + return defer.promise; +} + +function setupRunSettingsWithRunInParallel(result: any) { + const runInParallelNode = { MaxCpuCount: 0 }; + if (!result.RunSettings.RunConfiguration || !result.RunSettings.RunConfiguration[0]) { + tl.debug('Run configuration not found in the runsettings, so adding one with RunInParallel'); + result.RunSettings.RunConfiguration = runInParallelNode; + } else if (!result.RunSettings.RunConfiguration[0].MaxCpuCount) { + tl.debug('MaxCpuCount node not found in run configuration, so adding MaxCpuCount node'); + result.RunSettings.RunConfiguration[0].MaxCpuCount = 0; + } else if (result.RunSettings.RunConfiguration[0].MaxCpuCount !== 0) { + tl.debug('MaxCpuCount given in the runsettings file is not 0, so updating it to 0, given value :' + + result.RunSettings.RunConfiguration[0].MaxCpuCount); + result.RunSettings.RunConfiguration[0].MaxCpuCount = 0; + } + return result; +} + +function setupRunSettingsWithTestImpactOn(result: any, baseLineRunId: String) { + var tiaNode = { + TestImpact: { + $: { + enabled: true + } + }, + BaseLineRunId: { + $: { + value: baseLineRunId + } + }, + } + + if (!result.RunSettings.RunConfiguration) { + tl.debug('Run configuration not found in the runsettings, so adding one with TestImpact on'); + result.RunSettings.RunConfiguration = tiaNode; + } else if (!result.RunSettings.RunConfiguration[0]) { + result.RunSettings.RunConfiguration.TestImpact = {}; + result.RunSettings.RunConfiguration.BaseLineRunId = {}; + result.RunSettings.RunConfiguration.TestImpact.$ = {}; + result.RunSettings.RunConfiguration.BaseLineRunId.$ = {}; + result.RunSettings.RunConfiguration.TestImpact.$.enabled = true; + result.RunSettings.RunConfiguration.BaseLineRunId.$.value = baseLineRunId; + } else { + result.RunSettings.RunConfiguration[0].TestImpact = {}; + result.RunSettings.RunConfiguration[0].BaseLineRunId = {}; + result.RunSettings.RunConfiguration[0].TestImpact.$ = {}; + result.RunSettings.RunConfiguration[0].BaseLineRunId.$ = {}; + result.RunSettings.RunConfiguration[0].TestImpact.$.enabled = true; + result.RunSettings.RunConfiguration[0].BaseLineRunId.$.value = baseLineRunId; + } + return result; +} + +function setupTestSettingsWithTestImpactOn(result: any, baseLineRunId: String) { + var tiaNode = { + TestImpact: { + $: { + enabled: true + } + }, + BaseLineRunId: { + $: { + value: baseLineRunId + } + }, + } + + if (!result.TestSettings.Execution) { + tl.debug('Execution not found in the testsettings, so adding one with TestImpact on'); + result.TestSettings.Execution = tiaNode; + } else if (!result.TestSettings.Execution[0]) { + result.TestSettings.Execution.TestImpact = {}; + result.TestSettings.Execution.BaseLineRunId = {}; + result.TestSettings.Execution.TestImpact.$ = {}; + result.TestSettings.Execution.BaseLineRunId.$ = {}; + result.TestSettings.Execution.TestImpact.$.enabled = true; + result.TestSettings.Execution.BaseLineRunId.$.value = baseLineRunId; + } else { + result.TestSettings.Execution[0].TestImpact = {}; + result.TestSettings.Execution[0].BaseLineRunId = {}; + result.TestSettings.Execution[0].TestImpact.$ = {}; + result.TestSettings.Execution[0].BaseLineRunId.$ = {}; + result.TestSettings.Execution[0].TestImpact.$.enabled = true; + result.TestSettings.Execution[0].BaseLineRunId.$.value = baseLineRunId; + } + return result; +} + +function getTraceCollectorUri(vsVersion: any): string { + if (vsVersion === 15) { + return 'file://' + path.join(__dirname, 'TestSelector/Microsoft.VisualStudio.TraceCollector.dll'); + } else { + return 'file://' + path.join(__dirname, 'TestSelector/14.0/Microsoft.VisualStudio.TraceCollector.dll'); + } +} + +function getTIALevel(tiaConfig: models.TiaConfiguration) { + if (tiaConfig.fileLevel && tiaConfig.fileLevel.toUpperCase() === 'FALSE') { + return 'method'; + } + return 'file'; +} \ No newline at end of file diff --git a/_generated/VsTestV2/task.json b/_generated/VsTestV2/task.json new file mode 100644 index 000000000000..96a4e940f201 --- /dev/null +++ b/_generated/VsTestV2/task.json @@ -0,0 +1,664 @@ +{ + "id": "EF087383-EE5E-42C7-9A53-AB56C98420F9", + "name": "VSTest", + "friendlyName": "Visual Studio Test", + "description": "Run unit and functional tests (Selenium, Appium, Coded UI test, etc.) using the Visual Studio Test (VsTest) runner. Test frameworks that have a Visual Studio test adapter such as MsTest, xUnit, NUnit, Chutzpah (for JavaScript tests using QUnit, Mocha and Jasmine), etc. can be run. Tests can be distributed on multiple agents using this task (version 2).", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/test/vstest", + "helpMarkDown": "[Learn more about this task](https://go.microsoft.com/fwlink/?LinkId=835764)", + "category": "Test", + "visibility": [ + "Build", + "Release" + ], + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 2, + "Minor": 234, + "Patch": 0 + }, + "demands": [ + "vstest" + ], + "releaseNotes": "
                              • Run tests using an agent job: Unified agent across Build, Release and Test allows for automation agents to be used for testing purposes as well. You can distribute tests using the multi-agent job setting. The multi-config job setting can be used to replicate tests in different configurations. More information
                              • Test Impact Analysis: Automatically select and run only the tests needed to validate the code change.
                              • Use the Visual Studio Test Platform Installer task to run tests without needing a full Visual Studio installation.
                              ", + "minimumAgentVersion": "2.103.0", + "groups": [ + { + "name": "testSelection", + "displayName": "Test selection", + "isExpanded": true + }, + { + "name": "executionOptions", + "displayName": "Execution options", + "isExpanded": true + }, + { + "name": "advancedExecutionOptions", + "displayName": "Advanced execution options", + "isExpanded": false + }, + { + "name": "reportingOptions", + "displayName": "Reporting options", + "isExpanded": true + } + ], + "inputs": [ + { + "name": "testSelector", + "type": "pickList", + "label": "Select tests using", + "defaultValue": "testAssemblies", + "required": true, + "helpMarkDown": "
                              • Test assembly: Use this option to specify one or more test assemblies that contain your tests. You can optionally specify a filter criteria to select only specific tests.
                              • Test plan: Use this option to run tests from your test plan that have an automated test method associated with it.
                              • Test run: Use this option when you are setting up an environment to run tests from the Test hub. This option should not be used when running tests in a continuous integration / continuous deployment (CI/CD) pipeline.
                              • ", + "groupName": "testSelection", + "options": { + "testAssemblies": "Test assemblies", + "testPlan": "Test plan", + "testRun": "Test run" + }, + "properties": { + "EditableOptions": "True" + } + }, + { + "name": "testAssemblyVer2", + "type": "multiLine", + "label": "Test files", + "defaultValue": "**\\bin\\**\\*test.dll\n**\\bin\\**\\*tests.dll", + "required": true, + "helpMarkDown": "Run tests from the specified files.
                                Ordered tests and webtests can be run by specifying the .orderedtest and .webtest files respectively. To run .webtest, Visual Studio 2017 Update 4 or higher is needed.

                                The file paths are relative to the search folder. Supports multiple lines of minimatch patterns. [More information](https://aka.ms/minimatchexamples)", + "groupName": "testSelection", + "properties": { + "rows": "3", + "resizable": "true" + }, + "visibleRule": "testSelector = testAssemblies" + }, + { + "name": "testPlan", + "type": "pickList", + "label": "Test plan", + "defaultValue": "", + "required": true, + "helpMarkDown": "Select a test plan containing test suites with automated test cases.", + "groupName": "testSelection", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + }, + "visibleRule": "testSelector = testPlan" + }, + { + "name": "testSuite", + "type": "pickList", + "label": "Test suite", + "defaultValue": "", + "required": true, + "helpMarkDown": "Select one or more test suites containing automated test cases. Test case work items must be associated with an automated test method. [Learn more.](https://go.microsoft.com/fwlink/?linkid=847773", + "groupName": "testSelection", + "properties": { + "MultiSelect": "True", + "DisableManageLink": "True", + "EditableOptions": "True" + }, + "visibleRule": "testSelector = testPlan" + }, + { + "name": "testConfiguration", + "type": "pickList", + "label": "Test configuration", + "defaultValue": "", + "required": true, + "helpMarkDown": "Select Test Configuration.", + "groupName": "testSelection", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + }, + "visibleRule": "testSelector = testPlan" + }, + { + "name": "tcmTestRun", + "type": "string", + "label": "Test Run", + "defaultValue": "$(test.RunId)", + "required": false, + "helpMarkDown": "Test run based selection is used when triggering automated test runs from the test hub. This option cannot be used for running tests in the CI/CD pipeline.", + "groupName": "testSelection", + "properties": { + "rows": "3", + "resizable": "true" + }, + "visibleRule": "testSelector = testRun" + }, + { + "name": "searchFolder", + "type": "string", + "label": "Search folder", + "defaultValue": "$(System.DefaultWorkingDirectory)", + "required": true, + "helpMarkDown": "Folder to search for the test assemblies.", + "groupName": "testSelection" + }, + { + "name": "resultsFolder", + "type": "string", + "label": "Test results folder", + "defaultValue": "$(Agent.TempDirectory)\\TestResults", + "required": false, + "helpMarkDown": "Folder to store test results. When this input is not specified, results are stored in $(Agent.TempDirectory)/TestResults by default, which is cleaned at the end of a pipeline run. The results directory will always be cleaned up at the start of the vstest task before the tests are run. Relative folder path if provided will be considered relative to $(Agent.TempDirectory)", + "groupName": "testSelection" + }, + { + "name": "testFiltercriteria", + "type": "string", + "label": "Test filter criteria", + "defaultValue": "", + "required": false, + "helpMarkDown": "Additional criteria to filter tests from Test assemblies. For example: `Priority=1|Name=MyTestMethod`. [More information](https://msdn.microsoft.com/en-us/library/jj155796.aspx)", + "groupName": "testSelection", + "visibleRule": "testSelector = testAssemblies" + }, + { + "name": "runOnlyImpactedTests", + "type": "boolean", + "label": "Run only impacted tests", + "defaultValue": "False", + "required": false, + "helpMarkDown": "Automatically select, and run only the tests needed to validate the code change. [More information](https://aka.ms/tialearnmore)", + "groupName": "testSelection", + "visibleRule": "testSelector = testAssemblies" + }, + { + "name": "runAllTestsAfterXBuilds", + "type": "string", + "label": "Number of builds after which all tests should be run", + "defaultValue": "50", + "required": false, + "helpMarkDown": "Number of builds after which to automatically run all tests. Test Impact Analysis stores the mapping between test cases and source code. It is recommended to regenerate the mapping by running all tests, on a regular basis.", + "groupName": "testSelection", + "visibleRule": "testSelector = testAssemblies && runOnlyImpactedTests = true" + }, + { + "name": "uiTests", + "type": "boolean", + "label": "Test mix contains UI tests", + "defaultValue": "false", + "required": false, + "helpMarkDown": "To run UI tests, ensure that the agent is set to run in interactive mode. Setting up an agent to run interactively must be done before queueing the build / release. Checking this box does not configure the agent in interactive mode automatically. This option in the task is to only serve as a reminder to configure agent appropriately to avoid failures.

                                Hosted Windows agents from the VS 2015 and 2017 pools can be used to run UI tests.
                                [More information](https://aka.ms/uitestmoreinfo).", + "groupName": "testSelection" + }, + { + "name": "vstestLocationMethod", + "type": "radio", + "label": "Select test platform using", + "required": false, + "groupName": "executionOptions", + "defaultValue": "version", + "options": { + "version": "Version", + "location": "Specific location" + } + }, + { + "name": "vsTestVersion", + "type": "pickList", + "label": "Test platform version", + "defaultValue": "latest", + "required": false, + "helpMarkDown": "The version of Visual Studio test to use. If latest is specified it chooses latest Visual Studio version starting from VS2022 followed by VS2019, VS2017 and VS2015 depending on what is installed. Visual Studio 2013 is not supported. To run tests without needing Visual Studio on the agent, use the ‘Installed by tools installer’ option. Be sure to include the ‘Visual Studio Test Platform Installer’ task to acquire the test platform from nuget.", + "visibleRule": "vstestLocationMethod = version", + "groupName": "executionOptions", + "options": { + "latest": "Latest", + "17.0": "Visual Studio 2022", + "16.0": "Visual Studio 2019", + "15.0": "Visual Studio 2017", + "14.0": "Visual Studio 2015", + "toolsInstaller": "Installed by Tools Installer" + }, + "properties": { + "EditableOptions": "True" + } + }, + { + "name": "vstestLocation", + "type": "string", + "label": "Path to vstest.console.exe", + "defaultValue": "", + "required": false, + "helpMarkDown": "Optionally supply the path to VSTest.", + "visibleRule": "vstestLocationMethod = location", + "groupName": "executionOptions" + }, + { + "name": "runSettingsFile", + "type": "filePath", + "label": "Settings file", + "defaultValue": "", + "required": false, + "helpMarkDown": "Path to runsettings or testsettings file to use with the tests.", + "groupName": "executionOptions" + }, + { + "name": "overrideTestrunParameters", + "type": "multiLine", + "label": "Override test run parameters", + "defaultValue": "", + "required": false, + "helpMarkDown": "Override parameters defined in the `TestRunParameters` section of runsettings file or `Properties` section of testsettings file. For example: `-key1 value1 -key2 value2`. Note: Properties specified in testsettings file can be accessed via the TestContext using Visual Studio 2017 Update 4 or higher ", + "properties": { + "rows": "3", + "resizable": "true", + "editorExtension": "ms.vss-services-azure.parameters-grid" + }, + "groupName": "executionOptions" + }, + { + "name": "pathtoCustomTestAdapters", + "type": "string", + "label": "Path to custom test adapters", + "defaultValue": "", + "required": false, + "helpMarkDown": "Directory path to custom test adapters. Adapters residing in the same folder as the test assemblies are automatically discovered.", + "groupName": "executionOptions" + }, + { + "name": "runInParallel", + "type": "boolean", + "label": "Run tests in parallel on multi-core machines", + "defaultValue": "False", + "required": false, + "helpMarkDown": "If set, tests will run in parallel leveraging available cores of the machine. This will override the MaxCpuCount if specified in your runsettings file. [Click here](https://aka.ms/paralleltestexecution) to learn more about how tests are run in parallel.", + "groupName": "executionOptions" + }, + { + "name": "runTestsInIsolation", + "type": "boolean", + "label": "Run tests in isolation", + "defaultValue": "False", + "required": false, + "helpMarkDown": "Runs the tests in an isolated process. This makes vstest.console.exe process less likely to be stopped on an error in the tests, but tests might run slower. This option currently cannot be used when running with the multi-agent job setting.", + "groupName": "executionOptions" + }, + { + "name": "codeCoverageEnabled", + "type": "boolean", + "label": "Code coverage enabled", + "defaultValue": "False", + "required": false, + "helpMarkDown": "Collect code coverage information from the test run.", + "groupName": "executionOptions" + }, + { + "name": "otherConsoleOptions", + "type": "string", + "label": "Other console options", + "defaultValue": "", + "required": false, + "helpMarkDown": "Other console options that can be passed to vstest.console.exe, as documented here.

                                These options are not supported and will be ignored when running tests using the ‘Multi agent’ parallel setting of an agent job or when running tests using ‘Test plan’ or 'Test run' option or when a custom batching option is selected. The options can be specified using a settings file instead.

                                ", + "groupName": "executionOptions" + }, + { + "name": "distributionBatchType", + "type": "pickList", + "label": "Batch tests", + "defaultValue": "basedOnTestCases", + "required": false, + "helpMarkDown": "A batch is a group of tests. A batch of tests runs its tests at the same time and results are published for the batch. If the job in which the task runs is set to use multiple agents, each agent picks up any available batches of tests to run in parallel.

                                Based on the number of tests and agents: Simple batching based on the number of tests and agents participating in the test run.

                                Based on past running time of tests: This batching considers past running time to create batches of tests such that each batch has approximately equal running time.

                                Based on test assemblies: Tests from an assembly are batched together.", + "groupName": "advancedExecutionOptions", + "options": { + "basedOnTestCases": "Based on number of tests and agents", + "basedOnExecutionTime": "Based on past running time of tests", + "basedOnAssembly": "Based on test assemblies" + }, + "properties": { + "EditableOptions": "True" + } + }, + { + "name": "batchingBasedOnAgentsOption", + "type": "radio", + "label": "Batch options", + "required": false, + "groupName": "advancedExecutionOptions", + "defaultValue": "autoBatchSize", + "helpMarkDown": "Simple batching based on the number of tests and agents participating in the test run. When the batch size is automatically determined, each batch contains `(total number of tests / number of agents)` tests. If a batch size is specified, each batch will contain the specified number of tests.", + "options": { + "autoBatchSize": "Automatically determine the batch size", + "customBatchSize": "Specify a batch size" + }, + "visibleRule": "distributionBatchType = basedOnTestCases" + }, + { + "name": "customBatchSizeValue", + "type": "string", + "label": "Number of tests per batch", + "defaultValue": "10", + "required": true, + "helpMarkDown": "Specify batch size", + "groupName": "advancedExecutionOptions", + "visibleRule": "distributionBatchType = basedOnTestCases && batchingBasedOnAgentsOption = customBatchSize" + }, + { + "name": "batchingBasedOnExecutionTimeOption", + "type": "radio", + "label": "Batch options", + "required": false, + "groupName": "advancedExecutionOptions", + "defaultValue": "autoBatchSize", + "helpMarkDown": "This batching considers past running time to create batches of tests such that each batch has approximately equal running time. Quick running tests will be batched together, while longer running tests may belong to a separate batch. When this option is used with the multi-agent job setting, total test time is reduced to a minimum.", + "options": { + "autoBatchSize": "Automatically determine the batch time", + "customTimeBatchSize": "Specify running time per batch" + }, + "properties": { + "EditableOptions": "True" + }, + "visibleRule": "distributionBatchType = basedOnExecutionTime" + }, + { + "name": "customRunTimePerBatchValue", + "type": "string", + "label": "Running time (sec) per batch", + "defaultValue": "60", + "required": true, + "helpMarkDown": "Specify the running time (sec) per batch", + "groupName": "advancedExecutionOptions", + "visibleRule": "distributionBatchType = basedOnExecutionTime && batchingBasedOnExecutionTimeOption = customTimeBatchSize" + }, + { + "name": "dontDistribute", + "type": "boolean", + "label": "Replicate tests instead of distributing when multiple agents are used in the job", + "defaultValue": "False", + "required": false, + "helpMarkDown": "Choosing this option will not distribute tests across agents when the task is running in a multi-agent job.
                                Each of the selected test(s) will be repeated on each agent.
                                The option is not applicable when the agent job is configured to run with no parallelism or with the multi-config option.", + "groupName": "advancedExecutionOptions" + }, + { + "name": "testRunTitle", + "type": "string", + "label": "Test run title", + "defaultValue": "", + "required": false, + "helpMarkDown": "Provide a name for the test run.", + "groupName": "reportingOptions" + }, + { + "name": "platform", + "type": "string", + "label": "Build platform", + "defaultValue": "", + "required": false, + "helpMarkDown": "Build platform against which the tests should be reported. If you have defined a variable for platform in your build task, use that here.", + "groupName": "reportingOptions" + }, + { + "name": "configuration", + "type": "string", + "label": "Build configuration", + "defaultValue": "", + "required": false, + "helpMarkDown": "Build configuration against which the tests should be reported. If you have defined a variable for configuration in your build task, use that here.", + "groupName": "reportingOptions" + }, + { + "name": "publishRunAttachments", + "type": "boolean", + "label": "Upload test attachments", + "defaultValue": "true", + "required": false, + "helpMarkDown": "Opt in/out of publishing run level attachments.", + "groupName": "reportingOptions" + }, + { + "name": "failOnMinTestsNotRun", + "type": "boolean", + "label": "Fail the task if a minimum number of tests are not run.", + "defaultValue": "False", + "required": false, + "helpMarkDown": "Selecting this option will fail the task if specified minimum number of tests is not run.", + "groupName": "reportingOptions" + }, + { + "name": "minimumExpectedTests", + "type": "string", + "label": "Minimum # of tests", + "defaultValue": "1", + "required": false, + "helpMarkDown": "Specify the minimum # of tests that should be run for the task to succeed. Total tests executed is calculated as the sum of passed, failed and aborted tests.", + "groupName": "reportingOptions", + "visibleRule": "failOnMinTestsNotRun = true" + }, + { + "name": "diagnosticsEnabled", + "type": "boolean", + "label": "Collect advanced diagnostics in case of catastrophic failures", + "defaultValue": "false", + "required": false, + "helpMarkDown": "Collect advanced diagnostics in case of catastrophic failures.", + "groupName": "executionOptions" + }, + { + "name": "collectDumpOn", + "type": "pickList", + "label": "Collect process dump and attach to test run report", + "defaultValue": "onAbortOnly", + "required": false, + "helpMarkDown": "Collect process dump and attach to test run report.", + "groupName": "executionOptions", + "options": { + "onAbortOnly": "On abort only", + "always": "Always", + "never": "Never" + }, + "visibleRule": "diagnosticsEnabled = true" + }, + { + "name": "rerunFailedTests", + "type": "boolean", + "label": "Rerun failed tests", + "defaultValue": "False", + "required": false, + "helpMarkDown": "Selecting this option will rerun any failed tests until they pass or the maximum # of attempts is reached.", + "groupName": "executionOptions" + }, + { + "name": "rerunType", + "type": "pickList", + "label": "Do not rerun if test failures exceed specified threshold", + "defaultValue": "basedOnTestFailurePercentage", + "required": false, + "helpMarkDown": "Use this option to avoid rerunning tests when failure rate crosses the specified threshold. This is applicable if any environment issues leads to massive failures.
                                You can specify % failures or # of failed tests as a threshold.", + "groupName": "executionOptions", + "options": { + "basedOnTestFailurePercentage": "% failure", + "basedOnTestFailureCount": "# of failed tests" + }, + "properties": { + "EditableOptions": "True" + }, + "visibleRule": "rerunFailedTests = true" + }, + { + "name": "rerunFailedThreshold", + "type": "string", + "label": "% failure", + "defaultValue": "30", + "required": false, + "helpMarkDown": "Use this option to avoid rerunning tests when failure rate crosses the specified threshold. This is applicable if any environment issues leads to massive failures.", + "groupName": "executionOptions", + "visibleRule": "rerunFailedTests = true && rerunType = basedOnTestFailurePercentage" + }, + { + "name": "rerunFailedTestCasesMaxLimit", + "type": "string", + "label": "# of failed tests", + "defaultValue": "5", + "required": false, + "helpMarkDown": "Use this option to avoid rerunning tests when number of failed test cases crosses specified limit. This is applicable if any environment issues leads to massive failures.", + "groupName": "executionOptions", + "visibleRule": "rerunFailedTests = true && rerunType = basedOnTestFailureCount" + }, + { + "name": "rerunMaxAttempts", + "type": "string", + "label": "Maximum # of attempts", + "defaultValue": "3", + "required": false, + "helpMarkDown": "Specify the maximum # of times a failed test should be retried. If a test passes before the maximum # of attempts is reached, it will not be rerun further.", + "groupName": "executionOptions", + "visibleRule": "rerunFailedTests = true" + } + ], + "dataSourceBindings": [ + { + "target": "testPlan", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans?filterActivePlans=true&api-version=3.0-preview.2&$skip={{skip}}&$top=1000", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }", + "callbackContextTemplate": "{\"skip\": \"{{add skip 1000}}\"}", + "callbackRequiredTemplate": "{{isEqualNumber result.count 1000}}", + "initialContextTemplate": "{\"skip\": \"0\"}" + }, + { + "target": "testConfiguration", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/configurations?api-version=3.0-preview.1", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }" + }, + { + "target": "testSuite", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans/{{testPlan}}/suites?$asTreeView=true&api-version=3.0-preview.2", + "parameters": { + "testPlan": "$(testPlan)" + }, + "resultSelector": "jsonpath:$.value[*]" + } + ], + "instanceNameFormat": "VsTest - $(testSelector)", + "execution": { + "Node10": { + "target": "runvstest.js" + }, + "Node16": { + "target": "runvstest.js" + } + }, + "messages": { + "VstestLocationDoesNotExist": "The location of 'vstest.console.exe' specified '%s' does not exist.", + "VstestFailedReturnCode": "VsTest task failed.", + "VstestPassedReturnCode": "VsTest task succeeded.", + "NoMatchingTestAssemblies": "No test assemblies found matching the pattern: %s.", + "VstestNotFound": "Visual Studio %d is not found. Try again with a version that exists on your build agent machine.", + "NoVstestFound": "Test platform is not found. Try again after installing it on your build agent machine.", + "VstestFailed": "Vstest failed with error. Check logs for failures. There might be failed tests.", + "VstestTIANotSupported": "Install Visual Studio 2015 update 3 or Visual Studio 2017 RC or above to run Test Impact Analysis.", + "NoResultsToPublish": "No results found to publish.", + "ErrorWhileReadingRunSettings": "Error occurred while reading run settings file. Error : %s.", + "ErrorWhileReadingTestSettings": "Error occurred while reading test settings file. Error : %s.", + "RunInParallelNotSupported": "Running tests in parallel on multi-core machines is not supported with testsettings file. This option will be ignored.", + "InvalidSettingsFile": "The specified settings file %s is invalid or does not exist. Provide a valid settings file or clear the field.", + "UpdateThreeOrHigherRequired": "Install Visual Studio 2015 Update 3 or higher on your build agent machine to run the tests in parallel.", + "ErrorOccuredWhileSettingRegistry": "Error occurred while setting registry key, Error: %s.", + "ErrorWhileSettingTestImpactCollectorTestSettings": "Error occurred while setting Test Impact Collector in test settings file.", + "ErrorWhileSettingTestImpactCollectorRunSettings": "Error occurred while setting Test Impact Collector in run settings file.", + "ErrorWhileCreatingResponseFile": "Error occurred while creating the response file. All the tests will be executed for this run.", + "ErrorWhileUpdatingResponseFile": "Error occurred while updating the response file '%s'. All the tests will be executed for this run.", + "ErrorWhilePublishingCodeChanges": "Error occurred while publishing the code changes. All the tests will be executed for this run.", + "ErrorWhileListingDiscoveredTests": "Error occurred while discovering the tests. All the tests will be executed for this run.", + "PublishCodeChangesPerfTime": "Total time taken to publish code changes: %d milliseconds.", + "GenerateResponseFilePerfTime": "Total time taken to get response file: %d milliseconds.", + "UploadTestResultsPerfTime": "Total time taken to upload test results: %d milliseconds.", + "ErrorReadingVstestVersion": "Error reading the version of vstest.console.exe.", + "UnexpectedVersionString": "Unexpected version string detected for vstest.console.exe: %s.", + "UnexpectedVersionNumber": "Unexpected version number detected for vstest.console.exe: %s.", + "VstestDiagNotSupported": "vstest.console.exe version does not support the /diag flag. Enable diagnostics via the exe.config files", + "NoIncludePatternFound": "No include pattern found. Specify at least one include pattern to search test assemblies.", + "ErrorWhileUpdatingSettings": "Error occurred while updating the settings file. Using the specified settings file.", + "VideoCollectorNotSupportedWithRunSettings": "Video collector is not supported with run settings.", + "runTestInIsolationNotSupported": "Running tests in isolation is not supported when using the multi-agent job setting. This option will be ignored.", + "overrideNotSupported": "Overriding test run parameters is supported only with valid runsettings or testsettings file. This option will be ignored.", + "testSettingPropertiesNotSupported": "Properties specified in testsettings file can be accessed via the TestContext using Visual Studio 2017 Update 4 or higher", + "vstestVersionInvalid": "Given test platform version %s is not supported.", + "configureDtaAgentFailed": "Configuring the test agent with the server failed even after %d retries with error %s", + "otherConsoleOptionsNotSupported": "Other console options is not supported for this task configuration. This option will be ignored.", + "distributedTestWorkflow": "In distributed testing flow", + "nonDistributedTestWorkflow": "Running tests using vstest.console.exe runner.", + "dtaNumberOfAgents": "Distributed test execution, number of agents in job : %s", + "testSelectorInput": "Test selector : %s", + "searchFolderInput": "Search folder : %s", + "testFilterCriteriaInput": "Test filter criteria : %s", + "runSettingsFileInput": "Run settings file : %s", + "runInParallelInput": "Run in parallel : %s", + "runInIsolationInput": "Run in isolation : %s", + "pathToCustomAdaptersInput": "Path to custom adapters : %s", + "otherConsoleOptionsInput": "Other console options : %s", + "codeCoverageInput": "Code coverage enabled : %s", + "testPlanInput": "Test plan Id : %s", + "testplanConfigInput": "Test plan configuration Id : %s", + "testSuiteSelected": "Test suite Id selected: %s", + "testAssemblyFilterInput": "Test assemblies : %s", + "vsVersionSelected": "VisualStudio version selected for test execution : %s", + "runTestsLocally": "Run the tests locally using %s", + "vstestLocationSpecified": "%s, specified location : %s", + "uitestsparallel": "Running UI tests in parallel on the same machine can lead to errors. Consider disabling the ‘run in parallel’ option or run UI tests using a separate task. To learn more, see https://aka.ms/paralleltestexecution ", + "pathToCustomAdaptersInvalid": "Path to custom adapters '%s' should be a directory and it should exist.", + "pathToCustomAdaptersContainsNoAdapters": "Path to custom adapters '%s' does not contain any test adapters, provide a valid path.", + "testAssembliesSelector": "Test assemblies", + "testPlanSelector": "Test plan", + "testRunSelector": "Test run", + "testRunIdInvalid": "The test selection is 'Test run', but the test run ID '%s' given is invalid", + "testRunIdInput": "Test run Id : '%s'", + "testSourcesFilteringFailed": "Preparing the test sources file failed. Error : %s", + "noTestSourcesFound": "No test sources found matching the given filter '%s'", + "DontShowWERUIDisabledWarning": "Windows Error Reporting DontShowUI not set, if the windows error dialog pops-up in the middle of UI test execution than the test will hang", + "noVstestConsole": "Tests will not be executed with vstest console. Install Visual Studio 2017 RC or above to run tests via vstest console.", + "numberOfTestCasesPerSlice": "Number of test cases per batch : %s", + "invalidTestBatchSize": "Invalid batch size provided: %s", + "invalidRunTimePerBatch": "Invalid 'Running time (sec) per batch': %s", + "minimumRunTimePerBatchWarning": "'Running time (seconds) per batch' should be at least '%s' seconds. Defaulting to the minimum supported value.", + "RunTimePerBatch": "Run time per batch(sec) : %s", + "searchLocationNotDirectory": "Search folder: '%s' should be a directory and it should exist.", + "rerunFailedTests": "Rerun failed tests: %s", + "rerunFailedThreshold": "Rerun failed tests threshold: %s", + "invalidRerunFailedThreshold": "Invalid rerun failed tests threshold, defaulting to 30%", + "rerunFailedTestCasesMaxLimit": "Rerun maximum failed test case limit: %s", + "invalidRerunFailedTestCasesMaxLimit": "Invalid rerun failed tests case limit, defaulting to 5", + "rerunMaxAttempts": "Rerun maximum attempts: %s", + "invalidRerunMaxAttempts": "Invalid/Exceeded rerun maximum attempts, defaulting to 3", + "rerunNotSupported": "Install Visual Studio 2015 update 3 or Visual Studio 2017 to rerun failed tests.", + "toolsInstallerPathNotSet": "VsTest Test Platform folder was not found in cache.", + "testImpactAndCCWontWork": "Test Impact (Run only Impacted tests) and Code Coverage data collector will not work.", + "ToolsInstallerInstallationError": "The Visual Studio Test Platform tools installer did not run or did not complete the installation successfully, please refer to the following blog for information on how to use the tools installer: https://aka.ms/vstesttoolsinstaller", + "OverrideUseVerifiableInstrumentation": "Overriding UseVerifiableInstrumentation field to false in the runsettings file.", + "NoTestResultsDirectoryFound": "Test results directory not found.", + "OnlyWindowsOsSupported": "This task is supported only on Windows agents and cannot be used on other platforms.", + "MultiConfigNotSupportedWithOnDemand": "On demand runs are not supported with Multi-Configuration option. Please use 'None' or 'Multi-agent' parallelism option.", + "disabledRerun": "Disabling the rerun of failed tests as the rerun threshold provided is %s", + "UpgradeAgentMessage": "Please upgrade your agent version. https://github.com/Microsoft/vsts-agent/releases", + "VsTestVersionEmpty": "VsTestVersion is null or empty", + "UserProvidedSourceFilter": "Source filter: %s", + "UnableToGetFeatureFlag": "Unable to get feature flag: %s", + "diagnosticsInput": "Diagnostics enabled : %s", + "UncPathNotSupported": "Path to test sources search folder cannot be a UNC path. Please provide a rooted path or a path relative to $(System.DefaultWorkingDirectory).", + "LookingForBuildToolsInstalltion": "Attempting to find vstest.console from a visual studio build tools installation with version %s.", + "LookingForVsInstalltion": "Attempting to find vstest.console from a visual studio installation with version %s.", + "minTestsNotExecuted": "The specified minimum number of tests %d were not executed in the test run.", + "actionOnThresholdNotMet": "Action when minimum tests threshold not met : %s", + "minimumExpectedTests": "Minimum tests expected to be run: %d" + }, + "_buildConfigMapping": { + "Default": "2.234.0", + "Node20_229_4": "2.234.1" + } +} \ No newline at end of file diff --git a/_generated/VsTestV2/task.loc.json b/_generated/VsTestV2/task.loc.json new file mode 100644 index 000000000000..3ba54dc7281a --- /dev/null +++ b/_generated/VsTestV2/task.loc.json @@ -0,0 +1,664 @@ +{ + "id": "EF087383-EE5E-42C7-9A53-AB56C98420F9", + "name": "VSTest", + "friendlyName": "ms-resource:loc.friendlyName", + "description": "ms-resource:loc.description", + "helpUrl": "https://docs.microsoft.com/azure/devops/pipelines/tasks/test/vstest", + "helpMarkDown": "ms-resource:loc.helpMarkDown", + "category": "Test", + "visibility": [ + "Build", + "Release" + ], + "runsOn": [ + "Agent", + "DeploymentGroup" + ], + "author": "Microsoft Corporation", + "version": { + "Major": 2, + "Minor": 234, + "Patch": 0 + }, + "demands": [ + "vstest" + ], + "releaseNotes": "ms-resource:loc.releaseNotes", + "minimumAgentVersion": "2.103.0", + "groups": [ + { + "name": "testSelection", + "displayName": "ms-resource:loc.group.displayName.testSelection", + "isExpanded": true + }, + { + "name": "executionOptions", + "displayName": "ms-resource:loc.group.displayName.executionOptions", + "isExpanded": true + }, + { + "name": "advancedExecutionOptions", + "displayName": "ms-resource:loc.group.displayName.advancedExecutionOptions", + "isExpanded": false + }, + { + "name": "reportingOptions", + "displayName": "ms-resource:loc.group.displayName.reportingOptions", + "isExpanded": true + } + ], + "inputs": [ + { + "name": "testSelector", + "type": "pickList", + "label": "ms-resource:loc.input.label.testSelector", + "defaultValue": "testAssemblies", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testSelector", + "groupName": "testSelection", + "options": { + "testAssemblies": "Test assemblies", + "testPlan": "Test plan", + "testRun": "Test run" + }, + "properties": { + "EditableOptions": "True" + } + }, + { + "name": "testAssemblyVer2", + "type": "multiLine", + "label": "ms-resource:loc.input.label.testAssemblyVer2", + "defaultValue": "**\\bin\\**\\*test.dll\n**\\bin\\**\\*tests.dll", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testAssemblyVer2", + "groupName": "testSelection", + "properties": { + "rows": "3", + "resizable": "true" + }, + "visibleRule": "testSelector = testAssemblies" + }, + { + "name": "testPlan", + "type": "pickList", + "label": "ms-resource:loc.input.label.testPlan", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testPlan", + "groupName": "testSelection", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + }, + "visibleRule": "testSelector = testPlan" + }, + { + "name": "testSuite", + "type": "pickList", + "label": "ms-resource:loc.input.label.testSuite", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testSuite", + "groupName": "testSelection", + "properties": { + "MultiSelect": "True", + "DisableManageLink": "True", + "EditableOptions": "True" + }, + "visibleRule": "testSelector = testPlan" + }, + { + "name": "testConfiguration", + "type": "pickList", + "label": "ms-resource:loc.input.label.testConfiguration", + "defaultValue": "", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.testConfiguration", + "groupName": "testSelection", + "properties": { + "DisableManageLink": "True", + "EditableOptions": "True" + }, + "visibleRule": "testSelector = testPlan" + }, + { + "name": "tcmTestRun", + "type": "string", + "label": "ms-resource:loc.input.label.tcmTestRun", + "defaultValue": "$(test.RunId)", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.tcmTestRun", + "groupName": "testSelection", + "properties": { + "rows": "3", + "resizable": "true" + }, + "visibleRule": "testSelector = testRun" + }, + { + "name": "searchFolder", + "type": "string", + "label": "ms-resource:loc.input.label.searchFolder", + "defaultValue": "$(System.DefaultWorkingDirectory)", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.searchFolder", + "groupName": "testSelection" + }, + { + "name": "resultsFolder", + "type": "string", + "label": "ms-resource:loc.input.label.resultsFolder", + "defaultValue": "$(Agent.TempDirectory)\\TestResults", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.resultsFolder", + "groupName": "testSelection" + }, + { + "name": "testFiltercriteria", + "type": "string", + "label": "ms-resource:loc.input.label.testFiltercriteria", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.testFiltercriteria", + "groupName": "testSelection", + "visibleRule": "testSelector = testAssemblies" + }, + { + "name": "runOnlyImpactedTests", + "type": "boolean", + "label": "ms-resource:loc.input.label.runOnlyImpactedTests", + "defaultValue": "False", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.runOnlyImpactedTests", + "groupName": "testSelection", + "visibleRule": "testSelector = testAssemblies" + }, + { + "name": "runAllTestsAfterXBuilds", + "type": "string", + "label": "ms-resource:loc.input.label.runAllTestsAfterXBuilds", + "defaultValue": "50", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.runAllTestsAfterXBuilds", + "groupName": "testSelection", + "visibleRule": "testSelector = testAssemblies && runOnlyImpactedTests = true" + }, + { + "name": "uiTests", + "type": "boolean", + "label": "ms-resource:loc.input.label.uiTests", + "defaultValue": "false", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.uiTests", + "groupName": "testSelection" + }, + { + "name": "vstestLocationMethod", + "type": "radio", + "label": "ms-resource:loc.input.label.vstestLocationMethod", + "required": false, + "groupName": "executionOptions", + "defaultValue": "version", + "options": { + "version": "Version", + "location": "Specific location" + } + }, + { + "name": "vsTestVersion", + "type": "pickList", + "label": "ms-resource:loc.input.label.vsTestVersion", + "defaultValue": "latest", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.vsTestVersion", + "visibleRule": "vstestLocationMethod = version", + "groupName": "executionOptions", + "options": { + "latest": "Latest", + "17.0": "Visual Studio 2022", + "16.0": "Visual Studio 2019", + "15.0": "Visual Studio 2017", + "14.0": "Visual Studio 2015", + "toolsInstaller": "Installed by Tools Installer" + }, + "properties": { + "EditableOptions": "True" + } + }, + { + "name": "vstestLocation", + "type": "string", + "label": "ms-resource:loc.input.label.vstestLocation", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.vstestLocation", + "visibleRule": "vstestLocationMethod = location", + "groupName": "executionOptions" + }, + { + "name": "runSettingsFile", + "type": "filePath", + "label": "ms-resource:loc.input.label.runSettingsFile", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.runSettingsFile", + "groupName": "executionOptions" + }, + { + "name": "overrideTestrunParameters", + "type": "multiLine", + "label": "ms-resource:loc.input.label.overrideTestrunParameters", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.overrideTestrunParameters", + "properties": { + "rows": "3", + "resizable": "true", + "editorExtension": "ms.vss-services-azure.parameters-grid" + }, + "groupName": "executionOptions" + }, + { + "name": "pathtoCustomTestAdapters", + "type": "string", + "label": "ms-resource:loc.input.label.pathtoCustomTestAdapters", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.pathtoCustomTestAdapters", + "groupName": "executionOptions" + }, + { + "name": "runInParallel", + "type": "boolean", + "label": "ms-resource:loc.input.label.runInParallel", + "defaultValue": "False", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.runInParallel", + "groupName": "executionOptions" + }, + { + "name": "runTestsInIsolation", + "type": "boolean", + "label": "ms-resource:loc.input.label.runTestsInIsolation", + "defaultValue": "False", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.runTestsInIsolation", + "groupName": "executionOptions" + }, + { + "name": "codeCoverageEnabled", + "type": "boolean", + "label": "ms-resource:loc.input.label.codeCoverageEnabled", + "defaultValue": "False", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.codeCoverageEnabled", + "groupName": "executionOptions" + }, + { + "name": "otherConsoleOptions", + "type": "string", + "label": "ms-resource:loc.input.label.otherConsoleOptions", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.otherConsoleOptions", + "groupName": "executionOptions" + }, + { + "name": "distributionBatchType", + "type": "pickList", + "label": "ms-resource:loc.input.label.distributionBatchType", + "defaultValue": "basedOnTestCases", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.distributionBatchType", + "groupName": "advancedExecutionOptions", + "options": { + "basedOnTestCases": "Based on number of tests and agents", + "basedOnExecutionTime": "Based on past running time of tests", + "basedOnAssembly": "Based on test assemblies" + }, + "properties": { + "EditableOptions": "True" + } + }, + { + "name": "batchingBasedOnAgentsOption", + "type": "radio", + "label": "ms-resource:loc.input.label.batchingBasedOnAgentsOption", + "required": false, + "groupName": "advancedExecutionOptions", + "defaultValue": "autoBatchSize", + "helpMarkDown": "ms-resource:loc.input.help.batchingBasedOnAgentsOption", + "options": { + "autoBatchSize": "Automatically determine the batch size", + "customBatchSize": "Specify a batch size" + }, + "visibleRule": "distributionBatchType = basedOnTestCases" + }, + { + "name": "customBatchSizeValue", + "type": "string", + "label": "ms-resource:loc.input.label.customBatchSizeValue", + "defaultValue": "10", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.customBatchSizeValue", + "groupName": "advancedExecutionOptions", + "visibleRule": "distributionBatchType = basedOnTestCases && batchingBasedOnAgentsOption = customBatchSize" + }, + { + "name": "batchingBasedOnExecutionTimeOption", + "type": "radio", + "label": "ms-resource:loc.input.label.batchingBasedOnExecutionTimeOption", + "required": false, + "groupName": "advancedExecutionOptions", + "defaultValue": "autoBatchSize", + "helpMarkDown": "ms-resource:loc.input.help.batchingBasedOnExecutionTimeOption", + "options": { + "autoBatchSize": "Automatically determine the batch time", + "customTimeBatchSize": "Specify running time per batch" + }, + "properties": { + "EditableOptions": "True" + }, + "visibleRule": "distributionBatchType = basedOnExecutionTime" + }, + { + "name": "customRunTimePerBatchValue", + "type": "string", + "label": "ms-resource:loc.input.label.customRunTimePerBatchValue", + "defaultValue": "60", + "required": true, + "helpMarkDown": "ms-resource:loc.input.help.customRunTimePerBatchValue", + "groupName": "advancedExecutionOptions", + "visibleRule": "distributionBatchType = basedOnExecutionTime && batchingBasedOnExecutionTimeOption = customTimeBatchSize" + }, + { + "name": "dontDistribute", + "type": "boolean", + "label": "ms-resource:loc.input.label.dontDistribute", + "defaultValue": "False", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.dontDistribute", + "groupName": "advancedExecutionOptions" + }, + { + "name": "testRunTitle", + "type": "string", + "label": "ms-resource:loc.input.label.testRunTitle", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.testRunTitle", + "groupName": "reportingOptions" + }, + { + "name": "platform", + "type": "string", + "label": "ms-resource:loc.input.label.platform", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.platform", + "groupName": "reportingOptions" + }, + { + "name": "configuration", + "type": "string", + "label": "ms-resource:loc.input.label.configuration", + "defaultValue": "", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.configuration", + "groupName": "reportingOptions" + }, + { + "name": "publishRunAttachments", + "type": "boolean", + "label": "ms-resource:loc.input.label.publishRunAttachments", + "defaultValue": "true", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.publishRunAttachments", + "groupName": "reportingOptions" + }, + { + "name": "failOnMinTestsNotRun", + "type": "boolean", + "label": "ms-resource:loc.input.label.failOnMinTestsNotRun", + "defaultValue": "False", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.failOnMinTestsNotRun", + "groupName": "reportingOptions" + }, + { + "name": "minimumExpectedTests", + "type": "string", + "label": "ms-resource:loc.input.label.minimumExpectedTests", + "defaultValue": "1", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.minimumExpectedTests", + "groupName": "reportingOptions", + "visibleRule": "failOnMinTestsNotRun = true" + }, + { + "name": "diagnosticsEnabled", + "type": "boolean", + "label": "ms-resource:loc.input.label.diagnosticsEnabled", + "defaultValue": "false", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.diagnosticsEnabled", + "groupName": "executionOptions" + }, + { + "name": "collectDumpOn", + "type": "pickList", + "label": "ms-resource:loc.input.label.collectDumpOn", + "defaultValue": "onAbortOnly", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.collectDumpOn", + "groupName": "executionOptions", + "options": { + "onAbortOnly": "On abort only", + "always": "Always", + "never": "Never" + }, + "visibleRule": "diagnosticsEnabled = true" + }, + { + "name": "rerunFailedTests", + "type": "boolean", + "label": "ms-resource:loc.input.label.rerunFailedTests", + "defaultValue": "False", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.rerunFailedTests", + "groupName": "executionOptions" + }, + { + "name": "rerunType", + "type": "pickList", + "label": "ms-resource:loc.input.label.rerunType", + "defaultValue": "basedOnTestFailurePercentage", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.rerunType", + "groupName": "executionOptions", + "options": { + "basedOnTestFailurePercentage": "% failure", + "basedOnTestFailureCount": "# of failed tests" + }, + "properties": { + "EditableOptions": "True" + }, + "visibleRule": "rerunFailedTests = true" + }, + { + "name": "rerunFailedThreshold", + "type": "string", + "label": "ms-resource:loc.input.label.rerunFailedThreshold", + "defaultValue": "30", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.rerunFailedThreshold", + "groupName": "executionOptions", + "visibleRule": "rerunFailedTests = true && rerunType = basedOnTestFailurePercentage" + }, + { + "name": "rerunFailedTestCasesMaxLimit", + "type": "string", + "label": "ms-resource:loc.input.label.rerunFailedTestCasesMaxLimit", + "defaultValue": "5", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.rerunFailedTestCasesMaxLimit", + "groupName": "executionOptions", + "visibleRule": "rerunFailedTests = true && rerunType = basedOnTestFailureCount" + }, + { + "name": "rerunMaxAttempts", + "type": "string", + "label": "ms-resource:loc.input.label.rerunMaxAttempts", + "defaultValue": "3", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.rerunMaxAttempts", + "groupName": "executionOptions", + "visibleRule": "rerunFailedTests = true" + } + ], + "dataSourceBindings": [ + { + "target": "testPlan", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans?filterActivePlans=true&api-version=3.0-preview.2&$skip={{skip}}&$top=1000", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }", + "callbackContextTemplate": "{\"skip\": \"{{add skip 1000}}\"}", + "callbackRequiredTemplate": "{{isEqualNumber result.count 1000}}", + "initialContextTemplate": "{\"skip\": \"0\"}" + }, + { + "target": "testConfiguration", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/configurations?api-version=3.0-preview.1", + "resultSelector": "jsonpath:$.value[*]", + "resultTemplate": "{ \"Value\" : \"{{{id}}}\", \"DisplayValue\" : \"{{{id}}} - {{{name}}}\" }" + }, + { + "target": "testSuite", + "endpointId": "tfs:teamfoundation", + "endpointUrl": "{{endpoint.url}}/{{system.teamProject}}/_apis/test/plans/{{testPlan}}/suites?$asTreeView=true&api-version=3.0-preview.2", + "parameters": { + "testPlan": "$(testPlan)" + }, + "resultSelector": "jsonpath:$.value[*]" + } + ], + "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "execution": { + "Node10": { + "target": "runvstest.js" + }, + "Node16": { + "target": "runvstest.js" + } + }, + "messages": { + "VstestLocationDoesNotExist": "ms-resource:loc.messages.VstestLocationDoesNotExist", + "VstestFailedReturnCode": "ms-resource:loc.messages.VstestFailedReturnCode", + "VstestPassedReturnCode": "ms-resource:loc.messages.VstestPassedReturnCode", + "NoMatchingTestAssemblies": "ms-resource:loc.messages.NoMatchingTestAssemblies", + "VstestNotFound": "ms-resource:loc.messages.VstestNotFound", + "NoVstestFound": "ms-resource:loc.messages.NoVstestFound", + "VstestFailed": "ms-resource:loc.messages.VstestFailed", + "VstestTIANotSupported": "ms-resource:loc.messages.VstestTIANotSupported", + "NoResultsToPublish": "ms-resource:loc.messages.NoResultsToPublish", + "ErrorWhileReadingRunSettings": "ms-resource:loc.messages.ErrorWhileReadingRunSettings", + "ErrorWhileReadingTestSettings": "ms-resource:loc.messages.ErrorWhileReadingTestSettings", + "RunInParallelNotSupported": "ms-resource:loc.messages.RunInParallelNotSupported", + "InvalidSettingsFile": "ms-resource:loc.messages.InvalidSettingsFile", + "UpdateThreeOrHigherRequired": "ms-resource:loc.messages.UpdateThreeOrHigherRequired", + "ErrorOccuredWhileSettingRegistry": "ms-resource:loc.messages.ErrorOccuredWhileSettingRegistry", + "ErrorWhileSettingTestImpactCollectorTestSettings": "ms-resource:loc.messages.ErrorWhileSettingTestImpactCollectorTestSettings", + "ErrorWhileSettingTestImpactCollectorRunSettings": "ms-resource:loc.messages.ErrorWhileSettingTestImpactCollectorRunSettings", + "ErrorWhileCreatingResponseFile": "ms-resource:loc.messages.ErrorWhileCreatingResponseFile", + "ErrorWhileUpdatingResponseFile": "ms-resource:loc.messages.ErrorWhileUpdatingResponseFile", + "ErrorWhilePublishingCodeChanges": "ms-resource:loc.messages.ErrorWhilePublishingCodeChanges", + "ErrorWhileListingDiscoveredTests": "ms-resource:loc.messages.ErrorWhileListingDiscoveredTests", + "PublishCodeChangesPerfTime": "ms-resource:loc.messages.PublishCodeChangesPerfTime", + "GenerateResponseFilePerfTime": "ms-resource:loc.messages.GenerateResponseFilePerfTime", + "UploadTestResultsPerfTime": "ms-resource:loc.messages.UploadTestResultsPerfTime", + "ErrorReadingVstestVersion": "ms-resource:loc.messages.ErrorReadingVstestVersion", + "UnexpectedVersionString": "ms-resource:loc.messages.UnexpectedVersionString", + "UnexpectedVersionNumber": "ms-resource:loc.messages.UnexpectedVersionNumber", + "VstestDiagNotSupported": "ms-resource:loc.messages.VstestDiagNotSupported", + "NoIncludePatternFound": "ms-resource:loc.messages.NoIncludePatternFound", + "ErrorWhileUpdatingSettings": "ms-resource:loc.messages.ErrorWhileUpdatingSettings", + "VideoCollectorNotSupportedWithRunSettings": "ms-resource:loc.messages.VideoCollectorNotSupportedWithRunSettings", + "runTestInIsolationNotSupported": "ms-resource:loc.messages.runTestInIsolationNotSupported", + "overrideNotSupported": "ms-resource:loc.messages.overrideNotSupported", + "testSettingPropertiesNotSupported": "ms-resource:loc.messages.testSettingPropertiesNotSupported", + "vstestVersionInvalid": "ms-resource:loc.messages.vstestVersionInvalid", + "configureDtaAgentFailed": "ms-resource:loc.messages.configureDtaAgentFailed", + "otherConsoleOptionsNotSupported": "ms-resource:loc.messages.otherConsoleOptionsNotSupported", + "distributedTestWorkflow": "ms-resource:loc.messages.distributedTestWorkflow", + "nonDistributedTestWorkflow": "ms-resource:loc.messages.nonDistributedTestWorkflow", + "dtaNumberOfAgents": "ms-resource:loc.messages.dtaNumberOfAgents", + "testSelectorInput": "ms-resource:loc.messages.testSelectorInput", + "searchFolderInput": "ms-resource:loc.messages.searchFolderInput", + "testFilterCriteriaInput": "ms-resource:loc.messages.testFilterCriteriaInput", + "runSettingsFileInput": "ms-resource:loc.messages.runSettingsFileInput", + "runInParallelInput": "ms-resource:loc.messages.runInParallelInput", + "runInIsolationInput": "ms-resource:loc.messages.runInIsolationInput", + "pathToCustomAdaptersInput": "ms-resource:loc.messages.pathToCustomAdaptersInput", + "otherConsoleOptionsInput": "ms-resource:loc.messages.otherConsoleOptionsInput", + "codeCoverageInput": "ms-resource:loc.messages.codeCoverageInput", + "testPlanInput": "ms-resource:loc.messages.testPlanInput", + "testplanConfigInput": "ms-resource:loc.messages.testplanConfigInput", + "testSuiteSelected": "ms-resource:loc.messages.testSuiteSelected", + "testAssemblyFilterInput": "ms-resource:loc.messages.testAssemblyFilterInput", + "vsVersionSelected": "ms-resource:loc.messages.vsVersionSelected", + "runTestsLocally": "ms-resource:loc.messages.runTestsLocally", + "vstestLocationSpecified": "ms-resource:loc.messages.vstestLocationSpecified", + "uitestsparallel": "ms-resource:loc.messages.uitestsparallel", + "pathToCustomAdaptersInvalid": "ms-resource:loc.messages.pathToCustomAdaptersInvalid", + "pathToCustomAdaptersContainsNoAdapters": "ms-resource:loc.messages.pathToCustomAdaptersContainsNoAdapters", + "testAssembliesSelector": "ms-resource:loc.messages.testAssembliesSelector", + "testPlanSelector": "ms-resource:loc.messages.testPlanSelector", + "testRunSelector": "ms-resource:loc.messages.testRunSelector", + "testRunIdInvalid": "ms-resource:loc.messages.testRunIdInvalid", + "testRunIdInput": "ms-resource:loc.messages.testRunIdInput", + "testSourcesFilteringFailed": "ms-resource:loc.messages.testSourcesFilteringFailed", + "noTestSourcesFound": "ms-resource:loc.messages.noTestSourcesFound", + "DontShowWERUIDisabledWarning": "ms-resource:loc.messages.DontShowWERUIDisabledWarning", + "noVstestConsole": "ms-resource:loc.messages.noVstestConsole", + "numberOfTestCasesPerSlice": "ms-resource:loc.messages.numberOfTestCasesPerSlice", + "invalidTestBatchSize": "ms-resource:loc.messages.invalidTestBatchSize", + "invalidRunTimePerBatch": "ms-resource:loc.messages.invalidRunTimePerBatch", + "minimumRunTimePerBatchWarning": "ms-resource:loc.messages.minimumRunTimePerBatchWarning", + "RunTimePerBatch": "ms-resource:loc.messages.RunTimePerBatch", + "searchLocationNotDirectory": "ms-resource:loc.messages.searchLocationNotDirectory", + "rerunFailedTests": "ms-resource:loc.messages.rerunFailedTests", + "rerunFailedThreshold": "ms-resource:loc.messages.rerunFailedThreshold", + "invalidRerunFailedThreshold": "ms-resource:loc.messages.invalidRerunFailedThreshold", + "rerunFailedTestCasesMaxLimit": "ms-resource:loc.messages.rerunFailedTestCasesMaxLimit", + "invalidRerunFailedTestCasesMaxLimit": "ms-resource:loc.messages.invalidRerunFailedTestCasesMaxLimit", + "rerunMaxAttempts": "ms-resource:loc.messages.rerunMaxAttempts", + "invalidRerunMaxAttempts": "ms-resource:loc.messages.invalidRerunMaxAttempts", + "rerunNotSupported": "ms-resource:loc.messages.rerunNotSupported", + "toolsInstallerPathNotSet": "ms-resource:loc.messages.toolsInstallerPathNotSet", + "testImpactAndCCWontWork": "ms-resource:loc.messages.testImpactAndCCWontWork", + "ToolsInstallerInstallationError": "ms-resource:loc.messages.ToolsInstallerInstallationError", + "OverrideUseVerifiableInstrumentation": "ms-resource:loc.messages.OverrideUseVerifiableInstrumentation", + "NoTestResultsDirectoryFound": "ms-resource:loc.messages.NoTestResultsDirectoryFound", + "OnlyWindowsOsSupported": "ms-resource:loc.messages.OnlyWindowsOsSupported", + "MultiConfigNotSupportedWithOnDemand": "ms-resource:loc.messages.MultiConfigNotSupportedWithOnDemand", + "disabledRerun": "ms-resource:loc.messages.disabledRerun", + "UpgradeAgentMessage": "ms-resource:loc.messages.UpgradeAgentMessage", + "VsTestVersionEmpty": "ms-resource:loc.messages.VsTestVersionEmpty", + "UserProvidedSourceFilter": "ms-resource:loc.messages.UserProvidedSourceFilter", + "UnableToGetFeatureFlag": "ms-resource:loc.messages.UnableToGetFeatureFlag", + "diagnosticsInput": "ms-resource:loc.messages.diagnosticsInput", + "UncPathNotSupported": "ms-resource:loc.messages.UncPathNotSupported", + "LookingForBuildToolsInstalltion": "ms-resource:loc.messages.LookingForBuildToolsInstalltion", + "LookingForVsInstalltion": "ms-resource:loc.messages.LookingForVsInstalltion", + "minTestsNotExecuted": "ms-resource:loc.messages.minTestsNotExecuted", + "actionOnThresholdNotMet": "ms-resource:loc.messages.actionOnThresholdNotMet", + "minimumExpectedTests": "ms-resource:loc.messages.minimumExpectedTests" + }, + "_buildConfigMapping": { + "Default": "2.234.0", + "Node20_229_4": "2.234.1" + } +} \ No newline at end of file diff --git a/_generated/VsTestV2/taskinputparser.ts b/_generated/VsTestV2/taskinputparser.ts new file mode 100644 index 000000000000..d4fd0c8af174 --- /dev/null +++ b/_generated/VsTestV2/taskinputparser.ts @@ -0,0 +1,462 @@ +import * as path from 'path'; +import * as Q from 'q'; +import * as tl from 'azure-pipelines-task-lib/task'; +import * as models from './models'; +import * as utils from './helpers'; +import * as constants from './constants'; +import * as ci from './cieventlogger'; +import * as versionFinder from './versionfinder'; +import { AreaCodes, ResultMessages } from './constants'; +import * as uuid from 'uuid'; +const regedit = require('regedit'); + +export function getvsTestConfigurations() { + const vsTestConfiguration = {} as models.VsTestConfigurations; + initTestConfigurations(vsTestConfiguration); + vsTestConfiguration.isResponseFileRun = false; + vsTestConfiguration.publishTestResultsInTiaMode = false; + vsTestConfiguration.publishRunAttachments = tl.getInput('publishRunAttachments'); + vsTestConfiguration.vstestDiagFile = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + vsTestConfiguration.responseFile = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + vsTestConfiguration.vstestArgsFile = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + vsTestConfiguration.responseSupplementryFile = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + vsTestConfiguration.responseFileSupported = vsTestConfiguration.vsTestVersionDetails.isResponseFileSupported() || utils.Helper.isToolsInstallerFlow(vsTestConfiguration); + return vsTestConfiguration; +} + +function initDtaEnvironment(): models.DtaEnvironment { + const dtaEnvironment = {} as models.DtaEnvironment; + dtaEnvironment.tfsCollectionUrl = tl.getVariable('System.TeamFoundationCollectionUri'); + dtaEnvironment.patToken = tl.getEndpointAuthorization('SystemVssConnection', true).parameters['AccessToken']; + dtaEnvironment.agentName = tl.getVariable('Agent.MachineName') + '-' + tl.getVariable('Agent.Name') + '-' + tl.getVariable('Agent.Id'); + dtaEnvironment.environmentUri = getEnvironmentUri(); + dtaEnvironment.dtaHostLogFilePath = path.join(tl.getVariable('System.DefaultWorkingDirectory'), 'DTAExecutionHost.exe.log'); + return dtaEnvironment; +} + +function getEnvironmentUri(): string { + let environmentUri: string = ''; + + const buildId = tl.getVariable('Build.BuildId'); + const releaseId = tl.getVariable('Release.ReleaseId'); + const projectName = tl.getVariable('System.TeamProject'); + const jobId = tl.getVariable('System.JobPositionInPhase'); + const parallelExecution = tl.getVariable('System.ParallelExecutionType'); + const taskInstanceId = getDtaInstanceId(); + const dontDistribute = tl.getBoolInput('dontDistribute'); + const pipelineId = utils.Helper.isNullEmptyOrUndefined(releaseId) ? 'build'.concat(`/${buildId}`) : 'release'.concat(`/${releaseId}`); + const phaseId = utils.Helper.isNullEmptyOrUndefined(releaseId) ? + tl.getVariable('System.PhaseId') : tl.getVariable('Release.DeployPhaseId'); + + if ((!utils.Helper.isNullEmptyOrUndefined(parallelExecution) && parallelExecution.toLowerCase() === 'multiconfiguration') + || dontDistribute) { + environmentUri = `vstest://env/${projectName}/_apis/${pipelineId}/${phaseId}/${jobId}/${taskInstanceId}`; + } else { + environmentUri = `vstest://env/${projectName}/_apis/${pipelineId}/${phaseId}/${taskInstanceId}`; + } + + return environmentUri; +} + +export function getDtaInstanceId(): number { + const taskInstanceIdString = tl.getVariable('DTA_INSTANCE_ID'); + let taskInstanceId: number = 1; + if (taskInstanceIdString) { + const instanceId: number = Number(taskInstanceIdString); + if (!isNaN(instanceId)) { + taskInstanceId = instanceId + 1; + } + } + tl.setVariable('DTA_INSTANCE_ID', taskInstanceId.toString()); + return taskInstanceId; +} + +function initTestConfigurations(testConfiguration: models.TestConfigurations) { + + testConfiguration.testSelection = tl.getInput('testSelector'); + getTestSelectorBasedInputs(testConfiguration); + + testConfiguration.testDropLocation = tl.getInput('searchFolder'); + if (!utils.Helper.isNullOrWhitespace(testConfiguration.testDropLocation)) { + testConfiguration.testDropLocation = path.resolve(testConfiguration.testDropLocation); + } + + if (testConfiguration.testDropLocation && !utils.Helper.pathExistsAsDirectory(testConfiguration.testDropLocation)) { + throw new Error(tl.loc('searchLocationNotDirectory', testConfiguration.testDropLocation)); + } + console.log(tl.loc('searchFolderInput', testConfiguration.testDropLocation)); + + testConfiguration.settingsFile = tl.getPathInput('runSettingsFile'); + if (!utils.Helper.isNullOrWhitespace(testConfiguration.settingsFile)) { + testConfiguration.settingsFile = path.resolve(testConfiguration.settingsFile); + } + console.log(tl.loc('runSettingsFileInput', testConfiguration.settingsFile)); + + testConfiguration.overrideTestrunParameters = tl.getInput('overrideTestrunParameters'); + + testConfiguration.runInParallel = tl.getBoolInput('runInParallel'); + console.log(tl.loc('runInParallelInput', testConfiguration.runInParallel)); + + testConfiguration.runTestsInIsolation = tl.getBoolInput('runTestsInIsolation'); + console.log(tl.loc('runInIsolationInput', testConfiguration.runTestsInIsolation)); + + testConfiguration.runUITests = tl.getBoolInput('uiTests'); + logWarningForWER(testConfiguration.runUITests); + testConfiguration.tiaConfig = getTiaConfiguration(); + + testConfiguration.pathtoCustomTestAdapters = tl.getInput('pathtoCustomTestAdapters'); + if (!utils.Helper.isNullOrWhitespace(testConfiguration.pathtoCustomTestAdapters)) { + testConfiguration.pathtoCustomTestAdapters = path.resolve(testConfiguration.pathtoCustomTestAdapters); + } + if (testConfiguration.pathtoCustomTestAdapters && + !utils.Helper.pathExistsAsDirectory(testConfiguration.pathtoCustomTestAdapters)) { + throw new Error(tl.loc('pathToCustomAdaptersInvalid', testConfiguration.pathtoCustomTestAdapters)); + } + + console.log(tl.loc('pathToCustomAdaptersInput', testConfiguration.pathtoCustomTestAdapters)); + + testConfiguration.otherConsoleOptions = tl.getInput('otherConsoleOptions'); + console.log(tl.loc('otherConsoleOptionsInput', testConfiguration.otherConsoleOptions)); + + testConfiguration.codeCoverageEnabled = tl.getBoolInput('codeCoverageEnabled'); + console.log(tl.loc('codeCoverageInput', testConfiguration.codeCoverageEnabled)); + + testConfiguration.diagnosticsConfiguration = getDiagnosticsConfiguration(); + console.log(tl.loc('diagnosticsInput', testConfiguration.diagnosticsConfiguration.enabled)); + + testConfiguration.buildConfig = tl.getInput('configuration'); + testConfiguration.buildPlatform = tl.getInput('platform'); + testConfiguration.testRunTitle = tl.getInput('testRunTitle'); + + // Rerun information + testConfiguration.rerunFailedTests = tl.getBoolInput('rerunFailedTests'); + console.log(tl.loc('rerunFailedTests', testConfiguration.rerunFailedTests)); + + if (testConfiguration.rerunFailedTests) { + parseRerunConfiguration(); + } + + testConfiguration.vsTestLocationMethod = tl.getInput('vstestLocationMethod'); + if (testConfiguration.vsTestLocationMethod === utils.Constants.vsTestVersionString) { + testConfiguration.vsTestVersion = tl.getInput('vsTestVersion'); + if (utils.Helper.isNullEmptyOrUndefined(testConfiguration.vsTestVersion)) { + console.log('vsTestVersion is null or empty'); + throw new Error('vsTestVersion is null or empty'); + } + if (testConfiguration.vsTestVersion.toLowerCase() === 'toolsinstaller') { + tl.debug('Trying VsTest installed by tools installer.'); + ci.publishEvent({ subFeature: 'ToolsInstallerSelected', isToolsInstallerPackageLocationSet: !utils.Helper.isNullEmptyOrUndefined(tl.getVariable(constants.VsTestToolsInstaller.PathToVsTestToolVariable)) }); + + testConfiguration.toolsInstallerConfig = getToolsInstallerConfiguration(); + + // if Tools installer is not there throw. + if (utils.Helper.isNullOrWhitespace(testConfiguration.toolsInstallerConfig.vsTestPackageLocation)) { + ci.publishEvent({ subFeature: 'ToolsInstallerInstallationError' }); + utils.Helper.publishEventToCi(AreaCodes.SPECIFIEDVSVERSIONNOTFOUND, 'Tools installer task did not complete successfully.', 1040, true); + throw new Error(tl.loc('ToolsInstallerInstallationError')); + } + + ci.publishEvent({ subFeature: 'ToolsInstallerInstallationSuccessful' }); + // if tools installer is there set path to vstest.console.exe and call getVsTestRunnerDetails + testConfiguration.vsTestLocationMethod = utils.Constants.vsTestLocationString; + testConfiguration.vsTestLocation = testConfiguration.toolsInstallerConfig.vsTestConsolePathFromPackageLocation; + + testConfiguration.toolsInstallerConfig.isToolsInstallerInUse = true; + } else if ((testConfiguration.vsTestVersion !== '17.0') + && (testConfiguration.vsTestVersion !== '16.0') + && (testConfiguration.vsTestVersion !== '15.0') + && (testConfiguration.vsTestVersion !== '14.0') + && (testConfiguration.vsTestVersion.toLowerCase() !== 'latest')) { + throw new Error(tl.loc('vstestVersionInvalid', testConfiguration.vsTestVersion)); + } + console.log(tl.loc('vsVersionSelected', testConfiguration.vsTestVersion)); + } else { + testConfiguration.vsTestLocation = tl.getInput('vsTestLocation'); + console.log(tl.loc('vstestLocationSpecified', 'vstest.console.exe', testConfiguration.vsTestLocation)); + } + + if (tl.getBoolInput('uiTests') && testConfiguration.runInParallel) { + tl.warning(tl.loc('uitestsparallel')); + } + + testConfiguration.taskInstanceIdentifier = uuid.v1(); + + try { + versionFinder.getVsTestRunnerDetails(testConfiguration); + } catch (error) { + utils.Helper.publishEventToCi(AreaCodes.SPECIFIEDVSVERSIONNOTFOUND, error.message, 1039, true); + throw error; + } + + testConfiguration.ignoreTestFailures = tl.getVariable('vstest.ignoretestfailures'); + + // Get proxy details + testConfiguration.proxyConfiguration = getProxyConfiguration(); + + function parseRerunConfiguration() { + testConfiguration.rerunType = tl.getInput('rerunType') || 'basedOnTestFailurePercentage'; + + if (testConfiguration.rerunType === 'basedOnTestFailureCount') { + testConfiguration.rerunFailedTestCasesMaxLimit = 5; //default value in case of error + const rerunFailedTestCasesMaxLimit = parseInt(tl.getInput('rerunFailedTestCasesMaxLimit')); + if (!isNaN(rerunFailedTestCasesMaxLimit) && rerunFailedTestCasesMaxLimit > 0 && rerunFailedTestCasesMaxLimit <= 100) { + testConfiguration.rerunFailedTestCasesMaxLimit = rerunFailedTestCasesMaxLimit; + console.log(tl.loc('rerunFailedTestCasesMaxLimit', testConfiguration.rerunFailedTestCasesMaxLimit)); + } else { + if (rerunFailedTestCasesMaxLimit === 0) { + tl.warning(tl.loc('disabledRerun', rerunFailedTestCasesMaxLimit)); + testConfiguration.rerunFailedTests = false; + return; + } else { + tl.warning(tl.loc('invalidRerunFailedTestCasesMaxLimit')); + } + } + } else { + testConfiguration.rerunFailedThreshold = 30; //default value in case of error + const rerunFailedThreshold = parseInt(tl.getInput('rerunFailedThreshold')); + if (!isNaN(rerunFailedThreshold) && rerunFailedThreshold > 0 && rerunFailedThreshold <= 100) { + testConfiguration.rerunFailedThreshold = rerunFailedThreshold; + console.log(tl.loc('rerunFailedThreshold', testConfiguration.rerunFailedThreshold)); + } else { + if (rerunFailedThreshold === 0) { + tl.warning(tl.loc('disabledRerun', rerunFailedThreshold)); + testConfiguration.rerunFailedTests = false; + return; + } else { + tl.warning(tl.loc('invalidRerunFailedThreshold')); + } + } + } + testConfiguration.rerunMaxAttempts = 3; //default values incase of error + const rerunMaxAttempts = parseInt(tl.getInput('rerunMaxAttempts')); + if (!isNaN(rerunMaxAttempts) && rerunMaxAttempts > 0 && rerunMaxAttempts <= 10) { + testConfiguration.rerunMaxAttempts = rerunMaxAttempts; + console.log(tl.loc('rerunMaxAttempts', testConfiguration.rerunMaxAttempts)); + } else { + tl.warning(tl.loc('invalidRerunMaxAttempts')); + } + } +} + +function getProxyConfiguration(): models.ProxyConfiguration { + const proxyConfiguration = {} as models.ProxyConfiguration; + proxyConfiguration.proxyUrl = tl.getVariable("agent.proxyurl"); + proxyConfiguration.proxyUserName = tl.getVariable("agent.proxyusername"); + proxyConfiguration.proxyPassword = tl.getVariable("agent.proxypassword"); + proxyConfiguration.proxyBypassHosts = tl.getVariable("agent.proxybypasslist"); + return proxyConfiguration; +} + +export async function logWarningForWER(runUITests: boolean) { + if (!runUITests) { + return; + } + + const regPathHKLM = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting'; + const regPathHKCU = 'HKCU\\SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting'; + + const isEnabledInHKCU = await isDontShowUIRegKeySet(regPathHKCU); + const isEnabledInHKLM = await isDontShowUIRegKeySet(regPathHKLM); + + if (!isEnabledInHKCU && !isEnabledInHKLM) { + tl.warning(tl.loc('DontShowWERUIDisabledWarning')); + } +} + +export function isDontShowUIRegKeySet(regPath: string): Q.Promise { + const defer = Q.defer(); + const regValue = 'DontShowUI'; + regedit.list(regPath).on('data', (entry) => { + if (entry && entry.data && entry.data.values && + entry.data.values[regValue] && (entry.data.values[regValue].value === 1)) { + defer.resolve(true); + } + defer.resolve(false); + }); + return defer.promise; +} + +function getTestSelectorBasedInputs(testConfiguration: models.TestConfigurations) { + const testSelection = testConfiguration.testSelection.toLowerCase(); + switch (testSelection) { + case 'testplan': + console.log(tl.loc('testSelectorInput', tl.loc('testPlanSelector'))); + testConfiguration.testplan = parseInt(tl.getInput('testPlan')); + console.log(tl.loc('testPlanInput', testConfiguration.testplan)); + + testConfiguration.testPlanConfigId = parseInt(tl.getInput('testConfiguration')); + console.log(tl.loc('testplanConfigInput', testConfiguration.testPlanConfigId)); + + const testSuiteStrings = tl.getDelimitedInput('testSuite', ',', true); + testConfiguration.testSuites = new Array(); + testSuiteStrings.forEach(element => { + const testSuiteId = parseInt(element); + console.log(tl.loc('testSuiteSelected', testSuiteId)); + testConfiguration.testSuites.push(testSuiteId); + }); + testConfiguration.sourceFilter = ['**\\*', '!**\\obj\\*']; + tl.debug('Setting the test source filter for the Test plan : ' + testConfiguration.sourceFilter); + break; + case 'testassemblies': + console.log(tl.loc('testSelectorInput', tl.loc('testAssembliesSelector'))); + testConfiguration.sourceFilter = tl.getDelimitedInput('testAssemblyVer2', '\n', true); + console.log(tl.loc('testAssemblyFilterInput', testConfiguration.sourceFilter)); + + testConfiguration.testcaseFilter = tl.getInput('testFiltercriteria'); + console.log(tl.loc('testFilterCriteriaInput', testConfiguration.testcaseFilter)); + break; + case 'testrun': + console.log(tl.loc('testSelectorInput', tl.loc('testRunSelector'))); + testConfiguration.onDemandTestRunId = tl.getInput('tcmTestRun'); + if (parseInt(testConfiguration.onDemandTestRunId) <= 0) { + throw new Error(tl.loc('testRunIdInvalid', testConfiguration.onDemandTestRunId)); + } + console.log(tl.loc('testRunIdInput', testConfiguration.onDemandTestRunId)); + testConfiguration.sourceFilter = ['**\\*', '!**\\obj\\*']; + tl.debug('Setting the test source filter for the TestRun : ' + testConfiguration.sourceFilter); + break; + } +} + +function getDiagnosticsConfiguration(): models.DiagnosticsConfiguration { + const diagnosticsConfiguration = {} as models.DiagnosticsConfiguration; + // Diagnostics is not supported for non-api based local test run flows. + diagnosticsConfiguration.enabled = false; + return diagnosticsConfiguration; +} + +function getTiaConfiguration(): models.TiaConfiguration { + const tiaConfiguration = {} as models.TiaConfiguration; + tiaConfiguration.tiaEnabled = tl.getBoolInput('runOnlyImpactedTests'); + tiaConfiguration.tiaRebaseLimit = tl.getInput('runAllTestsAfterXBuilds'); + tiaConfiguration.fileLevel = tl.getVariable('tia.filelevel'); + tiaConfiguration.sourcesDir = tl.getVariable('build.sourcesdirectory'); + tiaConfiguration.tiaFilterPaths = tl.getVariable('TIA_IncludePathFilters'); + tiaConfiguration.runIdFile = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + tiaConfiguration.baseLineBuildIdFile = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + tiaConfiguration.responseFile = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + + tiaConfiguration.useNewCollector = false; + + const useNewCollector = tl.getVariable('tia.useNewCollector'); + if (useNewCollector && useNewCollector.toUpperCase() === 'TRUE') { + tiaConfiguration.useNewCollector = true; + } + + const buildReason = tl.getVariable('Build.Reason'); + + // https://www.visualstudio.com/en-us/docs/build/define/variables + // PullRequest -> This is the case for TfsGit PR flow + // CheckInShelveset -> This is the case for TFVC Gated Checkin + if (buildReason && (buildReason === 'PullRequest' || buildReason === 'CheckInShelveset')) { + tiaConfiguration.isPrFlow = 'true'; + } else { + tiaConfiguration.isPrFlow = tl.getVariable('tia.isPrFlow'); + } + tiaConfiguration.useTestCaseFilterInResponseFile = tl.getVariable('tia.useTestCaseFilterInResponseFile'); + + const releaseuri = tl.getVariable('release.releaseUri'); + tiaConfiguration.context = 'CI'; + if (releaseuri) { + tiaConfiguration.context = 'CD'; + } + + // User map file + tiaConfiguration.userMapFile = tl.getVariable('tia.usermapfile'); + + // disable editing settings file to switch on data collector + if (tl.getVariable('tia.disabletiadatacollector') && tl.getVariable('tia.disabletiadatacollector').toUpperCase() === 'TRUE') { + tiaConfiguration.disableEnablingDataCollector = true; + } else { + tiaConfiguration.disableEnablingDataCollector = false; + } + + return tiaConfiguration; +} + +function getToolsInstallerConfiguration(): models.ToolsInstallerConfiguration { + const toolsInstallerConfiguration = {} as models.ToolsInstallerConfiguration; + + tl.debug("Path to VsTest from tools installer: " + tl.getVariable(constants.VsTestToolsInstaller.PathToVsTestToolVariable)); + toolsInstallerConfiguration.vsTestPackageLocation = tl.getVariable(constants.VsTestToolsInstaller.PathToVsTestToolVariable); + + // get path to vstest.console.exe + var matches = tl.findMatch(toolsInstallerConfiguration.vsTestPackageLocation, "**\\vstest.console.exe"); + if (matches && matches.length !== 0) { + toolsInstallerConfiguration.vsTestConsolePathFromPackageLocation = matches[0]; + } else { + utils.Helper.publishEventToCi(AreaCodes.TOOLSINSTALLERCACHENOTFOUND, tl.loc('toolsInstallerPathNotSet'), 1041, false); + throw new Error(tl.loc('toolsInstallerPathNotSet')); + } + + // get path to Microsoft.IntelliTrace.ProfilerProxy.dll (amd64) + var amd64ProfilerProxy = tl.findMatch(toolsInstallerConfiguration.vsTestPackageLocation, "**\\amd64\\Microsoft.IntelliTrace.ProfilerProxy.dll"); + if (amd64ProfilerProxy && amd64ProfilerProxy.length !== 0) { + toolsInstallerConfiguration.x64ProfilerProxyDLLLocation = amd64ProfilerProxy[0]; + } else { + // Look in x64 also for Microsoft.IntelliTrace.ProfilerProxy.dll (x64) + amd64ProfilerProxy = tl.findMatch(toolsInstallerConfiguration.vsTestPackageLocation, "**\\x64\\Microsoft.IntelliTrace.ProfilerProxy.dll"); + if (amd64ProfilerProxy && amd64ProfilerProxy.length !== 0) { + toolsInstallerConfiguration.x64ProfilerProxyDLLLocation = amd64ProfilerProxy[0]; + } else { + utils.Helper.publishEventToCi(AreaCodes.TOOLSINSTALLERCACHENOTFOUND, tl.loc('testImpactAndCCWontWork'), 1043, false); + tl.warning(tl.loc('testImpactAndCCWontWork')); + } + + utils.Helper.publishEventToCi(AreaCodes.TOOLSINSTALLERCACHENOTFOUND, tl.loc('testImpactAndCCWontWork'), 1042, false); + tl.warning(tl.loc('testImpactAndCCWontWork')); + } + + // get path to Microsoft.IntelliTrace.ProfilerProxy.dll (x86) + var x86ProfilerProxy = tl.findMatch(toolsInstallerConfiguration.vsTestPackageLocation, "**\\x86\\Microsoft.IntelliTrace.ProfilerProxy.dll"); + if (x86ProfilerProxy && x86ProfilerProxy.length !== 0) { + toolsInstallerConfiguration.x86ProfilerProxyDLLLocation = x86ProfilerProxy[0]; + } else { + utils.Helper.publishEventToCi(AreaCodes.TOOLSINSTALLERCACHENOTFOUND, tl.loc('testImpactAndCCWontWork'), 1044, false); + tl.warning(tl.loc('testImpactAndCCWontWork')); + } + + return toolsInstallerConfiguration; +} + +function getDistributionBatchSize(dtaTestConfiguration: models.DtaTestConfigurations) { + const distributeOption = tl.getInput('distributionBatchType'); + if (distributeOption && distributeOption === 'basedOnTestCases') { + dtaTestConfiguration.batchingType = models.BatchingType.TestCaseBased; + // flow if the batch type = based on agents/custom batching + const distributeByAgentsOption = tl.getInput('batchingBasedOnAgentsOption'); + if (distributeByAgentsOption && distributeByAgentsOption === 'customBatchSize') { + const batchSize = parseInt(tl.getInput('customBatchSizeValue')); + if (!isNaN(batchSize) && batchSize > 0) { + dtaTestConfiguration.numberOfTestCasesPerSlice = batchSize; + console.log(tl.loc('numberOfTestCasesPerSlice', dtaTestConfiguration.numberOfTestCasesPerSlice)); + } else { + throw new Error(tl.loc('invalidTestBatchSize', batchSize)); + } + } + // by default we set the distribution = number of agents + } else if (distributeOption && distributeOption === 'basedOnExecutionTime') { + dtaTestConfiguration.batchingType = models.BatchingType.TestExecutionTimeBased; + // flow if the batch type = based on agents/custom batching + const batchBasedOnExecutionTimeOption = tl.getInput('batchingBasedOnExecutionTimeOption'); + if (batchBasedOnExecutionTimeOption && batchBasedOnExecutionTimeOption === 'customTimeBatchSize') { + const batchExecutionTimeInSec = parseInt(tl.getInput('customRunTimePerBatchValue')); + if (isNaN(batchExecutionTimeInSec) || batchExecutionTimeInSec <= 0) { + throw new Error(tl.loc('invalidRunTimePerBatch', batchExecutionTimeInSec)); + } + + dtaTestConfiguration.runningTimePerBatchInMs = 60 * 1000; + if (batchExecutionTimeInSec >= 60) { + dtaTestConfiguration.runningTimePerBatchInMs = batchExecutionTimeInSec * 1000; + console.log(tl.loc('RunTimePerBatch', dtaTestConfiguration.runningTimePerBatchInMs)); + } else { + tl.warning(tl.loc('minimumRunTimePerBatchWarning', 60)); + } + } else if (batchBasedOnExecutionTimeOption && batchBasedOnExecutionTimeOption === 'autoBatchSize') { + dtaTestConfiguration.runningTimePerBatchInMs = 0; + } + } else if (distributeOption && distributeOption === 'basedOnAssembly') { + dtaTestConfiguration.batchingType = models.BatchingType.AssemblyBased; + } + return 0; +} \ No newline at end of file diff --git a/_generated/VsTestV2/testagent.ts b/_generated/VsTestV2/testagent.ts new file mode 100644 index 000000000000..fa012bb43eca --- /dev/null +++ b/_generated/VsTestV2/testagent.ts @@ -0,0 +1,33 @@ +import * as tl from 'azure-pipelines-task-lib/task'; +import * as webapim from 'vso-node-api/WebApi'; +import * as models from './models'; + +export class TestAgent { + public static async createAgent(environment: models.DtaEnvironment, retries: number) { + var currentRetryCount = retries; + while(currentRetryCount > 0) { + currentRetryCount--; + try { + const envUrlRef: any = { Url: environment.environmentUri }; + const machineNameRef: any = { Name: environment.agentName }; + // TODO : Change any to appropriate types once promiseme package is avialable + const testAgent: any = { + Name: environment.agentName, + Capabilities: [], + DtlEnvironment: envUrlRef, + DtlMachine: machineNameRef }; + const webapi: any = new webapim.WebApi(environment.tfsCollectionUrl, webapim.getBearerHandler(environment.patToken)); + const testApi: any = webapi.getTestApi(); + const registeredAgent = await testApi.createAgent(testAgent); + tl.debug('created the test agent entry in DTA service, id : ' + registeredAgent.id); + return registeredAgent.id; + } catch (error) { + tl.error('Error : created the test agent entry in DTA service, so retrying => retries pending : ' + currentRetryCount + + 'error details :' + error); + if(currentRetryCount === 0) { + throw new Error(tl.loc("configureDtaAgentFailed", retries, error)); + } + } + } + } +} \ No newline at end of file diff --git a/_generated/VsTestV2/testselectorinvoker.ts b/_generated/VsTestV2/testselectorinvoker.ts new file mode 100644 index 000000000000..505b60acfb73 --- /dev/null +++ b/_generated/VsTestV2/testselectorinvoker.ts @@ -0,0 +1,287 @@ +import models = require('./models'); +import tl = require('azure-pipelines-task-lib/task'); +import tr = require('azure-pipelines-task-lib/toolrunner'); +import path = require('path'); +import { Helper } from './helpers'; +const uuid = require('uuid'); +let perf = require('performance-now'); + +export class TestSelectorInvoker { + public publishCodeChanges(tiaConfig: models.TiaConfiguration, proxyConfig: models.ProxyConfiguration, testCaseFilterFile: string, taskInstanceIdentifier: string): number { + tl.debug('Entered publish code changes'); + + const startTime = perf(); + let endTime: number; + let elapsedTime: number; + let pathFilters: string; + let definitionRunId: string; + let definitionId: string; + let prFlow: string; + let rebaseLimit: string; + let sourcesDirectory: string; + + let newprovider = 'true'; + if (this.getTIALevel(tiaConfig) === 'method') { + newprovider = 'false'; + } + + const selectortool = tl.tool(this.getTestSelectorLocation()); + selectortool.arg('PublishCodeChanges'); + + if (tiaConfig.context === 'CD') { + // Release context. Passing Release Id. + definitionRunId = tl.getVariable('Release.ReleaseId'); + definitionId = tl.getVariable('release.DefinitionId'); + } else { + // Build context. Passing build id. + definitionRunId = tl.getVariable('Build.BuildId'); + definitionId = tl.getVariable('System.DefinitionId'); + } + + if (tiaConfig.isPrFlow && tiaConfig.isPrFlow.toUpperCase() === 'TRUE') { + prFlow = 'true'; + } else { + prFlow = 'false'; + } + + if (tiaConfig.tiaRebaseLimit) { + rebaseLimit = tiaConfig.tiaRebaseLimit; + } + + if (typeof tiaConfig.tiaFilterPaths !== 'undefined') { + pathFilters = tiaConfig.tiaFilterPaths.trim(); + } else { + pathFilters = ''; + } + + if (typeof tiaConfig.sourcesDir !== 'undefined') { + sourcesDirectory = tiaConfig.sourcesDir.trim(); + } else { + sourcesDirectory = ''; + } + + let output = selectortool.execSync({ + cwd: null, + env: { + 'collectionurl': tl.getVariable('System.TeamFoundationCollectionUri'), + 'projectid': tl.getVariable('System.TeamProject'), + 'definitionrunid': definitionRunId, + 'definitionid': definitionId, + 'token': tl.getEndpointAuthorizationParameter('SystemVssConnection', 'AccessToken', false), + 'sourcesdir': sourcesDirectory, + 'newprovider': newprovider, + 'prflow': prFlow, + 'rebaselimit': rebaseLimit, + 'baselinefile': tiaConfig.baseLineBuildIdFile, + 'context': tiaConfig.context, + 'filter': pathFilters, + 'userMapFile': tiaConfig.userMapFile ? tiaConfig.userMapFile : '', + 'testCaseFilterResponseFile': testCaseFilterFile ? testCaseFilterFile : '', + 'proxyurl': proxyConfig.proxyUrl, + 'proxyusername': proxyConfig.proxyUserName, + 'proxypassword': proxyConfig.proxyPassword, + 'proxybypasslist': proxyConfig.proxyBypassHosts, + 'AGENT_VERSION': tl.getVariable('AGENT.VERSION'), + 'VsTest_TaskInstanceIdentifier': taskInstanceIdentifier, + 'VSTS_HTTP_RETRY': tl.getVariable('VSTS_HTTP_RETRY'), + 'VSTS_HTTP_TIMEOUT': tl.getVariable('VSTS_HTTP_TIMEOUT'), + 'DebugLogging': this.isDebugEnabled() + }, + silent: null, + outStream: null, + errStream: null, + windowsVerbatimArguments: null + }); + + endTime = perf(); + elapsedTime = endTime - startTime; + console.log('##vso[task.logissue type=warning;SubTaskName=PublishCodeChanges;SubTaskDuration=' + elapsedTime + ']'); + tl.debug(tl.loc('PublishCodeChangesPerfTime', elapsedTime)); + + if (output.code !== 0) { + tl.warning(output.stderr); + } + + tl.debug('completed publish code changes'); + return output.code; + } + + public generateResponseFile(tiaConfig: models.TiaConfiguration, vstestConfig: models.VsTestConfigurations, discoveredTests: string, testCaseFilterOutputFile: string): number { + const startTime = perf(); + let endTime: number; + let elapsedTime: number; + let definitionRunId: string; + let title: string; + let platformInput: string; + let configurationInput: string; + let useTestCaseFilterInResponseFile: string; + tl.debug('Response file will be generated at ' + tiaConfig.responseFile); + tl.debug('RunId file will be generated at ' + tiaConfig.runIdFile); + + const selectortool = tl.tool(this.getTestSelectorLocation()); + selectortool.arg('GetImpactedtests'); + + if (tiaConfig.context === 'CD') { + // Release context. Passing Release Id. + definitionRunId = tl.getVariable('Release.ReleaseId'); + } else { + // Build context. Passing build id. + definitionRunId = tl.getVariable('Build.BuildId'); + } + + if (vstestConfig.buildPlatform) { + platformInput = vstestConfig.buildPlatform; + } else { + platformInput = ''; + } + + if (vstestConfig.testRunTitle) { + title = vstestConfig.testRunTitle; + } else { + title = ''; + } + + if (vstestConfig.buildConfig) { + configurationInput = vstestConfig.buildConfig; + } else { + configurationInput = ''; + } + + if (tiaConfig.useTestCaseFilterInResponseFile && tiaConfig.useTestCaseFilterInResponseFile.toUpperCase() === 'TRUE') { + useTestCaseFilterInResponseFile = 'true'; + } else { + useTestCaseFilterInResponseFile = 'false'; + } + + let output = selectortool.execSync({ + cwd: null, + env: { + 'collectionurl': tl.getVariable('System.TeamFoundationCollectionUri'), + 'projectid': tl.getVariable('System.TeamProject'), + 'definitionrunid': definitionRunId, + 'releaseuri': tl.getVariable('release.releaseUri'), + 'releaseenvuri': tl.getVariable('release.environmentUri'), + 'token': tl.getEndpointAuthorizationParameter('SystemVssConnection', 'AccessToken', false), + 'responsefilepath': tiaConfig.responseFile, + 'discoveredtestspath': discoveredTests, + 'runidfilepath': tiaConfig.runIdFile, + 'testruntitle': title, + 'baselinebuildfilepath': tiaConfig.baseLineBuildIdFile, + 'context': tiaConfig.context, + 'platform': platformInput, + 'configuration': configurationInput, + 'useTestCaseFilterInResponseFile': useTestCaseFilterInResponseFile, + 'testCaseFilterOutputFile': testCaseFilterOutputFile ? testCaseFilterOutputFile : "", + 'isCustomEngineEnabled': String(!Helper.isNullOrWhitespace(tiaConfig.userMapFile)), + 'proxyurl': vstestConfig.proxyConfiguration.proxyUrl, + 'proxyusername': vstestConfig.proxyConfiguration.proxyUserName, + 'proxypassword': vstestConfig.proxyConfiguration.proxyPassword, + 'proxybypasslist': vstestConfig.proxyConfiguration.proxyBypassHosts, + 'AGENT_VERSION': tl.getVariable('AGENT.VERSION'), + 'VsTest_TaskInstanceIdentifier': vstestConfig.taskInstanceIdentifier, + 'VSTS_HTTP_RETRY': tl.getVariable('VSTS_HTTP_RETRY'), + 'VSTS_HTTP_TIMEOUT': tl.getVariable('VSTS_HTTP_TIMEOUT'), + 'DebugLogging': this.isDebugEnabled() + }, + silent: null, + outStream: null, + errStream: null, + windowsVerbatimArguments: null + }); + + endTime = perf(); + elapsedTime = endTime - startTime; + console.log('##vso[task.logissue type=warning;SubTaskName=GetImpactedTests;SubTaskDuration=' + elapsedTime + ']'); + tl.debug(tl.loc('GenerateResponseFilePerfTime', elapsedTime)); + + if (output.code !== 0) { + tl.error(output.stderr); + } + + tl.debug('completed publish code changes'); + return output.code; + } + + public uploadTestResults(tiaConfig: models.TiaConfiguration, vstestConfig: models.VsTestConfigurations, testResultsDirectory: string): number { + const startTime = perf(); + let endTime; + let elapsedTime; + let definitionRunId: string; + let resultFile: string; + let resultFiles; + if (!Helper.isNullOrWhitespace(testResultsDirectory)) { + resultFiles = tl.findMatch(testResultsDirectory, path.join(testResultsDirectory, '*.trx')); + } + + const selectortool = tl.tool(this.getTestSelectorLocation()); + selectortool.arg('UpdateTestResults'); + + if (tiaConfig.context === 'CD') { + definitionRunId = tl.getVariable('Release.ReleaseId'); + } else { + definitionRunId = tl.getVariable('Build.BuildId'); + } + + if (resultFiles && resultFiles[0]) { + resultFile = resultFiles[0]; + } + + let output = selectortool.execSync({ + cwd: null, + env: { + 'collectionurl': tl.getVariable('System.TeamFoundationCollectionUri'), + 'projectid': tl.getVariable('System.TeamProject'), + 'definitionrunid': definitionRunId, + 'token': tl.getEndpointAuthorizationParameter('SystemVssConnection', 'AccessToken', false), + 'resultfile': resultFile, + 'runidfile': tiaConfig.runIdFile, + 'context': tiaConfig.context, + 'proxyurl': vstestConfig.proxyConfiguration.proxyUrl, + 'proxyusername': vstestConfig.proxyConfiguration.proxyUserName, + 'proxypassword': vstestConfig.proxyConfiguration.proxyPassword, + 'proxybypasslist': vstestConfig.proxyConfiguration.proxyBypassHosts, + 'AGENT_VERSION': tl.getVariable('AGENT.VERSION'), + 'VsTest_TaskInstanceIdentifier': vstestConfig.taskInstanceIdentifier, + 'VSTS_HTTP_RETRY': tl.getVariable('VSTS_HTTP_RETRY'), + 'VSTS_HTTP_TIMEOUT': tl.getVariable('VSTS_HTTP_TIMEOUT'), + 'DebugLogging': this.isDebugEnabled() + }, + silent: null, + outStream: null, + errStream: null, + windowsVerbatimArguments: null + }); + + endTime = perf(); + elapsedTime = endTime - startTime; + console.log('##vso[task.logissue type=warning;SubTaskName=UploadTestResults;SubTaskDuration=' + elapsedTime + ']'); + tl.debug(tl.loc('UploadTestResultsPerfTime', elapsedTime)); + + if (output.code !== 0) { + tl.error(output.stderr); + } + + tl.debug('Completed updating test results'); + return output.code; + } + + private getTIALevel(tiaConfig: models.TiaConfiguration) { + if (tiaConfig.fileLevel && tiaConfig.fileLevel.toUpperCase() === 'FALSE') { + return 'method'; + } + return 'file'; + } + + private getTestSelectorLocation(): string { + return path.join(__dirname, 'TestSelector/TestSelector.exe'); + } + + private isDebugEnabled(): string { + const sysDebug = tl.getVariable('System.Debug'); + if (sysDebug === undefined) { + return "false"; + } + + return sysDebug.toLowerCase() === 'true' ? "true" : "false"; + } +} \ No newline at end of file diff --git a/_generated/VsTestV2/tsconfig.json b/_generated/VsTestV2/tsconfig.json new file mode 100644 index 000000000000..69e1238721de --- /dev/null +++ b/_generated/VsTestV2/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs", + "allowJs": true + } +} \ No newline at end of file diff --git a/_generated/VsTestV2/typings.json b/_generated/VsTestV2/typings.json new file mode 100644 index 000000000000..b87711f54fd4 --- /dev/null +++ b/_generated/VsTestV2/typings.json @@ -0,0 +1,9 @@ +{ + "name": "VSTS.VsTest", + "dependencies": {}, + "globalDependencies": { + "mocha": "registry:dt/mocha#2.2.5+20160720003353", + "node": "registry:dt/node#6.0.0+20160914131736", + "q": "registry:dt/q#0.0.0+20160613154756" + } +} diff --git a/_generated/VsTestV2/versionfinder.ts b/_generated/VsTestV2/versionfinder.ts new file mode 100644 index 000000000000..6a6b14b1c385 --- /dev/null +++ b/_generated/VsTestV2/versionfinder.ts @@ -0,0 +1,194 @@ +import * as tl from 'azure-pipelines-task-lib/task'; +import tr = require('azure-pipelines-task-lib/toolrunner'); +import * as path from 'path'; +import * as models from './models'; +import * as version from './vstestversion'; +import * as utils from './helpers'; +import * as ci from './cieventlogger'; + +const regedit = require('regedit'); + +export function getVsTestRunnerDetails(testConfig: models.TestConfigurations) { + const vstestexeLocation = locateVSTestConsole(testConfig); + + // Temporary hack for 16.0. All this code will be removed once we migrate to the Hydra flow + if (testConfig.vsTestVersion === '16.0') { + testConfig.vsTestVersionDetails = new version.VSTestVersion(vstestexeLocation, 16, 0, 0); + return; + } + + const vstestLocationEscaped = vstestexeLocation.replace(/\\/g, '\\\\'); + const wmicTool = tl.tool('wmic'); + const wmicArgs = ['datafile', 'where', 'name=\''.concat(vstestLocationEscaped, '\''), 'get', 'Version', '/Value']; + wmicTool.arg(wmicArgs); + let output = wmicTool.execSync({ silent: true } as tr.IExecSyncOptions).stdout; + + if (utils.Helper.isNullOrWhitespace(output)) { + tl.error(tl.loc('ErrorReadingVstestVersion')); + throw new Error(tl.loc('ErrorReadingVstestVersion')); + } + output = output.trim(); + tl.debug('VSTest Version information: ' + output); + const verSplitArray = output.split('='); + if (verSplitArray.length !== 2) { + tl.error(tl.loc('ErrorReadingVstestVersion')); + throw new Error(tl.loc('ErrorReadingVstestVersion')); + } + + const versionArray = verSplitArray[1].split('.'); + if (versionArray.length !== 4) { + tl.warning(tl.loc('UnexpectedVersionString', output)); + throw new Error(tl.loc('UnexpectedVersionString', output)); + } + + const majorVersion = parseInt(versionArray[0]); + const minorVersion = parseInt(versionArray[1]); + const patchNumber = parseInt(versionArray[2]); + + ci.publishEvent({ testplatform: `${majorVersion}.${minorVersion}.${patchNumber}` }); + + if (isNaN(majorVersion) || isNaN(minorVersion) || isNaN(patchNumber)) { + tl.warning(tl.loc('UnexpectedVersionNumber', verSplitArray[1])); + throw new Error(tl.loc('UnexpectedVersionNumber', verSplitArray[1])); + } + + switch (majorVersion) { + case 14: + testConfig.vsTestVersionDetails = new version.Dev14VSTestVersion(vstestexeLocation, minorVersion, patchNumber); + break; + case 15: + testConfig.vsTestVersionDetails = new version.Dev15VSTestVersion(vstestexeLocation, minorVersion, patchNumber); + break; + default: + testConfig.vsTestVersionDetails = new version.VSTestVersion(vstestexeLocation, majorVersion, minorVersion, patchNumber); + break; + } +} + +function locateVSTestConsole(testConfig: models.TestConfigurations): string { + const vstestExeFolder = locateTestWindow(testConfig); + let vstestExePath: string = vstestExeFolder; + if (vstestExeFolder) { + vstestExePath = path.join(vstestExeFolder, 'vstest.console.exe'); + } + return vstestExePath; +} + +function locateTestWindow(testConfig: models.TestConfigurations): string { + if (testConfig.vsTestLocationMethod === utils.Constants.vsTestLocationString) { + if (utils.Helper.pathExistsAsFile(testConfig.vsTestLocation)) { + return path.join(testConfig.vsTestLocation, '..'); + } + + if (utils.Helper.pathExistsAsDirectory(testConfig.vsTestLocation) && + utils.Helper.pathExistsAsFile(path.join(testConfig.vsTestLocation, 'vstest.console.exe'))) { + return testConfig.vsTestLocation; + } + throw (new Error(tl.loc('VstestLocationDoesNotExist', testConfig.vsTestLocation))); + } + + if (testConfig.vsTestVersion.toLowerCase() === 'latest') { + // latest + tl.debug('Searching for latest Visual Studio'); + + let vstestconsolePath = getVSTestConsolePath('17.0', '18.0'); + if (vstestconsolePath) { + testConfig.vsTestVersion = "17.0"; + return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform'); + } + vstestconsolePath = getVSTestConsolePath('16.0', '17.0'); + if (vstestconsolePath) { + testConfig.vsTestVersion = "16.0"; + return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform'); + } + + vstestconsolePath = getVSTestConsolePath('15.0', '16.0'); + if (vstestconsolePath) { + testConfig.vsTestVersion = "15.0"; + return path.join(vstestconsolePath, 'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'TestWindow'); + } + + // fallback + tl.debug('Unable to find an instance of Visual Studio 2017..'); + tl.debug('Searching for Visual Studio 2015..'); + testConfig.vsTestVersion = "14.0"; + return getVSTestLocation(14); + } + + const vsVersion: number = parseFloat(testConfig.vsTestVersion); + + if (vsVersion === 17.0) { //Visual Studio 2022 + const vstestconsolePath = getVSTestConsolePath('17.0', '18.0'); + if (vstestconsolePath) { + return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform'); + } + throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion)))); + } + + if (vsVersion === 16.0) { + const vstestconsolePath = getVSTestConsolePath('16.0', '17.0'); + if (vstestconsolePath) { + return path.join(vstestconsolePath, 'Common7', 'IDE', 'Extensions', 'TestPlatform'); + } + throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion)))); + } + + if (vsVersion === 15.0) { + const vstestconsolePath = getVSTestConsolePath('15.0', '16.0'); + if (vstestconsolePath) { + return path.join(vstestconsolePath, 'Common7', 'IDE', 'CommonExtensions', 'Microsoft', 'TestWindow'); + } + throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion)))); + } + + tl.debug('Searching for Visual Studio ' + vsVersion.toString()); + return getVSTestLocation(vsVersion); +} + +export function getVSTestConsolePath(versionLowerLimit : string, versionUpperLimit : string): string { + let vswhereTool = tl.tool(path.join(__dirname, 'vswhere.exe')); + + console.log(tl.loc('LookingForVsInstalltion', `[${versionLowerLimit},${versionUpperLimit})`)); + vswhereTool.line(`-version [${versionLowerLimit},${versionUpperLimit}) -latest -products * -requires Microsoft.VisualStudio.PackageGroup.TestTools.Core -property installationPath`); + let vsPath = vswhereTool.execSync({ silent: true } as tr.IExecSyncOptions).stdout; + vsPath = utils.Helper.trimString(vsPath); + if (!utils.Helper.isNullOrWhitespace(vsPath)) { + tl.debug('Visual Studio 15.0 or higher installed path: ' + vsPath); + return vsPath; + } + + // look for build tool installation if full VS not present + console.log(tl.loc('LookingForBuildToolsInstalltion', `[${versionLowerLimit},${versionUpperLimit})`)); + vswhereTool = tl.tool(path.join(__dirname, 'vswhere.exe')); + vswhereTool.line(`-version [${versionLowerLimit},${versionUpperLimit}) -latest -products * -requires Microsoft.VisualStudio.Component.TestTools.BuildTools -property installationPath`); + vsPath = vswhereTool.execSync({ silent: true } as tr.IExecSyncOptions).stdout; + vsPath = utils.Helper.trimString(vsPath); + if (!utils.Helper.isNullOrWhitespace(vsPath)) { + tl.debug('Build tools installed path: ' + vsPath); + return vsPath; + } + + return null; +} + +export function getVSTestLocation(vsVersion: number): string { + const vsCommon: string = tl.getVariable('VS' + vsVersion + '0COMNTools'); + if (!vsCommon) { + throw (new Error(tl.loc('VstestNotFound', utils.Helper.getVSVersion(vsVersion)))); + } + return path.join(vsCommon, '..\\IDE\\CommonExtensions\\Microsoft\\TestWindow'); +} + +function getFloatsFromStringArray(inputArray: string[]): number[] { + const outputArray: number[] = []; + let count; + if (inputArray) { + for (count = 0; count < inputArray.length; count++) { + const floatValue = parseFloat(inputArray[count]); + if (!isNaN(floatValue)) { + outputArray.push(floatValue); + } + } + } + return outputArray; +} \ No newline at end of file diff --git a/_generated/VsTestV2/vstest.ts b/_generated/VsTestV2/vstest.ts new file mode 100644 index 000000000000..97854503b54d --- /dev/null +++ b/_generated/VsTestV2/vstest.ts @@ -0,0 +1,753 @@ +import * as tl from 'azure-pipelines-task-lib/task'; +import * as tr from 'azure-pipelines-task-lib/toolrunner'; +import * as path from 'path'; +import * as models from './models'; +import * as taskInputParser from './taskinputparser'; +import * as settingsHelper from './settingshelper'; +import * as utils from './helpers'; +import * as outStream from './outputstream'; +import * as ci from './cieventlogger'; +import * as testselectorinvoker from './testselectorinvoker'; +import { AreaCodes, ResultMessages } from './constants'; +import * as os from 'os'; +import * as uuid from 'uuid'; +import * as fs from 'fs'; +import * as xml2js from 'xml2js'; +import * as process from 'process'; + +const runSettingsExt = '.runsettings'; +const testSettingsExt = '.testsettings'; + +let vstestConfig: models.VsTestConfigurations = undefined; +let tiaConfig: models.TiaConfiguration = undefined; +const workingDirectory = utils.Constants.systemDefaultWorkingDirectory; +let testAssemblyFiles = undefined; +let resultsDirectory = null; + +export function startTest() { + try { + console.log(tl.loc('runTestsLocally', 'vstest.console.exe')); + console.log('========================================================'); + try { + vstestConfig = taskInputParser.getvsTestConfigurations(); + } catch (error) { + utils.Helper.publishEventToCi(AreaCodes.RUNTESTSLOCALLY, error.message, 1038, true); + throw (error); + } + console.log('========================================================'); + + tiaConfig = vstestConfig.tiaConfig; + + // Try to find the results directory for clean up. + // This may change later if runsettings has results directory and location go runsettings file changes. + resultsDirectory = getTestResultsDirectory(vstestConfig.settingsFile, path.join(workingDirectory, 'TestResults')); + tl.debug('TestRunResults Directory : ' + resultsDirectory); + + // clean up old testResults + tl.rmRF(resultsDirectory); + tl.mkdirP(resultsDirectory); + + testAssemblyFiles = getTestAssemblies(); + + if (!testAssemblyFiles || testAssemblyFiles.length === 0) { + uploadVstestDiagFile(); + console.log('##vso[task.logissue type=warning;code=002004;]'); + tl.warning(tl.loc('NoMatchingTestAssemblies', vstestConfig.sourceFilter)); + return; + } + + var consolidatedCiData = { + agentPhaseSettings: tl.getVariable('System.ParallelExecutionType'), + codeCoverageEnabled: vstestConfig.codeCoverageEnabled, + overrideTestrunParameters: utils.Helper.isNullOrUndefined(vstestConfig.overrideTestrunParameters) ? 'false' : 'true', + pipeline: tl.getVariable('release.releaseUri') != null ? 'release' : 'build', + runTestsInIsolation: vstestConfig.runTestsInIsolation, + task: 'VsTestConsoleFlow', + runInParallel: vstestConfig.runInParallel, + result: 'Failed', + settingsType: !utils.Helper.isNullOrUndefined(vstestConfig.settingsFile) ? vstestConfig.settingsFile.endsWith('.runsettings') ? 'runsettings' : vstestConfig.settingsFile.endsWith('.testsettings') ? 'testsettings' : 'none': 'none', + testSelection: vstestConfig.testSelection, + tiaEnabled: vstestConfig.tiaConfig.tiaEnabled, + vsTestVersion: vstestConfig.vsTestVersionDetails.majorVersion + '.' + vstestConfig.vsTestVersionDetails.minorversion + '.' + vstestConfig.vsTestVersionDetails.patchNumber, + consoleOptionsEnabled: + !utils.Helper.isNullOrWhitespace(vstestConfig.otherConsoleOptions) ? vstestConfig.otherConsoleOptions : '', + rerunEnabled: vstestConfig.rerunFailedTests, + rerunType: utils.Helper.isNullEmptyOrUndefined(vstestConfig.rerunType) ? '' : vstestConfig.rerunType + }; + + invokeVSTest().then(function (taskResult) { + uploadVstestDiagFile(); + if (vstestConfig.tiaConfig.tiaEnabled) { + uploadFile(path.join(os.tmpdir(), 'TestImpactZip.zip')); + uploadFile(path.join(os.tmpdir(), 'TestSelector.log')); + } + if (taskResult == tl.TaskResult.Failed) { + tl.setResult(tl.TaskResult.Failed, tl.loc('VstestFailedReturnCode'), true); + } + else { + consolidatedCiData.result = 'Succeeded'; + tl.setResult(tl.TaskResult.Succeeded, tl.loc('VstestPassedReturnCode'), true); + } + ci.publishEvent(consolidatedCiData); + + }).catch(function (err) { + uploadVstestDiagFile(); + utils.Helper.publishEventToCi(AreaCodes.INVOKEVSTEST, err.message, 1002, false); + console.log('##vso[task.logissue type=error;code=' + err + ';TaskName=VSTest]'); + tl.setResult(tl.TaskResult.Failed, err, true); + }); + } catch (error) { + uploadVstestDiagFile(); + utils.Helper.publishEventToCi(AreaCodes.RUNTESTSLOCALLY, error.message, 1003, false); + tl.setResult(tl.TaskResult.Failed, error, true); + } +} + +function getTestAssemblies(): string[] { + tl.debug('Searching for test assemblies in: ' + vstestConfig.testDropLocation); + return tl.findMatch(vstestConfig.testDropLocation, vstestConfig.sourceFilter); +} + +function getVstestArguments(settingsFile: string, addTestCaseFilter: boolean): string[] { + const argsArray: string[] = []; + testAssemblyFiles.forEach(function (testAssembly) { + let testAssemblyPath = testAssembly; + //To maintain parity with the behaviour when test assembly was filepath, try to expand it relative to build sources directory. + if (utils.Constants.systemDefaultWorkingDirectory && !utils.Helper.pathExistsAsFile(testAssembly)) { + const expandedPath = path.join(utils.Constants.systemDefaultWorkingDirectory, testAssembly); + if (utils.Helper.pathExistsAsFile(expandedPath)) { + testAssemblyPath = expandedPath; + } + } + argsArray.push(testAssemblyPath); + }); + if (vstestConfig.testcaseFilter && addTestCaseFilter) { + argsArray.push('/TestCaseFilter:' + vstestConfig.testcaseFilter); + } + + if (settingsFile) { + if (utils.Helper.pathExistsAsFile(settingsFile)) { + argsArray.push('/Settings:' + settingsFile); + utils.Helper.readFileContents(settingsFile, 'utf-8').then(function (settings) { + tl.debug('Running VsTest with settings : '); + utils.Helper.printMultiLineLog(settings, (logLine) => { console.log('##vso[task.debug]' + logLine); }); + }); + } else { + if (!tl.exist(settingsFile)) { + // because this is filepath input build puts default path in the input. To avoid that we are checking this. + utils.Helper.publishEventToCi(AreaCodes.INVALIDSETTINGSFILE, 'InvalidSettingsFile', 1004, true); + tl.setResult(tl.TaskResult.Failed, tl.loc('InvalidSettingsFile', settingsFile)); + throw Error((tl.loc('InvalidSettingsFile', settingsFile))); + } + } + } + + if (vstestConfig.codeCoverageEnabled) { + if (!utils.Helper.isToolsInstallerFlow(vstestConfig)) { + argsArray.push('/EnableCodeCoverage'); + } + } + + if (vstestConfig.runTestsInIsolation) { + argsArray.push('/InIsolation'); + } + + argsArray.push('/logger:trx'); + if (utils.Helper.isNullOrWhitespace(vstestConfig.pathtoCustomTestAdapters)) { + if (vstestConfig.testDropLocation && isTestAdapterPresent(vstestConfig.testDropLocation)) { + argsArray.push('/TestAdapterPath:\"' + vstestConfig.testDropLocation + '\"'); + } + } else { + argsArray.push('/TestAdapterPath:\"' + vstestConfig.pathtoCustomTestAdapters + '\"'); + } + + if (utils.Helper.isDebugEnabled()) { + if (vstestConfig.vsTestVersionDetails !== null && (vstestConfig.vsTestVersionDetails.vstestDiagSupported() + || utils.Helper.isToolsInstallerFlow(vstestConfig))) { + argsArray.push('/diag:' + vstestConfig.vstestDiagFile); + } else { + tl.warning(tl.loc('VstestDiagNotSupported')); + } + } + + return argsArray; +} + +function addVstestArgs(argsArray: string[], vstest: any) { + argsArray.forEach(function (arr: any) { + vstest.arg(arr); + }); +} + +function updateResponseFile(argsArray: string[], responseFile: string): boolean { + + if (!vstestConfig.responseFileSupported) { + return false; + } + + try { + argsArray.forEach(function (arr, i) { + argsArray[i] = utils.Helper.modifyVsTestConsoleArgsForResponseFile(arr); + }); + + let vsTestArgsString: string = os.EOL + argsArray.join(os.EOL); + if (!utils.Helper.isNullEmptyOrUndefined(vstestConfig.otherConsoleOptions)) { + vsTestArgsString = vsTestArgsString + os.EOL + vstestConfig.otherConsoleOptions; + } + + fs.appendFileSync(responseFile, vsTestArgsString); + } + catch (err) { + utils.Helper.publishEventToCi(AreaCodes.UPDATERESPONSEFILE, err.message, 1017, false); + tl.error(err); + tl.warning(tl.loc('ErrorWhileUpdatingResponseFile', responseFile)); + return false; + } + return true; +} + +function getTestSelectorLocation(): string { + return path.join(__dirname, 'TestSelector/TestSelector.exe'); +} + +async function executeVstest(parallelRunSettingsFile: string, vsVersion: number, argsArray: string[], addOtherConsoleOptions: boolean): Promise { + let vstest = tl.tool(vstestConfig.vsTestVersionDetails.vstestExeLocation); + + //Re-calculate the results directory based on final runsettings and clean up again if required. + resultsDirectory = getTestResultsDirectory(parallelRunSettingsFile, path.join(workingDirectory, 'TestResults')); + tl.rmRF(resultsDirectory); + tl.mkdirP(resultsDirectory); + + tl.cd(workingDirectory); + const ignoreTestFailures = vstestConfig.ignoreTestFailures && vstestConfig.ignoreTestFailures.toLowerCase() === 'true'; + + const envVars: { [key: string]: string; } = process.env; + if (vstestConfig.rerunFailedTests) { + vstest = tl.tool(path.join(__dirname, 'Modules/DTAExecutionHost.exe')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.VstestConsole', vstestConfig.vsTestVersionDetails.vstestExeLocation); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.TestResultDirectory', resultsDirectory); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.Configuration', vstestConfig.buildConfig); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.Platform', vstestConfig.buildPlatform); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.Runname', vstestConfig.testRunTitle); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.ExecutionMode', 'vstestexecution'); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.EnableConsoleLogs', 'true'); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.TeamFoundationCollectionUri', tl.getVariable('System.TeamFoundationCollectionUri')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.AccessToken', tl.getEndpointAuthorization('SystemVssConnection', true).parameters['AccessToken']); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.ProjectName', tl.getVariable('System.TeamProject')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.Owner', 'VsTest'); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.BuildId', tl.getVariable('Build.BuildId')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.BuildUri', tl.getVariable('Build.BuildUri')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.ReleaseUri', tl.getVariable('Release.ReleaseUri')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.ReleaseEnvironmentUri', tl.getVariable('Release.EnvironmentUri')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.ResponseFile', vstestConfig.responseFile); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.ResponseSupplementryFile', vstestConfig.responseSupplementryFile); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.VstestArgsFile', vstestConfig.vstestArgsFile); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.IsResponseFileRun', vstestConfig.isResponseFileRun.toString()); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.PublishTestResultsInTiaMode', vstestConfig.publishTestResultsInTiaMode.toString()); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.TestSelector', path.join(__dirname, 'TestSelector/TestSelector.exe')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.TiaContext', vstestConfig.tiaConfig.context); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.ReleaseId', tl.getVariable('Release.ReleaseId')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.TiaRunIdFile', vstestConfig.tiaConfig.runIdFile); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.AgentVersion', tl.getVariable('AGENT.VERSION')); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.VstestTaskInstanceIdentifier', vstestConfig.taskInstanceIdentifier); + utils.Helper.addToProcessEnvVars(envVars, 'DTA.RerunIterationCount', vstestConfig.rerunMaxAttempts.toString()); + if (vstestConfig.rerunType === 'basedOnTestFailureCount') { + utils.Helper.addToProcessEnvVars(envVars, 'DTA.RerunFailedTestCasesMaxLimit', vstestConfig.rerunFailedTestCasesMaxLimit.toString()); + } else { + utils.Helper.addToProcessEnvVars(envVars, 'DTA.RerunFailedThreshold', vstestConfig.rerunFailedThreshold.toString()); + } + } else { + addVstestArgs(argsArray, vstest); + // Adding the other console options here + // => Because it should be added as ".line" inorder to pass multiple parameters + // => Parsing will be taken care by .line + // https://github.com/Microsoft/vsts-task-lib/blob/master/node/docs/vsts-task-lib.md#toolrunnerToolRunnerline + if (addOtherConsoleOptions && !utils.Helper.isNullEmptyOrUndefined(vstestConfig.otherConsoleOptions)) { + vstest.line(vstestConfig.otherConsoleOptions); + } + } + + utils.Helper.addToProcessEnvVars(envVars, 'Test.TestCaseAccessToken', tl.getVariable('Test.TestCaseAccessToken')); + if (utils.Helper.isToolsInstallerFlow(vstestConfig)) { + utils.Helper.addToProcessEnvVars(envVars, 'COR_PROFILER_PATH_32', vstestConfig.toolsInstallerConfig.x86ProfilerProxyDLLLocation); + utils.Helper.addToProcessEnvVars(envVars, 'COR_PROFILER_PATH_64', vstestConfig.toolsInstallerConfig.x64ProfilerProxyDLLLocation); + } + + const execOptions: tr.IExecOptions = { + ignoreReturnCode: ignoreTestFailures, + env: envVars, + failOnStdErr: false, + // In effect this will not be called as failOnStdErr is false + // Keeping this code in case we want to change failOnStdErr + errStream: new outStream.StringErrorWritable({ decodeStrings: false }) + }; + + // The error codes return below are not the same as tl.TaskResult which follows a different convention. + // Here we are returning the code as returned to us by vstest.console in case of complete run + // In case of a failure 1 indicates error to our calling function + try { + var code = await vstest.exec(execOptions); + cleanUp(parallelRunSettingsFile); + if (ignoreTestFailures) { + return 0; // ignore failures. + } else { + return code; + } + } + catch (err) { + cleanUp(parallelRunSettingsFile); + tl.warning(tl.loc('VstestFailed')); + if (ignoreTestFailures) { + tl.warning(err); + return 0; + } else { + utils.Helper.publishEventToCi(AreaCodes.EXECUTEVSTEST, err.message, 1005, true); + tl.error(err); + return 1; + } + } +} + +function getVstestTestsListInternal(vsVersion: number, testCaseFilter: string, outputFile: string): string { + const tempFile = outputFile; + tl.debug('Discovered tests listed at: ' + tempFile); + const argsArray: string[] = []; + + try { + testAssemblyFiles.forEach(function (testAssembly) { + let testAssemblyPath = testAssembly; + if (utils.Constants.systemDefaultWorkingDirectory && !utils.Helper.pathExistsAsFile(testAssembly)) { + const expandedPath = path.join(utils.Constants.systemDefaultWorkingDirectory, testAssembly); + if (utils.Helper.pathExistsAsFile(expandedPath)) { + testAssemblyPath = expandedPath; + } + } + argsArray.push(testAssemblyPath); + }); + + tl.debug('The list of discovered tests is generated at ' + tempFile); + + argsArray.push('/ListFullyQualifiedTests'); + argsArray.push('/ListTestsTargetPath:' + tempFile); + if (testCaseFilter) { + argsArray.push('/TestCaseFilter:' + testCaseFilter); + } + if (vstestConfig.pathtoCustomTestAdapters) { + if (utils.Helper.pathExistsAsDirectory(vstestConfig.pathtoCustomTestAdapters)) { + argsArray.push('/TestAdapterPath:\"' + vstestConfig.pathtoCustomTestAdapters + '\"'); + } else { + argsArray.push('/TestAdapterPath:\"' + path.dirname(vstestConfig.pathtoCustomTestAdapters) + '\"'); + } + } else if (vstestConfig.testDropLocation && isTestAdapterPresent(vstestConfig.testDropLocation)) { + argsArray.push('/TestAdapterPath:\"' + vstestConfig.testDropLocation + '\"'); + } + + if (vstestConfig.pathtoCustomTestAdapters && vstestConfig.pathtoCustomTestAdapters.toLowerCase().indexOf('usevsixextensions:true') !== -1) { + argsArray.push('/UseVsixExtensions:true'); + } + + let vstest = tl.tool(vstestConfig.vsTestVersionDetails.vstestExeLocation); + + if (vsVersion === 14.0) { + tl.debug('Visual studio 2015 selected. Selecting vstest.console.exe in task '); + const vsTestPath = path.join(__dirname, 'TestSelector/14.0/vstest.console.exe') // Use private vstest as the changes to discover tests are not there in update3 + vstest = tl.tool(vsTestPath); + } + addVstestArgs(argsArray, vstest); + + // Adding the other console options here + // => Because it should be added as ".line" inorder to pass multiple parameters + // => Parsing will be taken care by .line + // https://github.com/Microsoft/vsts-task-lib/blob/master/node/docs/vsts-task-lib.md#toolrunnerToolRunnerline + if (!utils.Helper.isNullEmptyOrUndefined(vstestConfig.otherConsoleOptions)) { + vstest.line(vstestConfig.otherConsoleOptions); + } + + var vstestExecutionResult = vstest.execSync({ cwd: workingDirectory }); + + if (vstestExecutionResult.code != 0) { + tl.debug('Listing tests from VsTest failed.'); + tl.error(vstestExecutionResult.error ? vstestExecutionResult.error.message : vstestExecutionResult.stderr); + utils.Helper.publishEventToCi(AreaCodes.GETVSTESTTESTSLISTINTERNAL, vstestExecutionResult.error ? vstestExecutionResult.error.message : vstestExecutionResult.stderr, 1006, false); + return vstestExecutionResult.error ? vstestExecutionResult.error.message : vstestExecutionResult.stderr; + } + + console.log(vstestExecutionResult.stdout); + return tempFile; + } + catch (err) { + utils.Helper.publishEventToCi(AreaCodes.GETVSTESTTESTSLIST, err.message, 1027, false); + tl.error(err); + tl.warning(tl.loc('ErrorWhileListingDiscoveredTests')); + throw err; + } +} + +function getVstestTestsList(vsVersion: number): string { + const tempFile = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + tl.debug('Discovered tests listed at: ' + tempFile); + const argsArray: string[] = []; + + return getVstestTestsListInternal(vsVersion, vstestConfig.testcaseFilter, tempFile); +} + +function uploadVstestDiagFile(): void { + if (vstestConfig && vstestConfig.vstestDiagFile && utils.Helper.pathExistsAsFile(vstestConfig.vstestDiagFile)) { + uploadFile(vstestConfig.vstestDiagFile); + const files = tl.findMatch(utils.Helper.GetTempFolder(), ['*host.*.txt', '*datacollector.*.txt']); + if (files) { + files.forEach(file => { + uploadFile(file); + }); + } + } +} + +function uploadFile(file: string): void { + try { + if (utils.Helper.pathExistsAsFile(file)) { + const stats = fs.statSync(file); + tl.debug('File exists. Size: ' + stats.size + ' Bytes'); + console.log('##vso[task.uploadfile]' + file); + } + } catch (err) { + utils.Helper.publishEventToCi(AreaCodes.GETVSTESTTESTSLIST, err.message, 1029, false); + tl.debug(err); + } +} + +function discoverTestFromFilteredFilter(vsVersion: number, testCaseFilterFile: string, testCaseFilterOutput: string): string { + if (utils.Helper.pathExistsAsFile(testCaseFilterFile)) { + let filters = utils.Helper.readFileContentsSync(testCaseFilterFile, 'utf-8'); + return getVstestTestsListInternal(vsVersion, filters, testCaseFilterOutput); + } +} + +async function runVStest(settingsFile: string, vsVersion: number): Promise { + if (!isTiaAllowed()) { + // Test Impact was not enabled + return runVsTestAndUploadResultsNonTIAMode(settingsFile, vsVersion); + } + + let testCaseFilterFile = ''; + let testCaseFilterOutput = ''; + let listFile = ''; + if (tiaConfig.userMapFile) { + testCaseFilterFile = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + testCaseFilterOutput = utils.Helper.GenerateTempFile(uuid.v1() + '.txt'); + } + + let testselector = new testselectorinvoker.TestSelectorInvoker(); + let code = testselector.publishCodeChanges(tiaConfig, vstestConfig.proxyConfiguration, testCaseFilterFile, vstestConfig.taskInstanceIdentifier); + + if (code !== 0) { + // If publishing code changes fails, we run all tests. Here we are calling the non tia run because + // the run was not yet created by TIA and we dont want to update the results via test selector + tl.warning(tl.loc('ErrorWhilePublishingCodeChanges')); + return runVsTestAndUploadResultsNonTIAMode(settingsFile, vsVersion); + } + + // Code changes were published successfully. We will create the run and populate it with discovered test cases now -> + try { + // Discovering the test cases and writing them to a file. + listFile = getVstestTestsList(vsVersion); + discoverTestFromFilteredFilter(vsVersion, testCaseFilterFile, testCaseFilterOutput); + + try { + // This calls GetImpactedTests from test selector. Response file will contain the impacted tests in the format: /Tests:Method1,Method2 + testselector.generateResponseFile(tiaConfig, vstestConfig, listFile, testCaseFilterOutput); + } + catch (err) { + utils.Helper.publishEventToCi(AreaCodes.GENERATERESPONSEFILE, err.message, 1024, false); + tl.error(err); + tl.warning(tl.loc('ErrorWhileCreatingResponseFile')); + let updateResponseFileSuccess = updateResponseFile(getVstestArguments(settingsFile, true), vstestConfig.responseFile); + return updateResponseFileSuccess ? + runVsTestAndUploadResults(settingsFile, vsVersion, true, vstestConfig.responseFile, true) : + runVsTestAndUploadResults(settingsFile, vsVersion, false, '', true); + } + + if (isEmptyResponseFile(tiaConfig.responseFile)) { + // Empty response file indicates some issue. We run all tests here. + tl.debug('Empty response file detected. All tests will be executed.'); + let updateResponseFileSuccess = updateResponseFile(getVstestArguments(settingsFile, true), vstestConfig.responseFile); + return updateResponseFileSuccess ? + runVsTestAndUploadResults(settingsFile, vsVersion, true, vstestConfig.responseFile, true) : + runVsTestAndUploadResults(settingsFile, vsVersion, false, '', true); + } + else { + if (responseContainsNoTests(tiaConfig.responseFile)) { + // Case where response file indicated no tests were impacted. E.g.: "/Tests:" + tl.debug('No tests impacted. Not running any tests.'); + let updateTestResultsOutputCode = testselector.uploadTestResults(tiaConfig, vstestConfig, ''); + if (updateTestResultsOutputCode !== 0) { + utils.Helper.publishEventToCi(AreaCodes.UPLOADTESTRESULTS, ResultMessages.UPLOADTESTRESULTSRETURNED + updateTestResultsOutputCode, 1011, false); + return tl.TaskResult.Failed; + } + return tl.TaskResult.Succeeded; + } + else { + let updateResponseFileSuccess = updateResponseFile(getVstestArguments(settingsFile, false), tiaConfig.responseFile); + if (updateResponseFileSuccess && vstestConfig.testcaseFilter) tl.debug('Ignoring TestCaseFilter in response file because Test Impact is enabled'); + + return updateResponseFileSuccess ? + runVsTestAndUploadResults(settingsFile, vsVersion, true, tiaConfig.responseFile, true) : + runVsTestAndUploadResults(settingsFile, vsVersion, false, '', true); + } + } + } + catch (err) { + // The errors and logging tasks are handled in individual calls before. Just failing the task here + return tl.TaskResult.Failed; + } +} + +async function runVsTestAndUploadResults(settingsFile: string, vsVersion: number, isResponseFileRun: boolean, updatedResponseFile: string, uploadTiaResults: boolean): Promise { + var vstestArgs; + let testselector = new testselectorinvoker.TestSelectorInvoker(); + + if (isResponseFileRun) { + vstestArgs = ['@' + updatedResponseFile]; + vstestConfig.responseFile = updatedResponseFile; + vstestConfig.isResponseFileRun = true; + } + else { + vstestArgs = getVstestArguments(settingsFile, true); + } + + vstestConfig.publishTestResultsInTiaMode = uploadTiaResults; + let updateResponseSupplementryFileSuccess = isResponseFileRun && updateResponseFile(getVstestArguments(settingsFile, false), vstestConfig.responseSupplementryFile); + if (!updateResponseSupplementryFileSuccess && vstestConfig.rerunFailedTests) { + tl.warning(tl.loc('rerunNotSupported')); + vstestConfig.rerunFailedTests = false; + } + + try { + var vscode = await executeVstest(settingsFile, vsVersion, vstestArgs, !isResponseFileRun); + let updateTestResultsOutputCode: number; + if (uploadTiaResults && !vstestConfig.rerunFailedTests) { + updateTestResultsOutputCode = testselector.uploadTestResults(tiaConfig, vstestConfig, resultsDirectory); + } + if (vscode !== 0 || (uploadTiaResults && !vstestConfig.rerunFailedTests && updateTestResultsOutputCode !== 0)) { + utils.Helper.publishEventToCi(AreaCodes.EXECUTEVSTEST, ResultMessages.EXECUTEVSTESTRETURNED + vscode, 1010, false); + return tl.TaskResult.Failed; + } + return tl.TaskResult.Succeeded; + } + catch (err) { + utils.Helper.publishEventToCi(AreaCodes.EXECUTEVSTEST, err.message, 1010, false); + tl.error(err) + return tl.TaskResult.Failed; + } +} + +async function runVsTestAndUploadResultsNonTIAMode(settingsFile: string, vsVersion: number): Promise { + let updateResponseFileSuccess = updateResponseFile(getVstestArguments(settingsFile, true), vstestConfig.responseFile); + if (!updateResponseFileSuccess) { + return runVsTestAndUploadResults(settingsFile, vsVersion, false, '', false).then(function (runResult) { + if (!vstestConfig.rerunFailedTests) { + let publishResult = publishTestResults(resultsDirectory); + return (runResult === tl.TaskResult.Failed || publishResult === tl.TaskResult.Failed) ? + tl.TaskResult.Failed : + tl.TaskResult.Succeeded; + } + return runResult; + }); + } + + return runVsTestAndUploadResults(settingsFile, vsVersion, true, vstestConfig.responseFile, false) + .then(function (runResult) { + if (!vstestConfig.rerunFailedTests) { + let publishResult = publishTestResults(resultsDirectory); + return (runResult === tl.TaskResult.Failed || publishResult === tl.TaskResult.Failed) ? + tl.TaskResult.Failed : + tl.TaskResult.Succeeded; + } + return runResult; + }).catch(function (err) { + tl.error(err); + return tl.TaskResult.Failed; + }); +} + +async function invokeVSTest(): Promise { + try { + const disableTIA = tl.getVariable('DisableTestImpactAnalysis'); + if (disableTIA !== undefined && disableTIA.toLowerCase() === 'true') { + tl.debug('Disabling tia.'); + tiaConfig.tiaEnabled = false; + } + + if (tiaConfig.tiaEnabled && (vstestConfig.vsTestVersionDetails === null + || (!vstestConfig.vsTestVersionDetails.isTestImpactSupported() && !(utils.Helper.isToolsInstallerFlow(vstestConfig))))) { + tl.warning(tl.loc('VstestTIANotSupported')); + tiaConfig.tiaEnabled = false; + } + } catch (err) { + utils.Helper.publishEventToCi(AreaCodes.TIACONFIG, err.message, 1032, false); + tl.error(err.message); + throw err; + } + + // We need to use private data collector dll + if (vstestConfig.vsTestVersionDetails !== null) { + tiaConfig.useNewCollector = vstestConfig.vsTestVersionDetails.isPrivateDataCollectorNeededForTIA(); + } + + setRunInParallellIfApplicable(); + let newSettingsFile = vstestConfig.settingsFile; + const vsVersion = vstestConfig.vsTestVersionDetails.majorVersion; + + if (newSettingsFile) { + if (!utils.Helper.pathExistsAsFile(newSettingsFile)) { + if (!tl.exist(newSettingsFile)) { // because this is filepath input build puts default path in the input. To avoid that we are checking this. + utils.Helper.publishEventToCi(AreaCodes.TIACONFIG, 'InvalidSettingsFile', 1033, true); + throw Error((tl.loc('InvalidSettingsFile', newSettingsFile))); + } + } + } + + try { + newSettingsFile = await settingsHelper.updateSettingsFileAsRequired(vstestConfig.settingsFile, vstestConfig.runInParallel, vstestConfig.tiaConfig, + vstestConfig.vsTestVersionDetails, false, vstestConfig.overrideTestrunParameters, false, vstestConfig.codeCoverageEnabled && utils.Helper.isToolsInstallerFlow(vstestConfig)); + return vsTestCall(newSettingsFile, vsVersion); + } + catch (err) { + //Should continue to run without the selected configurations. + throw err; + } +} + +async function vsTestCall(newSettingsFile, vsVersion): Promise { + return runVStest(newSettingsFile, vsVersion).then(function (code) { + if (code !== 0) { + utils.Helper.publishEventToCi(AreaCodes.INVOKEVSTEST, 'RunVStest returned ' + code, 1036, false); + return tl.TaskResult.Failed; + } + return tl.TaskResult.Succeeded; + }).catch(function (err) { + utils.Helper.publishEventToCi(AreaCodes.INVOKEVSTEST, err.message, 1037, false); + tl.error(err); + return tl.TaskResult.Failed; + }); +} + +function publishTestResults(testResultsDirectory: string): tl.TaskResult { + try { + if (testResultsDirectory) { + const resultFiles = tl.findMatch(testResultsDirectory, path.join(testResultsDirectory, '*.trx')); + + if (resultFiles && resultFiles.length !== 0) { + const tp = new tl.TestPublisher('VSTest'); + tp.publish(resultFiles, 'false', vstestConfig.buildPlatform, vstestConfig.buildConfig, vstestConfig.testRunTitle, vstestConfig.publishRunAttachments); + } else { + console.log('##vso[task.logissue type=warning;code=002003;]'); + tl.warning(tl.loc('NoResultsToPublish')); + } + } else { + utils.Helper.publishEventToCi(AreaCodes.PUBLISHRESULTS, 'no test directory', 1041, false); + tl.warning(tl.loc('NoTestResultsDirectoryFound')); + } + + return tl.TaskResult.Succeeded; + } + catch (err) { + utils.Helper.publishEventToCi(AreaCodes.PUBLISHRESULTS, err.message, 1040, false); + tl.error(err); + return tl.TaskResult.Failed; + } +} + +function cleanUp(temporarySettingsFile: string): void { + //cleanup the runsettings file + if (temporarySettingsFile && vstestConfig.settingsFile !== temporarySettingsFile) { + try { + tl.rmRF(temporarySettingsFile); + } catch (error) { + //ignore. just cleanup. + } + } +} + +function isTestAdapterPresent(rootDirectory: string): boolean { + const adapterFiles = tl.findMatch(rootDirectory, '**\\*TestAdapter.dll'); + + if (adapterFiles && adapterFiles.length !== 0) { + return true; + } + return false; +} + +function getTestResultsDirectory(settingsFile: string, defaultResultsDirectory: string): string { + let resultDirectory = defaultResultsDirectory; + + if (!settingsFile || !utils.Helper.pathExistsAsFile(settingsFile)) { + return resultDirectory; + } + + try { + const xmlContents = utils.Helper.readFileContentsSync(settingsFile, 'utf-8'); + const parser = new xml2js.Parser(); + + parser.parseString(xmlContents, function (err, result) { + if (!err && result.RunSettings && result.RunSettings.RunConfiguration && result.RunSettings.RunConfiguration[0] && + result.RunSettings.RunConfiguration[0].ResultsDirectory && result.RunSettings.RunConfiguration[0].ResultsDirectory[0].length > 0) { + let runSettingsResultDirectory = result.RunSettings.RunConfiguration[0].ResultsDirectory[0]; + runSettingsResultDirectory = runSettingsResultDirectory.trim(); + + if (runSettingsResultDirectory) { + // path.resolve will take care if the result directory given in settings files is not absolute. + resultDirectory = path.resolve(path.dirname(settingsFile), runSettingsResultDirectory); + } + } + }); + } catch (error) { + //In case of error return default directory. + tl.debug(error); + return resultDirectory; + } + + return resultDirectory; +} + +function setRunInParallellIfApplicable() { + if (vstestConfig.runInParallel) { + if (vstestConfig.vsTestVersionDetails != null && vstestConfig.vsTestVersionDetails.isRunInParallelSupported()) { + return; + } + + // 2015 Update3 needed for run in parallel. + tl.warning(tl.loc('UpdateThreeOrHigherRequired')); + vstestConfig.runInParallel = false; + } +} + +function isEmptyResponseFile(responseFile: string): boolean { + if (utils.Helper.pathExistsAsFile(responseFile) && tl.stats(responseFile).size) { + return false; + } + return true; +} + +function isTiaAllowed(): boolean { + if (tiaConfig.tiaEnabled && getTestSelectorLocation()) { + return true; + } + return false; +} + +function responseContainsNoTests(filePath: string): boolean { + try { + let resp = utils.Helper.readFileContentsSync(filePath, 'utf-8'); + if (resp === '/Tests:"' || resp === '/Tests:' || resp === '/TestCaseFilter:') { + return true; + } else { + return false; + } + } + catch (err) { + utils.Helper.publishEventToCi(AreaCodes.RESPONSECONTAINSNOTESTS, err.message, 1023, false); + tl.error(err); + throw err; + } +} diff --git a/_generated/VsTestV2/vstestversion.ts b/_generated/VsTestV2/vstestversion.ts new file mode 100644 index 000000000000..088edb42597f --- /dev/null +++ b/_generated/VsTestV2/vstestversion.ts @@ -0,0 +1,69 @@ +export class VSTestVersion { + + constructor(public vstestExeLocation: string, public majorVersion: number, public minorversion: number, public patchNumber: number) { + } + + public isTestImpactSupported(): boolean { + return (this.majorVersion >= 15); + } + + public isResponseFileSupported(): boolean { + return (this.majorVersion >= 15); + } + + public vstestDiagSupported(): boolean { + return (this.majorVersion >= 15); + } + + public isPrivateDataCollectorNeededForTIA(): boolean { + return false; + } + + public isRunInParallelSupported(): boolean { + return (this.majorVersion >= 15); + } + + public isTestSettingsPropertiesSupported(): boolean { + return (this.majorVersion > 15) || (this.majorVersion === 15) && (this.patchNumber > 26906); + } +} + +export class Dev14VSTestVersion extends VSTestVersion { + constructor(runnerLocation: string, minorVersion: number, patchNumber: number) { + super(runnerLocation, 14, minorVersion, patchNumber); + } + + public isTestImpactSupported(): boolean { + return (this.patchNumber >= 25420); + } + + public isResponseFileSupported(): boolean { + return (this.patchNumber >= 25420); + } + + public isRunInParallelSupported(): boolean { + return (this.patchNumber >= 25420); + } + + public isPrivateDataCollectorNeededForTIA(): boolean { + return true; + } +} + +export class Dev15VSTestVersion extends VSTestVersion { + constructor(runnerLocation: string, minorVersion: number, patchNumber: number) { + super(runnerLocation, 15, minorVersion, patchNumber); + } + + public isTestImpactSupported(): boolean { + return (this.patchNumber >= 25727); + } + + public isResponseFileSupported(): boolean { + return (this.patchNumber >= 25420); + } + + public vstestDiagSupported(): boolean { + return (this.patchNumber > 25428); + } +} \ No newline at end of file diff --git a/_generated/VsTestV2_Node20/make.json b/_generated/VsTestV2_Node20/make.json index 3ec008712366..24fda5eb1455 100644 --- a/_generated/VsTestV2_Node20/make.json +++ b/_generated/VsTestV2_Node20/make.json @@ -6,7 +6,7 @@ "dest": "./" }, { - "url": "https://testexecution.blob.core.windows.net/testexecution/22799172/TestAgent.zip", + "url": "https://testexecution.blob.core.windows.net/testexecution/25847670/TestAgent.zip", "dest": "./Modules" }, { diff --git a/_generated/VsTestV2_Node20/task.json b/_generated/VsTestV2_Node20/task.json index 337c05504259..2617634345c9 100644 --- a/_generated/VsTestV2_Node20/task.json +++ b/_generated/VsTestV2_Node20/task.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 231, - "Patch": 0 + "Minor": 234, + "Patch": 1 }, "demands": [ "vstest" @@ -662,7 +662,7 @@ "minimumExpectedTests": "Minimum tests expected to be run: %d" }, "_buildConfigMapping": { - "Default": "2.229.0", - "Node20_229_4": "2.231.0" + "Default": "2.234.0", + "Node20_229_4": "2.234.1" } } \ No newline at end of file diff --git a/_generated/VsTestV2_Node20/task.loc.json b/_generated/VsTestV2_Node20/task.loc.json index 5dfb6f8f9660..fb3d5cc33eb0 100644 --- a/_generated/VsTestV2_Node20/task.loc.json +++ b/_generated/VsTestV2_Node20/task.loc.json @@ -17,8 +17,8 @@ "author": "Microsoft Corporation", "version": { "Major": 2, - "Minor": 231, - "Patch": 0 + "Minor": 234, + "Patch": 1 }, "demands": [ "vstest" @@ -662,7 +662,7 @@ "minimumExpectedTests": "ms-resource:loc.messages.minimumExpectedTests" }, "_buildConfigMapping": { - "Default": "2.229.0", - "Node20_229_4": "2.231.0" + "Default": "2.234.0", + "Node20_229_4": "2.234.1" } } \ No newline at end of file diff --git a/_generated/XamarinTestCloudV1.versionmap.txt b/_generated/XamarinTestCloudV1.versionmap.txt index 0104ff9a73fd..c2c95dff691b 100644 --- a/_generated/XamarinTestCloudV1.versionmap.txt +++ b/_generated/XamarinTestCloudV1.versionmap.txt @@ -1,2 +1,2 @@ -Default|1.234.2 -Node20-228|1.234.3 +Default|1.235.0 +Node20-228|1.235.1 diff --git a/_generated/XamarinTestCloudV1_Node20/Strings/resources.resjson/en-US/resources.resjson b/_generated/XamarinTestCloudV1_Node20/Strings/resources.resjson/en-US/resources.resjson index 560a389003c3..bae4406560f9 100644 --- a/_generated/XamarinTestCloudV1_Node20/Strings/resources.resjson/en-US/resources.resjson +++ b/_generated/XamarinTestCloudV1_Node20/Strings/resources.resjson/en-US/resources.resjson @@ -28,5 +28,6 @@ "loc.input.label.optionalArgs": "Optional arguments", "loc.input.help.optionalArgs": "Additional arguments passed to test-cloud.exe.", "loc.input.label.publishNUnitResults": "Publish results to Azure Pipelines", - "loc.input.help.publishNUnitResults": "When selected, --nunit-xml option will be passed to test-cloud.exe. Results from the NUnit xml file will be published to Azure Pipelines." + "loc.input.help.publishNUnitResults": "When selected, --nunit-xml option will be passed to test-cloud.exe. Results from the NUnit xml file will be published to Azure Pipelines.", + "loc.messages.DeprecatedTask": "The XamarinTestCloud@1 (Xamarin Test Cloud) task has been deprecated since January 11, 2018 and will soon be retired. Use the AppCenterDistribute@3 task instead." } \ No newline at end of file diff --git a/_generated/XamarinTestCloudV1_Node20/XamarinTestCloud.ps1 b/_generated/XamarinTestCloudV1_Node20/XamarinTestCloud.ps1 index 9e100e213e02..80e6b6170378 100644 --- a/_generated/XamarinTestCloudV1_Node20/XamarinTestCloud.ps1 +++ b/_generated/XamarinTestCloudV1_Node20/XamarinTestCloud.ps1 @@ -193,4 +193,11 @@ if($testCloudResults) Write-Host "##vso[task.addattachment type=Distributedtask.Core.Summary;name=Xamarin Test Cloud Results;]$mdReportFile" } +$featureFlags = @{ + failDeprecatedBuildTask = [System.Convert]::ToBoolean($env:FAIL_DEPRECATED_BUILD_TASK) +} +if ($featureFlags.failDeprecatedBuildTask) +{ + throw "The XamarinTestCloud@1 (Xamarin Test Cloud) task has been deprecated since January 11, 2018 and will soon be retired. Use the AppCenterDistribute@3 task instead." +} Write-Verbose "Leaving script XamarinTestCloud.ps1" \ No newline at end of file diff --git a/_generated/XamarinTestCloudV1_Node20/task.json b/_generated/XamarinTestCloudV1_Node20/task.json index 5ede6bc15ad9..ea148e4d26d2 100644 --- a/_generated/XamarinTestCloudV1_Node20/task.json +++ b/_generated/XamarinTestCloudV1_Node20/task.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, - "Patch": 3 + "Minor": 235, + "Patch": 1 }, "demands": [], "minimumAgentVersion": "1.83.0", @@ -201,8 +201,11 @@ "argumentFormat": "" } }, + "messages": { + "DeprecatedTask": "The XamarinTestCloud@1 (Xamarin Test Cloud) task has been deprecated since January 11, 2018 and will soon be retired. Use the AppCenterDistribute@3 task instead." + }, "_buildConfigMapping": { - "Default": "1.234.2", - "Node20-228": "1.234.3" + "Default": "1.235.0", + "Node20-228": "1.235.1" } } \ No newline at end of file diff --git a/_generated/XamarinTestCloudV1_Node20/task.loc.json b/_generated/XamarinTestCloudV1_Node20/task.loc.json index 343569b91e8c..45d4e1efd1d5 100644 --- a/_generated/XamarinTestCloudV1_Node20/task.loc.json +++ b/_generated/XamarinTestCloudV1_Node20/task.loc.json @@ -13,8 +13,8 @@ "author": "Microsoft Corporation", "version": { "Major": 1, - "Minor": 234, - "Patch": 3 + "Minor": 235, + "Patch": 1 }, "demands": [], "minimumAgentVersion": "1.83.0", @@ -201,8 +201,11 @@ "argumentFormat": "" } }, + "messages": { + "DeprecatedTask": "ms-resource:loc.messages.DeprecatedTask" + }, "_buildConfigMapping": { - "Default": "1.234.2", - "Node20-228": "1.234.3" + "Default": "1.235.0", + "Node20-228": "1.235.1" } } \ No newline at end of file diff --git a/_generated/XamarinTestCloudV1_Node20/xamarintestcloud.ts b/_generated/XamarinTestCloudV1_Node20/xamarintestcloud.ts index 1b0d73d3b87f..41c0d4f7af0d 100644 --- a/_generated/XamarinTestCloudV1_Node20/xamarintestcloud.ts +++ b/_generated/XamarinTestCloudV1_Node20/xamarintestcloud.ts @@ -268,3 +268,9 @@ var submitToTestCloud = function (index) { } submitToTestCloud(appFileIndex); + +let shouldFail = tl.getVariable('FAIL_DEPRECATED_BUILD_TASK'); + +if (shouldFail != null && shouldFail.toLowerCase() === 'true') { + throw new Error(tl.loc("DeprecatedTask")); +} \ No newline at end of file diff --git a/make-options.json b/make-options.json index 0ce1d5acc4c9..11ffe53c8765 100644 --- a/make-options.json +++ b/make-options.json @@ -45,6 +45,7 @@ "AzureRmWebAppDeploymentV4", "AzureSpringCloudV0", "AzureStaticWebAppV0", + "AzureTestPlanV0", "AzureWebAppV1", "AzureWebAppContainerV1", "AzureVmssDeploymentV0", @@ -221,6 +222,7 @@ "Node20": [ "AndroidSigningV2", "AndroidSigningV3", + "AzureTestPlanV0", "ANTV1", "ArchiveFilesV2", "BashV3", diff --git a/package.json b/package.json index da4dcc3b9f78..be57411cbc37 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "homepage": "https://github.com/Microsoft/azure-pipelines-tasks", "devDependencies": { "adm-zip": "0.4.13", - "azure-devops-node-api": "^10.2.2", + "azure-devops-node-api": "^12.2.0", "js-yaml": "^3.13.1", "minimatch": "3.0.2", "minimist": "^1.2.6",