diff --git a/eng/pipelines/templates/stages/archetype-cpp-release.yml b/eng/pipelines/templates/stages/archetype-cpp-release.yml index 29f8d0463..c4af6b90e 100644 --- a/eng/pipelines/templates/stages/archetype-cpp-release.yml +++ b/eng/pipelines/templates/stages/archetype-cpp-release.yml @@ -103,7 +103,11 @@ stages: - pwsh: | $packageSpec = Get-Content -Raw -Path "$(Pipeline.Workspace)/packages/${{artifact.Name}}/package-info.json" | ConvertFrom-Json $version = $packageSpec.version - $title = "[${{ artifact.VcpkgPortName }}] publish version $version" + Write-Host "##vso[task.setvariable variable=PackageVersion]$version" + displayName: Set PackageVersion variable + + - pwsh: | + $title = "[${{ artifact.VcpkgPortName }}] publish version $(PackageVersion)" if ('$(VcpkgPRTitle)') { Write-Host "Using queue time PR title" @@ -112,12 +116,6 @@ stages: Write-Host "##vso[task.setvariable variable=PrTitle]$title" displayName: Set PR title - - pwsh: | - $packageSpec = Get-Content -Raw -Path "$(Pipeline.Workspace)/packages/${{artifact.Name}}/package-info.json" | ConvertFrom-Json - $version = $packageSpec.version - Write-Host "##vso[task.setvariable variable=PackageVersion]$version" - displayName: Set PackageVersion variable - - task: Powershell@2 inputs: filePath: eng/scripts/Initialize-VcpkgRelease.ps1 @@ -133,66 +131,56 @@ stages: # in parallel against the same branch name. Release only # one package at a time. - pwsh: | - Write-Host "git clone https://github.com/microsoft/vcpkg $(Pipeline.Workspace)/vcpkg" - git clone https://github.com/microsoft/vcpkg $(Pipeline.Workspace)/vcpkg + Write-Host "git clone https://github.com/azure-sdk/vcpkg $(Pipeline.Workspace)/vcpkg" + git clone https://github.com/azure-sdk/vcpkg $(Pipeline.Workspace)/vcpkg if ($LASTEXITCODE -ne 0) { - Write-Error "Unable to check out vcpkg repo" + Write-Error "Unable to check out vcpkg fork repo" exit $LASTEXITCODE } - - Write-Host "cd $(Pipeline.Workspace)/vcpkg" - cd $(Pipeline.Workspace)/vcpkg + Write-Host "##vso[task.setvariable variable=VcpkgWorkspace]$(Pipeline.Workspace)/vcpkg" + displayName: Clone vcpkg from upstream - # Clean out the folder so that template files removed - # are not inadvertently re-added - if (Test-Path "ports/${{ artifact.VcpkgPortName }}") { - Remove-Item -v -r "ports/${{ artifact.VcpkgPortName }}" - } - - New-Item -Type Directory ports/${{ artifact.VcpkgPortName }} - Copy-Item -Verbose $(Pipeline.Workspace)/packages/${{artifact.Name}}/vcpkg/port/* ports/${{ artifact.VcpkgPortName }} - - # Show artifacts copied into ports folder for PR - Get-ChildItem -Recurse ports/${{ artifact.VcpkgPortName }} - - Write-Host "git status" + # Check out the PR branch if it's already in remote. + # Ignore failures. + - pwsh: | + $ErrorActionPreference = "Continue" + git checkout "origin/$(PrBranchName)" 2>&1 | Out-Null + $LASTEXITCODE = 0 # This ignores any error from git checkout git status + displayName: Checkout Previous PRBranch if it exist. + workingDirectory: $(VcpkgWorkspace) - # Commit changes - Write-Host "git add -A" - git add -A - Write-Host "git -c user.name=`"azure-sdk`" -c user.email=`"azuresdk@microsoft.com`" commit -m `"Initial vcpkg commit for ${{ artifact.VcpkgPortName }}`"" - git -c user.name="azure-sdk" -c user.email="azuresdk@microsoft.com" commit -m "Initial vcpkg commit for ${{ artifact.VcpkgPortName }}" + - task: Powershell@2 + inputs: + pwsh: true + targetType: filePath + filePath: eng/scripts/Update-VcpkgPort.ps1 + arguments: >- + -ReleaseArtifactSourceDirectory "$(Pipeline.Workspace)/packages/${{ artifact.Name }}" + -PortDestinationDirectory 'ports/${{ artifact.VcpkgPortName }}' + -VcpkgPortName '${{ artifact.VcpkgPortName }}' + -GitCommitParameters '-c user.name="azure-sdk" -c user.email="azuresdk@microsoft.com"' + workingDirectory: $(VcpkgWorkspace) + displayName: Update vcpkg port - # Run vcpkg x-add-version to add version to vcpkg file - Write-Host "./bootstrap-vcpkg.bat" - ./bootstrap-vcpkg.bat - Write-Host "./vcpkg.exe x-add-version ${{ artifact.VcpkgPortName }}" - ./vcpkg.exe x-add-version ${{ artifact.VcpkgPortName }} - - # Amend commit to include results of x-add-version - Write-Host "git status" - git status - Write-Host "git add -A" - git add -A - Write-Host "git -c user.name=`"azure-sdk`" -c user.email=`"azuresdk@microsoft.com`" commit --amend -m `"[${{ artifact.VcpkgPortName }}] Update to $(PackageVersion)`"" - git -c user.name="azure-sdk" -c user.email="azuresdk@microsoft.com" commit --amend -m "[${{ artifact.VcpkgPortName }}] Update to $(PackageVersion)" - - # Work around create-pull-request.yml logic that - # checks for changes - Write-Host "##vso[task.setvariable variable=HasChanges]$true" - displayName: Commit changes for PR + # Set $(HasChanges) to $true so that + # create-pull-request.yml completes the push and PR + # submission steps + - pwsh: Write-Host "##vso[task.setvariable variable=HasChanges]$true" + displayName: Set $(HasChanges) to $true for create-pull-request.yml + # SkipCheckingForChanges is true to skip the commit step + # (which is already done by Update-VcpkgPort.ps1) - template: /eng/common/pipelines/templates/steps/create-pull-request.yml parameters: RepoOwner: Microsoft RepoName: vcpkg WorkingDirectory: $(Pipeline.Workspace)/vcpkg PrBranchName: $(PrBranchName) - CommitMsg: "[${{ artifact.VcpkgPortName }}] Update to $(PackageVersion)" PRTitle: $(PrTitle) - BaseBranchName: master + PRBody: Update vcpkg ports for Azure SDK release. This release may contain multiple ports. SkipCheckingForChanges: true + BaseBranchName: master - ${{if ne(artifact.skipUpdatePackageVersion, 'true')}}: - deployment: UpdatePackageVersion diff --git a/eng/scripts/Update-VcpkgPort.ps1 b/eng/scripts/Update-VcpkgPort.ps1 new file mode 100644 index 000000000..e0e5c32d5 --- /dev/null +++ b/eng/scripts/Update-VcpkgPort.ps1 @@ -0,0 +1,150 @@ +param ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $ReleaseArtifactSourceDirectory, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $PortDestinationDirectory, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $VcpkgPortName, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $GitCommitParameters +) + +."$PSScriptRoot/../common/scripts/common.ps1" + +# Validate prerequisites +if (!(Test-Path bootstrap-vcpkg.bat)) { + LogError "Could not locate bootstrap-vcpkg.bat current directory must be a clone of the vcpkg repo (https://github.com/microsoft/vcpkg)" + exit 1 +} + +if ((Get-Command git | Measure-Object).Count -eq 0) { + LogError "Could not locate git. Install git https://git-scm.com/downloads" + exit 1 +} + +if (!(Test-Path $ReleaseArtifactSourceDirectory/package-info.json)) { + LogError "Could not locate package-info.json in -ReleaseArtifactSourceDirectory" + exit 1 +} + +if (!(Test-Path $ReleaseArtifactSourceDirectory/CHANGELOG.md)) { + LogError "Could not locate CHANGELOG.md in -ReleaseArtifactSourceDirectory" +} + +if (!(Test-Path $ReleaseArtifactSourceDirectory/vcpkg/port)) { + LogError "Could not locate vcpkg/port directory in -ReleaseArtifactSourceDirectory" +} + +# Clean out the folder so that template files removed are not inadvertently +# re-added +if (Test-Path $PortDestinationDirectory) { + Remove-Item -v -r $PortDestinationDirectory +} + +New-Item -Type Directory $PortDestinationDirectory +Copy-Item ` + -Verbose ` + "$ReleaseArtifactSourceDirectory/vcpkg/port/*" ` + $PortDestinationDirectory + +# Show artifacts copied into ports folder for PR +Write-Host "Files in destination directory:" +Get-ChildItem -Recurse $PortDestinationDirectory | Out-String | Write-Host + +Write-Host "git status" +git status + +# Temporarily commit changes to generate git tree objects required by +# "vcpkg x-add-version " +Write-Host "git add -A" +git add -A +Write-Host "git $GitCommitParameters commit -m 'Temporary commit to reset after x-add-version'" +"git $GitCommitParameters commit -m 'Temporary commit to reset after x-add-version'" | Invoke-Expression -Verbose | Write-Host + + +Write-Host "./bootstrap-vcpkg.bat" +./bootstrap-vcpkg.bat + +if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to run bootstrap-vcpkg.bat" + exit 1 +} + +Write-Host "./vcpkg.exe x-add-version $VcpkgPortName" +./vcpkg.exe x-add-version $VcpkgPortName + +if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to run vcpkg x-add-version $VcpkgPortName" + exit 1 +} + +# Reset to undo previous commit and put changes in the working directory. +Write-Host "git reset HEAD^" +git reset HEAD^ + +# Grab content needed for commit message and place in a temporary file +$packageVersion = (Get-Content $ReleaseArtifactSourceDirectory/package-info.json -Raw | ConvertFrom-Json).version +$commitMessageFile = New-TemporaryFile +$chagelogEntry = Get-ChangeLogEntryAsString ` + -ChangeLogLocation $ReleaseArtifactSourceDirectory/CHANGELOG.md ` + -VersionString $PackageVersion + +"[$VcpkgPortName] Update to $PackageVersion`n$chagelogEntry" ` + | Set-Content $commitMessageFile + +Write-Host "Commit Message:" +Write-host (Get-Content $commitMessageFile -Raw) + + +Write-Host "git add -A" +git add -A + +# Final commit using commit message from the temporary file. Using the file +# enables the commit message to be formatted properly without having to write +# code to escape certain characters that might appear in the changelog file. +Write-Host "git $GitCommitParameters commit --file $commitMessageFile" +"git $GitCommitParameters commit --file $commitMessageFile" ` + | Invoke-Expression -Verbose ` + | Write-Host + +<# +.SYNOPSIS +Uses release artifacts to update a vcpkg port + +.DESCRIPTION +This script updates a given vcpkg port using C++ release artifacts. It requires +that the GitHub repo is tagged and a release is available at that tag for +generating the SHA of the vcpkg artifact. + +This script also uses the contents of the changelog at the release version in +the commit message. + +Vcpkg requires the use of `vcpkg.exe x-add-version` to prepare ports going +forward. This script handles adding this and making a single commit so that +subsequent functions in the Azure DevOps pipeline can push the commit or rebase +as needed to get the commit into the PR branch. + +.PARAMETER ReleaseArtifactSourceDirectory +Location of the release artifact. Must have package-info.json, CHANGELOG.md, and +vcpkg/port/ + +.PARAMETER PortDestinationDirectory +Location of the vcpkg port folder where the port release artifacts are copied. +Generally "/ports/" + +.PARAMETER VcpkgPortName +Name of the vcpkg port (e.g. azure-template-cpp) + +.PARAMETER GitCommitParameters +Additional parameters to supply to the `git commit` command. These are useful +in the context of Azure DevOps where the git client does not have a configured +user.name and user.email. + +#>