diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/ConfigServiceGroup.json b/.pipelines/EV2Specs/ServiceGroupRoot/ConfigServiceGroup.json new file mode 100644 index 000000000..1dd94f219 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/ConfigServiceGroup.json @@ -0,0 +1,12 @@ +{ + "Settings": { + "tenantid": "00000000-0000-0000-0000-000000000000", + "environment": "Prod", + "subscription": { + "backFilledSubscriptionId": "00000000-0000-0000-0000-000000000000", + "backFilledSubscriptionName": "default", + "subscriptionkey": "SubKey-Prod-PSResourceGetMAR" + }, + "azureResourceGroup": "default" + } +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/PSResourceGetReleaseMAR.Rollout.json b/.pipelines/EV2Specs/ServiceGroupRoot/PSResourceGetReleaseMAR.Rollout.json new file mode 100644 index 000000000..7803ec37f --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/PSResourceGetReleaseMAR.Rollout.json @@ -0,0 +1,60 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/rolloutParameters.json", + "contentVersion": "1.0.0.0", + "shellExtensions": [ + { + "name": "Run", + "type": "Run", + "properties": { + "maxExecutionTime": "PT2H" + }, + "package": { + "reference": { + "path": "Shell/Run.tar" + } + }, + "launch": { + "command": [ + "/bin/bash", + "-c", + "pwsh ./Run/Run.ps1" + ], + "environmentVariables": [ + { + "name": "NUPKG_PATH", + "reference": + { + "path": "default" + } + }, + { + "name": "PSRESOURCE_NAME", + "value": "default" + }, + { + "name": "PSRESOURCE_VERSION", + "value": "default" + }, + { + "name": "DESTINATION_ACR_NAME", + "value": "default" + }, + { + "name": "DESTINATION_ACR_URI", + "value": "default" + }, + { + "name": "MI_CLIENTID", + "value": "default" + } + ], + "identity": { + "type": "userAssigned", + "userAssignedIdentities": [ + "default" + ] + } + } + } + ] +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/Parameters/subscriptionProvisioning.RolloutParameters.json b/.pipelines/EV2Specs/ServiceGroupRoot/Parameters/subscriptionProvisioning.RolloutParameters.json new file mode 100644 index 000000000..cbc3c9670 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/Parameters/subscriptionProvisioning.RolloutParameters.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/rolloutParameters.json", + "contentVersion": "1.0.0.0", + "subscriptions": [ + { + "name": "SubscriptionProvisioning", + "displayName": "__BACKFILLED_SUBSCRIPTION_NAME__", + "backfilledSubscriptionId": "__BACKFILLED_SUBSCRIPTION_ID__" + } + ] +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/RolloutSpec.json b/.pipelines/EV2Specs/ServiceGroupRoot/RolloutSpec.json new file mode 100644 index 000000000..b34c95809 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/RolloutSpec.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-04-01/RegionAgnosticRolloutSpecification.json", + "contentVersion": "1.0.0.0", + "rolloutMetadata": { + "serviceModelPath": "ServiceModel.json", + "ScopeBindingsPath": "ScopeBindings.json", + "name": "Microsoft.Azure.PSCore.PSResourceGet", + "rolloutType": "Major", + "buildSource": { + "parameters": { + "versionFile": "buildver.txt" + } + }, + "configuration": { + "serviceGroupScope": { + "specPath": "ConfigServiceGroup.json" + } + }, + "Notification": { + "Email": { + "To": "default" + } + } + }, + "orchestratedSteps": [ + { + "name": "PSResourceGetMARRelease", + "targetType": "ServiceResourceDefinition", + "targetName": "PSResourceGetMARReleaseShell", + "actions": ["Shell/Run"] + } + ] +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/ScopeBindings.json b/.pipelines/EV2Specs/ServiceGroupRoot/ScopeBindings.json new file mode 100644 index 000000000..8975abafa --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/ScopeBindings.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/scopeBindings.json", + "contentVersion": "0.0.0.1", + "scopeBindings": [ + { + "scopeTagName": "Global", + "bindings": [ + { + "find": "__SUBSCRIPTION_ID__", + "replaceWith": "$azureSubscriptionId()" + }, + { + "find": "__RESOURCE_GROUP__", + "replaceWith": "$azureResourceGroup()" + }, + { + "find": "__BUILD_VERSION__", + "replaceWith": "$buildVersion()" + } + ] + }, + { + "scopeTagName": "scope.tag.subscriptionprovisioning", + "bindings": [ + { + "find": "__BACKFILLED_SUBSCRIPTION_NAME__", + "replaceWith": "$config(subscription.backFilledSubscriptionName)" + }, + { + "find": "__BACKFILLED_SUBSCRIPTION_ID__", + "replaceWith": "$config(subscription.backFilledSubscriptionId)" + } + ] + } + ] +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/ServiceGroupSpecification.json b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceGroupSpecification.json new file mode 100644 index 000000000..46d5da360 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceGroupSpecification.json @@ -0,0 +1,7 @@ +{ + "name": "Microsoft.Azure.PSCore.PSResourceGet", + "description": "PSResourceGet Publish to MAR", + "ownerGroupObjectId": "00000000-0000-0000-0000-000000000000", + "ownerGroupContactEmail": "default", + "contentVersion": "1.0.0.0" +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json new file mode 100644 index 000000000..c517dcb87 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceModel.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-04-01/regionAgnosticServiceModel.json", + "contentVersion": "1.0.0.0", + "serviceMetadata": { + "serviceIdentifier": "00000000-0000-0000-0000-000000000000", + "serviceGroup": "Microsoft.Azure.PSCore.PSResourceGet", + "serviceSpecificationPath": "ServiceSpecification.json", + "serviceGroupSpecificationPath": "ServiceGroupSpecification.json", + "environment": "$config(environment)", + "displayName":"PSResourceGet-Ev2Release-MAR", + "tenantId":"$config(tenantid)" + }, + "subscriptionProvisioning": { + "rolloutParametersPath": "Parameters\\subscriptionProvisioning.rolloutParameters.json", + "scopeTags": [ + { + "name": "scope.tag.subscriptionprovisioning" + } + ] + }, + "serviceResourceGroupDefinitions": [ + { + "name": "OneBranch-PSResourceGet-RGDef", + "azureResourceGroupName": "$config(azureResourceGroup)", + "subscriptionKey": "$config(subscription.subscriptionkey)", + "serviceResourceDefinitions": [ + { + "name": "PSResourceGetMARReleaseShell", + "composedOf": { + "extension": { + "rolloutParametersPath": "PSResourceGetReleaseMAR.Rollout.json", + "shell": [ + { + "type": "Run", + "properties": { + "imageName": "adm-azurelinux-30-l", + "imageVersion": "v2" + } + } + ] + } + }, + "scopeTags": [ + { + "name": "Global" + } + ] + } + ] + } + ] +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/ServiceSpecification.json b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceSpecification.json new file mode 100644 index 000000000..93243e69a --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/ServiceSpecification.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://ev2schema.azure.net/schemas/2020-01-01/serviceSpecification.json", + "providerType": "ServiceTree", + "identifier": "00000000-0000-0000-0000-000000000000", + "description": "PowerShell Core service for deployments.", + "ownerGroupContactEmail": "default", + "policyCheckEnabled": true, + "contentVersion": "1.0.0.0" +} diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 b/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 new file mode 100644 index 000000000..7425864c6 --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 @@ -0,0 +1,85 @@ +# ensure variables were passed in +if ($env:NUPKG_PATH -eq $null) +{ + Write-Verbose -Verbose "NUPKG_PATH variable didn't get set properly" + return 1 +} + +if ($env:PSRESOURCE_NAME -eq $null) +{ + Write-Verbose -Verbose "PSRESOURCE_NAME variable didn't get set properly" + return 1 +} + +if ($env:PSRESOURCE_VERSION -eq $null) +{ + Write-Verbose -Verbose "PSRESOURCE_VERSION variable didn't get set properly" + return 1 +} + +if ($env:DESTINATION_ACR_NAME -eq $null) +{ + Write-Verbose -Verbose "DESTINATION_ACR_NAME variable didn't get passed correctly" + return 1 +} + +if ($env:DESTINATION_ACR_URI -eq $null) +{ + Write-Verbose -Verbose "DESTINATION_ACR_URI variable didn't get passed correctly" + return 1 +} + +if ($env:MI_CLIENTID -eq $null) +{ + Write-Verbose -Verbose "MI_CLIENTID variable didn't get passed correctly" + return 1 +} + +try { + Write-Verbose -Verbose ".nupkg file path: $env:NUPKG_PATH" + Write-Verbose -Verbose "psresource name: $env:PSRESOURCE_NAME" + Write-Verbose -Verbose "psresource version: $env:PSRESOURCE_VERSION" + Write-Verbose -Verbose "ACR name: $env:DESTINATION_ACR_NAME" + Write-Verbose -Verbose "ACR uri: $env:DESTINATION_ACR_URI" + Write-Verbose -Verbose "MI client Id: $env:MI_CLIENTID" + + $nupkgFileName = "$($env:PSRESOURCE_NAME).$($env:PSRESOURCE_VERSION).nupkg" + Write-Verbose -Verbose "Download file" + Invoke-WebRequest -Uri $env:NUPKG_PATH -OutFile $nupkgFileName + + # Install PSResourceGet 1.1.0 + Write-Verbose "Download PSResourceGet version 1.1.0" + Register-PSRepository -Name CFS -SourceLocation "https://pkgs.dev.azure.com/powershell/PowerShell/_packaging/powershell/nuget/v2" -InstallationPolicy Trusted + Install-Module -Repository CFS -Name Microsoft.PowerShell.PSResourceGet -RequiredVersion '1.1.0' -AllowPrerelease -Verbose + Import-Module Microsoft.PowerShell.PSResourceGet + Get-Module + + # Login to Azure CLI using Managed Identity + Write-Verbose -Verbose "Login cli using managed identity" + az login --identity --client-id $env:MI_CLIENTID + + # Register the target ACR as a PSResourceGet repository + Write-Verbose -Verbose "Register ACR as a PSResourceGet reposirory" + Register-PSResourceRepository -Uri $env:DESTINATION_ACR_URI -Name $env:DESTINATION_ACR_NAME -Trusted -Verbose + + Get-PSResourceRepository + + # Publish module to ACR + Write-Verbose -Verbose "Publish $env:PSRESOURCE_NAME from file $nupkgFileName to ACR $env:DESTINATION_ACR_NAME" + + # unlisted + $prefix = "unlisted/psresource" + Publish-PSResource -NupkgPath $nupkgFileName -Repository $env:DESTINATION_ACR_NAME -ModulePrefix $prefix -Confirm:$false + + # public + $prefix = "public/psresource" + + Publish-PSResource -NupkgPath $nupkgFileName -Repository $env:DESTINATION_ACR_NAME -ModulePrefix $prefix -Confirm:$false +} +catch { + $_.Exception | Format-List -Force + + return 1 +} + +return 0 diff --git a/.pipelines/EV2Specs/ServiceGroupRoot/buildVer.txt b/.pipelines/EV2Specs/ServiceGroupRoot/buildVer.txt new file mode 100644 index 000000000..b1435cb4a --- /dev/null +++ b/.pipelines/EV2Specs/ServiceGroupRoot/buildVer.txt @@ -0,0 +1 @@ +1.2.0.101 \ No newline at end of file diff --git a/.pipelines/PSResourceGet-Release-Official-Azure.yml b/.pipelines/PSResourceGet-Release-Official-Azure.yml new file mode 100644 index 000000000..9f0d707f7 --- /dev/null +++ b/.pipelines/PSResourceGet-Release-Official-Azure.yml @@ -0,0 +1,80 @@ +################################################################################# +# OneBranch Pipelines # +# Documentation: https://aka.ms/onebranchrelease # +# Yaml Schema: https://aka.ms/obpipelines/yaml/schema # +# Support: https://aka.ms/onebranchsupport # +################################################################################# +name: PSResourceGet-Release-Official-$(Build.BuildId) +trigger: none # https://aka.ms/obpipelines/triggers +pr: + branches: + include: + - master + - release* + +parameters: # parameters are shown up in ADO UI in a build queue time + - name: 'debug' + displayName: 'Enable debug output' + type: boolean + default: false + - name: 'rolloutType' + displayName: 'SDP rollout type' + type: string + default: 'normal' + values: + - normal + - emergency + - globaloutage + - name: 'overrideManagedValidationDuration' + displayName: 'Override standard SDP duration?' + type: boolean + default: false + - name: 'managedValidationDurationInHours' + displayName: 'Override standard SDP duration (in hours)' + type: number + default: 0 + - name: 'icmIncidentId' + displayName: 'IcM Incident Id' + type: number + default: 0 + +variables: + - name: DOTNET_CLI_TELEMETRY_OPTOUT + value: 1 + - name: POWERSHELL_TELEMETRY_OPTOUT + value: 1 + - name: ob_sdl_tsa_configFile + value: $(Build.SourcesDirectory)\.config\tsaoptions.json + - name: WindowsContainerImage + value: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest # Docker image which is used to build the project https://aka.ms/obpipelines/containers + - name: LinuxContainerImage + value: mcr.microsoft.com/onebranch/azurelinux/build:3.0 + +resources: + repositories: + - repository: templates + type: git + name: OneBranch.Pipelines/GovernedTemplates + ref: refs/heads/main + # https://learn.microsoft.com/en-us/azure/devops/pipelines/process/resources?view=azure-devops&tabs=example#define-a-pipelines-resource + + pipelines: + - pipeline: PSResourceGetBuild + source: PSResourceGet-Official + +extends: + template: v2/OneBranch.Official.CrossPlat.yml@templates # The Official template may only be used by Production-classified pipelines + parameters: + featureFlags: + linuxEsrpSigning: true + globalSdl: + tsaOptionsFile: .config\tsaoptions.json + ev2ManagedSdpRolloutConfig: + rolloutType: ${{parameters.rolloutType}} + overrideManagedValidationDuration: ${{parameters.overrideManagedValidationDuration}} + managedValidationOverrideDurationInHours: ${{parameters.managedValidationDurationInHours}} + icmIncidentId: ${{parameters.icmIncidentId}} + + stages: + - template: /.pipelines/templates/release-publish-mar.yml@self + diff --git a/.pipelines/templates/release-publish-mar.yml b/.pipelines/templates/release-publish-mar.yml new file mode 100644 index 000000000..ea6c31f02 --- /dev/null +++ b/.pipelines/templates/release-publish-mar.yml @@ -0,0 +1,249 @@ +stages: +- stage: PrepForEV2 + displayName: 'Copy and prep all files needed for EV2 stage' + jobs: + - job: CopyEV2FilesToArtifact + displayName: 'Copy EV2 Files to Artifact' + pool: + type: linux + variables: + - name: ob_outputDirectory + value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT' + - name: repoRoot + value: '$(Build.SourcesDirectory)/PSResourceGet' + - name: ev2ServiceGroupRootFolder + value: '$(Build.SourcesDirectory)/PSResourceGet/.pipelines/EV2Specs/ServiceGroupRoot' + - name: ev2SourceFilesFolder + value: '$(Build.SourcesDirectory)/PSResourceGet/.pipelines/EV2Specs/ServiceGroupRoot/SourceFiles' + - group: 'SecretManagementAcr' + # - name: ob_sdl_credscan_suppressionsFile + # value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json + steps: + - checkout: self ## the global setting on lfs didn't work + lfs: false + env: + ob_restore_phase: true + + - download: PSResourceGetBuild + artifact: 'drop_stagebuild_nupkg' + displayName: 'Download artifact containing .nupkg file from PSResourceGetBuild pipeline' + env: + ob_restore_phase: true + + - pwsh: | + New-Item -Path '$(ev2SourceFilesFolder)' -ItemType Directory + $sourceFilesFolderExists = Test-Path -Path '$(ev2SourceFilesFolder)' + Write-Verbose -Verbose "Ev2 parameters folder exists: $sourceFilesFolderExists" + displayName: 'Create SourceFiles folder under EV2Specs/ServiceGroupRoot folder' + env: + ob_restore_phase: true + + - task: CopyFiles@2 + inputs: + SourceFolder: '$(Pipeline.Workspace)/PSResourceGetBuild/drop_stagebuild_nupkg/PSResourceGet/signed/PublishedNupkg' + Contents: '*.nupkg' + TargetFolder: $(ev2SourceFilesFolder) + env: + ob_restore_phase: true + + - pwsh: | + $nupkgFile = Get-ChildItem -Path '$(ev2SourceFilesFolder)' -Filter "*.nupkg" -Recurse | Select-Object -First 1 + $nupkgFileName = $nupkgFile.Name + $nupkgFilePath = $nupkgFile.FullName + + Write-Verbose -Verbose ".nupkg file $nupkgFileName found at $nupkgFilePath" + + $moduleName = "Microsoft.PowerShell.PSResourceGet" + $trimmedFileName = $nupkgFileName.Trim(".nupkg") + $moduleVersion = $trimmedFileName.Split("$moduleName.", [System.StringSplitOptions]::RemoveEmptyEntries) + + Write-Host "##vso[task.setvariable variable=moduleName;isOutput=true]$moduleName" + Write-Host "##vso[task.setvariable variable=moduleVersion;isOutput=true]$moduleVersion" + + Write-Verbose -Verbose "Module to publish info: name '$moduleName' Version '$moduleVersion'" + displayName: 'Ensure PSResource .nupkg file is present and extract module name and version' + name: setModuleInfoStep + env: + ob_restore_phase: true + + - pwsh: | + Get-ChildItem Env: | Out-String -Stream | write-Verbose -Verbose + displayName: 'Capture Environment Variables' + env: + ob_restore_phase: true + + - pwsh: | + Get-ChildItem '$(Build.SourcesDirectory)' -Recurse | Out-String -Stream | write-Verbose -Verbose + displayName: 'Capture BuildDirectory' + env: + ob_restore_phase: true + + - pwsh: | + Get-ChildItem '$(Pipeline.Workspace)' -Recurse | Out-String -Stream | write-Verbose -Verbose + displayName: 'Capture Workspace' + env: + ob_restore_phase: true + + - pwsh: | + $pathToJsonFile = Join-Path -Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'RolloutSpec.json' + $content = Get-Content -Path $pathToJsonFile | ConvertFrom-Json + $content.RolloutMetadata.Notification.Email.To = '$(email_address)' + Remove-Item -Path $pathToJsonFile + $content | ConvertTo-Json -Depth 4 | Out-File $pathToJsonFile + displayName: 'Replace values in RolloutSpecPath.json' + env: + ob_restore_phase: true + + - pwsh: | + $moduleResourceName = '$(setModuleInfoStep.moduleName)' + $moduleResourceVersion = '$(setModuleInfoStep.moduleVersion)' + $pathToJsonFile = Join-Path -Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'PSResourceGetReleaseMAR.Rollout.json' + $content = Get-Content -Path $pathToJsonFile | ConvertFrom-Json + + $envVarArrayLen = $content.shellExtensions.launch.environmentVariables.Length + + for ($i=0; $i -lt $envVarArrayLen; $i++) + { + $name = $($content.shellExtensions.launch.environmentVariables[$i].name) + if ($name -eq "NUPKG_PATH") + { + $content.shellExtensions.launch.environmentVariables[$i].reference.path = "SourceFiles/$moduleResourceName.$moduleResourceVersion.nupkg" + Write-Verbose -Verbose "Nupkg Path: $($content.shellExtensions.launch.environmentVariables[$i].reference.path)" + } + elseif ($name -eq "PSRESOURCE_NAME") + { + $content.shellExtensions.launch.environmentVariables[$i].value = $moduleResourceName + Write-Verbose -Verbose "PSResource Name: $($content.shellExtensions.launch.environmentVariables[$i].value)" + } + elseif ($name -eq "PSRESOURCE_VERSION") + { + $content.shellExtensions.launch.environmentVariables[$i].value = $moduleResourceVersion + Write-Verbose -Verbose "PSResource Version: $($content.shellExtensions.launch.environmentVariables[$i].value)" + } + elseif ($name -eq "DESTINATION_ACR_NAME") + { + $content.shellExtensions.launch.environmentVariables[$i].value = '$(acr_name)' + Write-Verbose -Verbose "ACR Name: $($content.shellExtensions.launch.environmentVariables[$i].value)" + } + elseif ($name -eq "DESTINATION_ACR_URI") + { + $content.shellExtensions.launch.environmentVariables[$i].value = '$(acr_uri)' + Write-Verbose -Verbose "ACR URI: $($content.shellExtensions.launch.environmentVariables[$i].value)" + } + elseif ($name -eq "MI_CLIENTID") + { + $content.shellExtensions.launch.environmentVariables[$i].value = '$(managed_identity_clientid)' + Write-Verbose -Verbose "MI Client ID: $($content.shellExtensions.launch.environmentVariables[$i].value)" + } + } + + $identityString = "/subscriptions/$(acr_subscription)/resourcegroups/$(acr_resource_group)/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$(managed_identity_name)" + $content.shellExtensions.launch.identity.userAssignedIdentities[0] = $identityString + + Remove-Item -Path $pathToJsonFile + $content | ConvertTo-Json -Depth 6 | Out-File $pathToJsonFile + displayName: 'Replace values in PSResourceGetReleaseMAR.Rollout.json file' + env: + ob_restore_phase: true + + - pwsh: | + $pathToJsonFile = Join-Path -Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'ServiceModel.json' + $content = Get-Content -Path $pathToJsonFile | ConvertFrom-Json + $content.serviceMetadata.serviceIdentifier = '$(service_identifier)' + + Remove-Item -Path $pathToJsonFile + $content | ConvertTo-Json -Depth 9 | Out-File $pathToJsonFile + displayName: 'Replace values in ServiceModel.json' + env: + ob_restore_phase: true + + - pwsh: | + $pathToJsonFile = Join-Path -Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'ServiceGroupSpecification.json' + $content = Get-Content -Path $pathToJsonFile | ConvertFrom-Json + $content.ownerGroupObjectId = '$(owner_group_id)' + $content.ownerGroupContactEmail = '$(owner_group_contact_email)' + + Remove-Item -Path $pathToJsonFile + $content | ConvertTo-Json -Depth 1 | Out-File $pathToJsonFile + displayName: 'Replace values in ServiceGroupSpecification.json' + env: + ob_restore_phase: true + + - pwsh: | + $pathToJsonFile = Join-Path -Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'ServiceSpecification.json' + $content = Get-Content -Path $pathToJsonFile | ConvertFrom-Json + $content.identifier = '$(service_identifier)' + $content.ownerGroupContactEmail = '$(owner_group_contact_email)' + + Remove-Item -Path $pathToJsonFile + $content | ConvertTo-Json -Depth 1 | Out-File $pathToJsonFile + displayName: 'Replace values in ServiceSpecification.json' + env: + ob_restore_phase: true + + - pwsh: | + $pathToJsonFile = Join-Path -Path '$(ev2ServiceGroupRootFolder)' -ChildPath 'ConfigServiceGroup.json' + $content = Get-Content -Path $pathToJsonFile | ConvertFrom-Json + $content.Settings.tenantid = '$(tenant_id)' + $content.Settings.subscription.backFilledSubscriptionId = '$(acr_subscription)' + $content.Settings.subscription.backFilledSubscriptionName = '$(acr_subscription_name)' + $content.Settings.azureResourceGroup = '$(acr_resource_group)' + + Remove-Item -Path $pathToJsonFile + $content | ConvertTo-Json -Depth 2 | Out-File $pathToJsonFile + displayName: 'Replace values in ConfigServiceGroup.json' + env: + ob_restore_phase: true + + - task: onebranch.pipeline.signing@1 + inputs: + command: 'sign' + signing_profile: internal_azure_service + files_to_sign: '*.ps1' + search_root: '$(repoRoot)/.pipelines/EV2Specs/ServiceGroupRoot/Shell/Run' + displayName: Sign Run.ps1 + + - pwsh: | + # folder to tar (ie /Run) must have: Run.ps1 and any other folders/files you want extracted + $srcPath = Join-Path '$(repoRoot)/.pipelines/EV2Specs/ServiceGroupRoot' -ChildPath 'Shell' + $pathToRunTarFile = Join-Path '$(repoRoot)/.pipelines/EV2Specs/ServiceGroupRoot/Shell' -ChildPath "Run.tar" + tar -cvf $pathToRunTarFile -C $srcPath ./Run + displayName: 'Create archive for the shell extension' + + - task: CopyFiles@2 + inputs: + SourceFolder: '$(repoRoot)/.pipelines' + Contents: 'EV2Specs/**' + TargetFolder: $(ob_outputDirectory) + +- stage: 'Prod_Managed_SDP' + displayName: 'Prod Managed SDP release of package to MAR with EV2' + dependsOn: + - PrepForEV2 + variables: + - name: ob_release_environment + value: "Production" + - name: repoRoot + value: $(Build.SourcesDirectory) + jobs: + - job: Prod_ReleaseJob + templateContext: + inputs: + - input: pipelineArtifact + artifactName: drop_PrepForEV2_CopyEv2FilesToArtifact + displayName: Publish to MAR + pool: + type: release + + steps: + - task: vsrm-ev2.ev2-rollout.ev2-rollout-task.Ev2RARollout@2 + inputs: + EndpointProviderType: ApprovalService + ApprovalServiceEnvironment: Production + TaskAction: RegisterAndRollout + SkipRegistrationIfExists: true + ServiceRootPath: '$(Pipeline.Workspace)/EV2Specs/ServiceGroupRoot' + RolloutSpecPath: '$(Pipeline.Workspace)/EV2Specs/ServiceGroupRoot/RolloutSpec.json' + StageMapName: 'Microsoft.Azure.SDP.Standard' + Select: 'regions(EastUS)' + displayName: 'Ev2 Managed SDP Rollout'