|
| 1 | +# This pipeline schedules regular merges of Library.Template into a repo that is based on it. |
| 2 | +# Only Azure Repos are supported. GitHub support comes via a GitHub Actions workflow. |
| 3 | + |
| 4 | +trigger: none |
| 5 | +pr: none |
| 6 | +schedules: |
| 7 | +- cron: "0 3 * * Mon" # Sun @ 8 or 9 PM Mountain Time (depending on DST) |
| 8 | + displayName: Weekly trigger |
| 9 | + branches: |
| 10 | + include: |
| 11 | + - main |
| 12 | + always: true |
| 13 | + |
| 14 | +parameters: |
| 15 | +- name: AutoComplete |
| 16 | + displayName: Auto-complete pull request |
| 17 | + type: boolean |
| 18 | + default: false |
| 19 | + |
| 20 | +stages: |
| 21 | +- stage: Merge |
| 22 | + jobs: |
| 23 | + - job: merge |
| 24 | + pool: |
| 25 | + vmImage: ubuntu-latest |
| 26 | + steps: |
| 27 | + - checkout: self |
| 28 | + fetchDepth: 0 |
| 29 | + clean: true |
| 30 | + - pwsh: | |
| 31 | + $LibTemplateBranch = & ./azure-pipelines/Get-LibTemplateBasis.ps1 -ErrorIfNotRelated |
| 32 | + if ($LASTEXITCODE -ne 0) { |
| 33 | + exit $LASTEXITCODE |
| 34 | + } |
| 35 | +
|
| 36 | + git fetch https://github.com/aarnott/Library.Template $LibTemplateBranch |
| 37 | + if ($LASTEXITCODE -ne 0) { |
| 38 | + exit $LASTEXITCODE |
| 39 | + } |
| 40 | + $LibTemplateCommit = git rev-parse FETCH_HEAD |
| 41 | +
|
| 42 | + if ((git rev-list FETCH_HEAD ^HEAD --count) -eq 0) { |
| 43 | + Write-Host "There are no Library.Template updates to merge." |
| 44 | + exit 0 |
| 45 | + } |
| 46 | +
|
| 47 | + $UpdateBranchName = 'auto/libtemplateUpdate' |
| 48 | + git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push origin -f FETCH_HEAD:refs/heads/$UpdateBranchName |
| 49 | +
|
| 50 | + Write-Host "Creating pull request" |
| 51 | + $contentType = 'application/json'; |
| 52 | + $headers = @{ Authorization = 'Bearer $(System.AccessToken)' }; |
| 53 | + $rawRequest = @{ |
| 54 | + sourceRefName = "refs/heads/$UpdateBranchName"; |
| 55 | + targetRefName = "refs/heads/main"; |
| 56 | + title = 'Merge latest Library.Template'; |
| 57 | + description = "This merges the latest features and fixes from [Library.Template's $LibTemplateBranch branch](https://github.com/AArnott/Library.Template/tree/$LibTemplateBranch)."; |
| 58 | + } |
| 59 | + $request = ConvertTo-Json $rawRequest |
| 60 | +
|
| 61 | + $prApiBaseUri = '$(System.TeamFoundationCollectionUri)/$(System.TeamProject)/_apis/git/repositories/$(Build.Repository.ID)/pullrequests' |
| 62 | + $prCreationUri = $prApiBaseUri + "?api-version=6.0" |
| 63 | + Write-Host "POST $prCreationUri" |
| 64 | + Write-Host $request |
| 65 | +
|
| 66 | + $prCreationResult = Invoke-RestMethod -uri $prCreationUri -method POST -Headers $headers -ContentType $contentType -Body $request |
| 67 | + $prUrl = "$($prCreationResult.repository.webUrl)/pullrequest/$($prCreationResult.pullRequestId)" |
| 68 | + Write-Host "Pull request: $prUrl" |
| 69 | + $prApiBaseUri += "/$($prCreationResult.pullRequestId)" |
| 70 | +
|
| 71 | + $SummaryPath = Join-Path '$(Agent.TempDirectory)' 'summary.md' |
| 72 | + Set-Content -Path $SummaryPath -Value "[Insertion pull request]($prUrl)" |
| 73 | + Write-Host "##vso[task.uploadsummary]$SummaryPath" |
| 74 | +
|
| 75 | + # Tag the PR |
| 76 | + $tagUri = "$prApiBaseUri/labels?api-version=7.0" |
| 77 | + $rawRequest = @{ |
| 78 | + name = 'auto-template-merge'; |
| 79 | + } |
| 80 | + $request = ConvertTo-Json $rawRequest |
| 81 | + Invoke-RestMethod -uri $tagUri -method POST -Headers $headers -ContentType $contentType -Body $request | Out-Null |
| 82 | +
|
| 83 | + # Add properties to the PR that we can programatically parse later. |
| 84 | + Function Set-PRProperties($properties) { |
| 85 | + $rawRequest = $properties.GetEnumerator() |% { |
| 86 | + @{ |
| 87 | + op = 'add' |
| 88 | + path = "/$($_.key)" |
| 89 | + from = $null |
| 90 | + value = $_.value |
| 91 | + } |
| 92 | + } |
| 93 | + $request = ConvertTo-Json $rawRequest |
| 94 | + $setPrPropertyUri = "$prApiBaseUri/properties?api-version=7.0" |
| 95 | + Write-Debug "$request" |
| 96 | + $setPrPropertyResult = Invoke-RestMethod -uri $setPrPropertyUri -method PATCH -Headers $headers -ContentType 'application/json-patch+json' -Body $request -StatusCodeVariable setPrPropertyStatus -SkipHttpErrorCheck |
| 97 | + if ($setPrPropertyStatus -ne 200) { |
| 98 | + Write-Host "##vso[task.logissue type=warning]Failed to set pull request properties. Result: $setPrPropertyStatus. $($setPrPropertyResult.message)" |
| 99 | + } |
| 100 | + } |
| 101 | + Write-Host "Setting pull request properties" |
| 102 | + Set-PRProperties @{ |
| 103 | + 'AutomatedMerge.SourceBranch' = $LibTemplateBranch |
| 104 | + 'AutomatedMerge.SourceCommit' = $LibTemplateCommit |
| 105 | + } |
| 106 | +
|
| 107 | + # Add an *active* PR comment to warn users to *merge* the pull request instead of squash it. |
| 108 | + $request = ConvertTo-Json @{ |
| 109 | + comments = @( |
| 110 | + @{ |
| 111 | + parentCommentId = 0 |
| 112 | + content = "Do **not** squash this pull request when completing it. You must *merge* it." |
| 113 | + commentType = 'system' |
| 114 | + } |
| 115 | + ) |
| 116 | + status = 'active' |
| 117 | + } |
| 118 | + $result = Invoke-RestMethod -uri "$prApiBaseUri/threads?api-version=7.1" -method POST -Headers $headers -ContentType $contentType -Body $request -StatusCodeVariable addCommentStatus -SkipHttpErrorCheck |
| 119 | + if ($addCommentStatus -ne 200) { |
| 120 | + Write-Host "##vso[task.logissue type=warning]Failed to post comment on pull request. Result: $addCommentStatus. $($result.message)" |
| 121 | + } |
| 122 | +
|
| 123 | + # Set auto-complete on the PR |
| 124 | + if ('${{ parameters.AutoComplete }}' -eq 'True') { |
| 125 | + Write-Host "Setting auto-complete" |
| 126 | + $mergeMessage = "Merged PR $($prCreationResult.pullRequestId): " + $commitMessage |
| 127 | + $rawRequest = @{ |
| 128 | + autoCompleteSetBy = @{ |
| 129 | + id = $prCreationResult.createdBy.id |
| 130 | + }; |
| 131 | + completionOptions = @{ |
| 132 | + deleteSourceBranch = $true; |
| 133 | + mergeCommitMessage = $mergeMessage; |
| 134 | + mergeStrategy = 'noFastForward'; |
| 135 | + }; |
| 136 | + } |
| 137 | + $request = ConvertTo-Json $rawRequest |
| 138 | + Write-Host $request |
| 139 | + $uri = "$($prApiBaseUri)?api-version=6.0" |
| 140 | + $result = Invoke-RestMethod -uri $uri -method PATCH -Headers $headers -ContentType $contentType -Body $request -StatusCodeVariable autoCompleteStatus -SkipHttpErrorCheck |
| 141 | + if ($autoCompleteStatus -ne 200) { |
| 142 | + Write-Host "##vso[task.logissue type=warning]Failed to set auto-complete on pull request. Result: $autoCompleteStatus. $($result.message)" |
| 143 | + } |
| 144 | + } |
| 145 | +
|
| 146 | + displayName: Create pull request |
0 commit comments