# Ideally we would use GitHub Actions for this, but since we use self-hosted machines to run image builds # we need the following features to use GitHub Actions for Images CI: # - https://github.community/t5/GitHub-Actions/Make-secrets-available-to-builds-of-forks/m-p/30678#M508 # - https://github.community/t5/GitHub-Actions/GitHub-Actions-Manual-Trigger-Approvals/td-p/31504 # - https://github.community/t5/GitHub-Actions/Protecting-github-workflows/td-p/30290 parameters: - name: job_id type: string default: 'generate_image' - name: image_type type: string - name: image_template_name type: string - name: image_readme_name type: string - name: agent_pool type: object default: name: 'ci-agent-pool' - name: variable_group_name type: string default: 'Image Generation Variables' - name: create_release type: boolean default: true - name: repository_ref type: string default: 'self' jobs: - job: ${{ parameters.job_id }} displayName: Image Generation (${{ parameters.image_type }}) timeoutInMinutes: 600 cancelTimeoutInMinutes: 30 pool: ${{ parameters.agent_pool }} variables: - group: ${{ parameters.variable_group_name }} steps: - checkout: ${{ parameters.repository_ref }} clean: true fetchDepth: 0 fetchTags: false - task: PowerShell@2 displayName: 'Download custom repository' condition: and(ne(variables['CUSTOM_REPOSITORY_URL'], ''), ne(variables['CUSTOM_REPOSITORY_BRANCH'], '')) inputs: targetType: 'filePath' filePath: ./images.CI/download-repo.ps1 arguments: -RepoUrl $(CUSTOM_REPOSITORY_URL) ` -RepoBranch $(CUSTOM_REPOSITORY_BRANCH) - task: AzureCLI@2 displayName: 'Set variables' inputs: azureSubscription: 'spn-hosted-runners' scriptType: 'pscore' scriptLocation: 'inlineScript' inlineScript: | $ImageType = "${{ parameters.image_type }}" $TemplateDirectoryName = if ($ImageType.StartsWith("ubuntu")) { "ubuntu/templates" } else { "windows/templates" } $TemplateDirectoryPath = Join-Path "images" $TemplateDirectoryName | Resolve-Path $TemplateFileName = "${{ parameters.image_template_name }}" $TemplatePath = Join-Path $TemplateDirectoryPath $TemplateFileName Write-Host "##vso[task.setvariable variable=TemplateDirectoryPath;]$TemplateDirectoryPath" Write-Host "##vso[task.setvariable variable=TemplatePath;]$TemplatePath" $ManagedImageName = "${{ parameters.image_type }}-$(Build.BuildId)" Write-Host "##vso[task.setvariable variable=ManagedImageName;]$ManagedImageName" $TempResourceGroupName = "packer-temp-$ManagedImageName" Write-Host "##vso[task.setvariable variable=TempResourceGroupName;]$TempResourceGroupName" $clientSecret = $(az keyvault secret show --name "spnhostedrunners" --vault-name "gh-imagegeneration" --query value -o tsv) Write-Host "##vso[task.setvariable variable=ClientSecret;issecret=true]$clientSecret" - task: PowerShell@2 displayName: 'Build VM' inputs: targetType: filePath filePath: ./images.CI/linux-and-win/build-image.ps1 arguments: -ClientId $(CLIENT_ID) ` -ClientSecret "$(ClientSecret)" ` -TemplatePath $(TemplatePath) ` -ImageName "$(ManagedImageName)" ` -ImageResourceGroupName $(AZURE_RESOURCE_GROUP) ` -TempResourceGroupName "$(TempResourceGroupName)" ` -SubscriptionId $(AZURE_SUBSCRIPTION) ` -TenantId $(AZURE_TENANT) ` -Location $(AZURE_LOCATION) ` -VirtualNetworkName $(BUILD_AGENT_VNET_NAME) ` -VirtualNetworkRG $(BUILD_AGENT_VNET_RESOURCE_GROUP) ` -VirtualNetworkSubnet $(BUILD_AGENT_SUBNET_NAME) env: PACKER_LOG: 1 PACKER_LOG_PATH: "$(Agent.TempDirectory)/packer-log.txt" - task: PowerShell@2 displayName: 'Copy image artifacts to the separate directory' inputs: targetType: 'inline' script: | $ImageType = "${{ parameters.image_type }}" $rootDirectoryName = if ($ImageType.StartsWith("ubuntu")) { "ubuntu" } else { "windows" } $rootDirectoryPath = Join-Path "images" $rootDirectoryName | Resolve-Path $readmePath = Join-Path $rootDirectoryPath "${{ parameters.image_readme_name }}" $softwareReportPath = Join-Path $rootDirectoryPath "software-report.json" Copy-Item -Path $readmePath -Destination "$(Build.ArtifactStagingDirectory)/" if (Test-Path $softwareReportPath) { Copy-Item -Path $softwareReportPath -Destination "$(Build.ArtifactStagingDirectory)/" } - task: PowerShell@2 displayName: 'Print markdown software report' inputs: targetType: 'inline' script: | Get-Content -Path "$(Build.ArtifactStagingDirectory)/${{ parameters.image_readme_name }}" - task: PowerShell@2 displayName: 'Print json software report' inputs: targetType: 'inline' script: | $softwareReportPath = "$(Build.ArtifactStagingDirectory)/software-report.json" if (Test-Path $softwareReportPath) { Get-Content -Path $softwareReportPath } - task: PublishBuildArtifacts@1 inputs: ArtifactName: 'Built_VM_Artifacts' displayName: Publish Artifacts - task: PowerShell@2 displayName: 'Print provisioners duration' inputs: targetType: 'filePath' filePath: ./images.CI/measure-provisioners-duration.ps1 arguments: -PackerLogPath "$(Agent.TempDirectory)/packer-log.txt" ` -PrefixToPathTrim "$(TemplateDirectoryPath)" ` -PrintTopNLongest 25 - ${{ if eq(parameters.create_release, true) }}: - task: PowerShell@2 displayName: 'Create release for VM deployment' inputs: targetType: filePath filePath: ./images.CI/linux-and-win/create-release.ps1 arguments: -BuildId $(Build.BuildId) ` -Organization $(RELEASE_TARGET_ORGANIZATION) ` -DefinitionId $(RELEASE_TARGET_DEFINITION_ID) ` -Project $(RELEASE_TARGET_PROJECT) ` -ImageType "${{ parameters.image_type }}" ` -ManagedImageName "$(ManagedImageName)" ` -AccessToken $(RELEASE_TARGET_TOKEN) - task: PowerShell@2 displayName: 'Clean up resources' condition: always() inputs: targetType: filePath filePath: ./images.CI/linux-and-win/cleanup.ps1 arguments: -TempResourceGroupName "$(TempResourceGroupName)" ` -SubscriptionId $(AZURE_SUBSCRIPTION) ` -ClientId $(CLIENT_ID) ` -ClientSecret "$(ClientSecret)" ` -TenantId $(AZURE_TENANT)