Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into microbuild_staging
Browse files Browse the repository at this point in the history
  • Loading branch information
AArnott committed Oct 4, 2024
2 parents c34c789 + 75baba3 commit 0f64e0a
Show file tree
Hide file tree
Showing 5 changed files with 252 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
fail-fast: false
matrix:
os:
- ubuntu-20.04
- ubuntu-22.04
- macos-latest
- windows-latest

Expand Down
25 changes: 25 additions & 0 deletions azure-pipelines/Get-LibTemplateBasis.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<#
.SYNOPSIS
Returns the name of the well-known branch in the Library.Template repository upon which HEAD is based.
#>
[CmdletBinding(SupportsShouldProcess = $true)]
Param(
[switch]$ErrorIfNotRelated
)

# This list should be sorted in order of decreasing specificity.
$branchMarkers = @(
@{ commit = 'fd0a7b25ccf030bbd16880cca6efe009d5b1fffc'; branch = 'microbuild' };
@{ commit = '05f49ce799c1f9cc696d53eea89699d80f59f833'; branch = 'main' };
)

foreach ($entry in $branchMarkers) {
if (git rev-list HEAD | Select-String -Pattern $entry.commit) {
return $entry.branch
}
}

if ($ErrorIfNotRelated) {
Write-Error "Library.Template has not been previously merged with this repo. Please review https://github.com/AArnott/Library.Template/tree/main?tab=readme-ov-file#readme for instructions."
exit 1
}
2 changes: 1 addition & 1 deletion azure-pipelines/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ parameters:
- name: linuxPool
type: object
default:
vmImage: ubuntu-20.04
vmImage: ubuntu-22.04
- name: macOSPool
type: object
default:
Expand Down
146 changes: 146 additions & 0 deletions azure-pipelines/libtemplate-update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# This pipeline schedules regular merges of Library.Template into a repo that is based on it.
# Only Azure Repos are supported. GitHub support comes via a GitHub Actions workflow.

trigger: none
pr: none
schedules:
- cron: "0 3 * * Mon" # Sun @ 8 or 9 PM Mountain Time (depending on DST)
displayName: Weekly trigger
branches:
include:
- main
always: true

parameters:
- name: AutoComplete
displayName: Auto-complete pull request
type: boolean
default: false

stages:
- stage: Merge
jobs:
- job: merge
pool:
vmImage: ubuntu-latest
steps:
- checkout: self
fetchDepth: 0
clean: true
- pwsh: |
$LibTemplateBranch = & ./azure-pipelines/Get-LibTemplateBasis.ps1 -ErrorIfNotRelated
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
git fetch https://github.com/aarnott/Library.Template $LibTemplateBranch
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
$LibTemplateCommit = git rev-parse FETCH_HEAD
if ((git rev-list FETCH_HEAD ^HEAD --count) -eq 0) {
Write-Host "There are no Library.Template updates to merge."
exit 0
}
$UpdateBranchName = 'auto/libtemplateUpdate'
git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" push origin -f FETCH_HEAD:refs/heads/$UpdateBranchName
Write-Host "Creating pull request"
$contentType = 'application/json';
$headers = @{ Authorization = 'Bearer $(System.AccessToken)' };
$rawRequest = @{
sourceRefName = "refs/heads/$UpdateBranchName";
targetRefName = "refs/heads/main";
title = 'Merge latest Library.Template';
description = "This merges the latest features and fixes from [Library.Template's $LibTemplateBranch branch](https://github.com/AArnott/Library.Template/tree/$LibTemplateBranch).";
}
$request = ConvertTo-Json $rawRequest
$prApiBaseUri = '$(System.TeamFoundationCollectionUri)/$(System.TeamProject)/_apis/git/repositories/$(Build.Repository.ID)/pullrequests'
$prCreationUri = $prApiBaseUri + "?api-version=6.0"
Write-Host "POST $prCreationUri"
Write-Host $request
$prCreationResult = Invoke-RestMethod -uri $prCreationUri -method POST -Headers $headers -ContentType $contentType -Body $request
$prUrl = "$($prCreationResult.repository.webUrl)/pullrequest/$($prCreationResult.pullRequestId)"
Write-Host "Pull request: $prUrl"
$prApiBaseUri += "/$($prCreationResult.pullRequestId)"
$SummaryPath = Join-Path '$(Agent.TempDirectory)' 'summary.md'
Set-Content -Path $SummaryPath -Value "[Insertion pull request]($prUrl)"
Write-Host "##vso[task.uploadsummary]$SummaryPath"
# Tag the PR
$tagUri = "$prApiBaseUri/labels?api-version=7.0"
$rawRequest = @{
name = 'auto-template-merge';
}
$request = ConvertTo-Json $rawRequest
Invoke-RestMethod -uri $tagUri -method POST -Headers $headers -ContentType $contentType -Body $request | Out-Null
# Add properties to the PR that we can programatically parse later.
Function Set-PRProperties($properties) {
$rawRequest = $properties.GetEnumerator() |% {
@{
op = 'add'
path = "/$($_.key)"
from = $null
value = $_.value
}
}
$request = ConvertTo-Json $rawRequest
$setPrPropertyUri = "$prApiBaseUri/properties?api-version=7.0"
Write-Debug "$request"
$setPrPropertyResult = Invoke-RestMethod -uri $setPrPropertyUri -method PATCH -Headers $headers -ContentType 'application/json-patch+json' -Body $request -StatusCodeVariable setPrPropertyStatus -SkipHttpErrorCheck
if ($setPrPropertyStatus -ne 200) {
Write-Host "##vso[task.logissue type=warning]Failed to set pull request properties. Result: $setPrPropertyStatus. $($setPrPropertyResult.message)"
}
}
Write-Host "Setting pull request properties"
Set-PRProperties @{
'AutomatedMerge.SourceBranch' = $LibTemplateBranch
'AutomatedMerge.SourceCommit' = $LibTemplateCommit
}
# Add an *active* PR comment to warn users to *merge* the pull request instead of squash it.
$request = ConvertTo-Json @{
comments = @(
@{
parentCommentId = 0
content = "Do **not** squash this pull request when completing it. You must *merge* it."
commentType = 'system'
}
)
status = 'active'
}
$result = Invoke-RestMethod -uri "$prApiBaseUri/threads?api-version=7.1" -method POST -Headers $headers -ContentType $contentType -Body $request -StatusCodeVariable addCommentStatus -SkipHttpErrorCheck
if ($addCommentStatus -ne 200) {
Write-Host "##vso[task.logissue type=warning]Failed to post comment on pull request. Result: $addCommentStatus. $($result.message)"
}
# Set auto-complete on the PR
if ('${{ parameters.AutoComplete }}' -eq 'True') {
Write-Host "Setting auto-complete"
$mergeMessage = "Merged PR $($prCreationResult.pullRequestId): " + $commitMessage
$rawRequest = @{
autoCompleteSetBy = @{
id = $prCreationResult.createdBy.id
};
completionOptions = @{
deleteSourceBranch = $true;
mergeCommitMessage = $mergeMessage;
mergeStrategy = 'noFastForward';
};
}
$request = ConvertTo-Json $rawRequest
Write-Host $request
$uri = "$($prApiBaseUri)?api-version=6.0"
$result = Invoke-RestMethod -uri $uri -method PATCH -Headers $headers -ContentType $contentType -Body $request -StatusCodeVariable autoCompleteStatus -SkipHttpErrorCheck
if ($autoCompleteStatus -ne 200) {
Write-Host "##vso[task.logissue type=warning]Failed to set auto-complete on pull request. Result: $autoCompleteStatus. $($result.message)"
}
}
displayName: Create pull request
79 changes: 79 additions & 0 deletions tools/MergeFrom-Template.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

<#
.SYNOPSIS
Merges the latest changes from Library.Template into HEAD of this repo.
.PARAMETER LocalBranch
The name of the local branch to create at HEAD and use to merge into from Library.Template.
#>
[CmdletBinding(SupportsShouldProcess = $true)]
Param(
[string]$LocalBranch = "dev/$($env:USERNAME)/libtemplateUpdate"
)

Function Spawn-Tool($command, $commandArgs, $workingDirectory, $allowFailures) {
if ($workingDirectory) {
Push-Location $workingDirectory
}
try {
if ($env:TF_BUILD) {
Write-Host "$pwd >"
Write-Host "##[command]$command $commandArgs"
}
else {
Write-Host "$command $commandArgs" -ForegroundColor Yellow
}
if ($commandArgs) {
& $command @commandArgs
} else {
Invoke-Expression $command
}
if ((!$allowFailures) -and ($LASTEXITCODE -ne 0)) { exit $LASTEXITCODE }
}
finally {
if ($workingDirectory) {
Pop-Location
}
}
}

$remoteBranch = & $PSScriptRoot\..\azure-pipelines\Get-LibTemplateBasis.ps1 -ErrorIfNotRelated
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}

$LibTemplateUrl = 'https://github.com/aarnott/Library.Template'
Spawn-Tool 'git' ('fetch', $LibTemplateUrl, $remoteBranch)
$SourceCommit = git rev-parse FETCH_HEAD
$BaseBranch = Spawn-Tool 'git' ('branch', '--show-current')
$SourceCommitUrl = "$LibTemplateUrl/commit/$SourceCommit"

# To reduce the odds of merge conflicts at this stage, we always move HEAD to the last successful merge.
$basis = Spawn-Tool 'git' ('rev-parse', 'HEAD') # TODO: consider improving this later

Write-Host "Merging the $remoteBranch branch of Library.Template ($SourceCommit) into local repo $basis" -ForegroundColor Green

Spawn-Tool 'git' ('checkout', '-b', $LocalBranch, $basis) $null $true
if ($LASTEXITCODE -eq 128) {
Spawn-Tool 'git' ('checkout', $LocalBranch)
Spawn-Tool 'git' ('merge', $basis)
}

Spawn-Tool 'git' ('merge', 'FETCH_HEAD', '--no-ff', '-m', "Merge the $remoteBranch branch from $LibTemplateUrl`n`nSpecifically, this merges [$SourceCommit from that repo]($SourceCommitUrl).")
if ($LASTEXITCODE -eq 1) {
Write-Error "Merge conflict detected. Manual resolution required."
exit 1
}
elseif ($LASTEXITCODE -ne 0) {
Write-Error "Merge failed with exit code $LASTEXITCODE."
exit $LASTEXITCODE
}

$result = New-Object PSObject -Property @{
BaseBranch = $BaseBranch # The original branch that was checked out when the script ran.
LocalBranch = $LocalBranch # The name of the local branch that was created before the merge.
SourceCommit = $SourceCommit # The commit from Library.Template that was merged in.
SourceBranch = $remoteBranch # The branch from Library.Template that was merged in.
}

Write-Host $result
Write-Output $result

0 comments on commit 0f64e0a

Please sign in to comment.