From fd09c368b8fbb73c308c368a0c0a13d03341914b Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Thu, 4 Feb 2021 17:24:28 -0500 Subject: [PATCH 1/5] Support several backports in a single command. When working in large projects with more than one release branch the old code made us write a comment PER branch, resulting in something like: /sudo backport d16-9 /sudo backport xcode12.4 /sudo backport xcode12.5 That is a lot of work and developers are lazy animals. We already supported using more than one branch in the regexp but it resulted in an error later in the script. This commit makes the required changes to ensure that we support several branches. 1. Pares all branches, creates a collection in the params. 2. If only one branhc is used, we create a collection with a single object, else several. 3. We trigger a backport PER branch in a loop using a scriptblock. 4. The exit code is the addition of all the execitions, resulting in 0 if all worked or the number of errors. --- action.yml | 135 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 87 insertions(+), 48 deletions(-) diff --git a/action.yml b/action.yml index 165276f..4bc4c44 100644 --- a/action.yml +++ b/action.yml @@ -62,16 +62,39 @@ runs: $response = Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri "${{ inputs.pull_request_url }}" | ConvertFrom-Json $backportPRNumber = $response.number - $parameters = @{ - BackportRepoName = "$repoName"; - BackportRepoOrg = "$repoOwner"; - BackportTargetBranch = "$backportTargetBranch"; - BackportPRNumber = "$backportPRNumber"; - BackportHeadSHA = "$($response.head.sha)"; - UseFork = "${{ inputs.use_fork }}" -eq "true"; - } | ConvertTo-Json -Compress - - $json = $parameters.Replace("`"","'") + # we can have a comment that wanted to backport to several PRs, that would mean that we create a backport pr branch + + $parameters = @() + + if ($backportTargetBranch.GetType().Name -eq "String") { # uh, this is ugly, but String also has length and we can iterate, so we need the type + $parameters.Add( + @{ + BackportRepoName = "$repoName"; + BackportRepoOrg = "$repoOwner"; + BackportTargetBranch = "$backportTargetBranch"; + BackportPRNumber = "$backportPRNumber"; + BackportHeadSHA = "$($response.head.sha)"; + UseFork = "${{ inputs.use_fork }}" -eq "true"; + } + ) + } else { + foreach ($branch in $backportTargetBranch) { + $parameters.Add( + @{ + BackportRepoName = "$repoName"; + BackportRepoOrg = "$repoOwner"; + BackportTargetBranch = "$branch"; + BackportPRNumber = "$backportPRNumber"; + BackportHeadSHA = "$($response.head.sha)"; + UseFork = "${{ inputs.use_fork }}" -eq "true"; + } + ) + } + } + + $parametersJson = $parameters | ConvertTo-Json -Compress + + $json = $parametersJon.Replace("`"","'") Write-Host "Setting output variables" echo "::set-output name=parameters::$json" echo "::set-output name=pr_number::$backportPRNumber" @@ -85,49 +108,65 @@ runs: - name: Launch ADO Build id: ado_build run: | - $message = "" - $statusCode = 0 - try { - $launchURI = "https://dev.azure.com/${{ inputs.ado_organization }}/${{ inputs.ado_project }}/_apis/pipelines/${{ inputs.backport_pipeline_id }}/runs?api-version=6.0-preview.1" - Write-Host "Grabbing parameters from prior step" - $parameters = ConvertFrom-Json "${{ steps.get_parameters.outputs.parameters }}" - Write-Host "$parameters" - $jsonBody = @{ - previewRun = false; - templateParameters = $parameters; - resources = @{ - repositories = @{ - self = @{ - refName = "refs/heads/yaml-pipeline" + # common stuff that is reused per call + Write-Host "Grabbing parameters from prior step" + $backportParameters = ConvertFrom-Json "${{ steps.get_parameters.outputs.parameters }}" + Write-Host "$backportParameters" + + $launchURI = "https://dev.azure.com/${{ inputs.ado_organization }}/${{ inputs.ado_project }}/_apis/pipelines/${{ inputs.backport_pipeline_id }}/runs?api-version=6.0-preview.1" + # create a scriptblock that will be called per branch created, makes it a lot simpler to read + $createBackport = { + param($parameters) + + $message = "" + $statusCode = 0 + + try { + $jsonBody = @{ + previewRun = false; + templateParameters = $parameters; + resources = @{ + repositories = @{ + self = @{ + refName = "refs/heads/yaml-pipeline" + } } - } - }; - } | ConvertTo-Json -Depth 10 + } | ConvertTo-Json -Depth 10 - Write-Host "Posting to $launchURI" - Write-Host $jsonBody - $encoded = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":${{ inputs.ado_build_pat }}")) - $headers = @{ Authorization = "Basic $encoded"} + Write-Host "Posting to $launchURI" + Write-Host $jsonBody + $encoded = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":${{ inputs.ado_build_pat }}")) + $headers = @{ Authorization = "Basic $encoded"} - $response = Invoke-WebRequest -UseBasicParsing -Method POST -Headers $headers -ContentType "application/json" -Uri $launchURI -Body $jsonBody - echo "Job successfully launched" - $message = "Backport Job to branch $($parameters.BackportTargetBranch) Created! The magic is happening [here](https://dev.azure.com/${{ inputs.ado_organization }}/${{ inputs.ado_project }}/_build/results?buildId=$($responseJson.id))" - } catch { - Write-Host $_.Exception.Message - $message = "I couldn't create a backport for you. :( Please check the Action logs for more details." - $statusCode = 1 - } finally { - $jsonBody = @{ - body = $message - } | ConvertTo-Json + $response = Invoke-WebRequest -UseBasicParsing -Method POST -Headers $headers -ContentType "application/json" -Uri $launchURI -Body $jsonBody + echo "Job successfully launched" + $message = "Backport Job to branch $($parameters.BackportTargetBranch) Created! The magic is happening [here](https://dev.azure.com/${{ inputs.ado_organization }}/${{ inputs.ado_project }}/_build/results?buildId=$($responseJson.id))" + } catch { + Write-Host $_.Exception.Message + $message = "I couldn't create a backport to $($parameters.BackportTargetBranch) for you. :( Please check the Action logs for more details." + $statusCode = 1 + } finally { + $jsonBody = @{ + body = $message + } | ConvertTo-Json - $headers = @{ Authorization = "token ${{ inputs.github_account_pat }}"} - $uri = "https://api.github.com/repos/${{ inputs.github_repository }}/issues/${{ steps.get_parameters.outputs.pr_number }}/comments" + $headers = @{ Authorization = "token ${{ inputs.github_account_pat }}"} + $uri = "https://api.github.com/repos/${{ inputs.github_repository }}/issues/${{ steps.get_parameters.outputs.pr_number }}/comments" - Write-Host "Posting to $uri" - Write-Host "$jsonBody" - Invoke-WebRequest -UseBasicParsing -Headers $headers -Method POST -Uri $uri -Body $jsonBody + Write-Host "Posting to $uri" + Write-Host "$jsonBody" + Invoke-WebRequest -UseBasicParsing -Headers $headers -Method POST -Uri $uri -Body $jsonBody + } # finally + + return $statusCode + } # block + + # a little ugly, but not terribly ugly, we are going add the status code per callback and use that as our return, if everything work, we always get 0 and we return 0, else we return the number of errors + $exitCode = 0 + foreach ($p in $backportParameters) { + # what a great and nice way to cal a lambda, the & is a must or you wont do a thing, &$ is just nice syntax + $exitCode += &$createBackport($p) } - return $statusCode + return $exitCode shell: pwsh From 339c63abd4e30f5f3e99ac56a8ce9bd197df0134 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Thu, 4 Feb 2021 17:56:51 -0500 Subject: [PATCH 2/5] Fix english --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index be0f17a..896a629 100644 --- a/action.yml +++ b/action.yml @@ -62,7 +62,7 @@ runs: $response = Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri "${{ inputs.pull_request_url }}" | ConvertFrom-Json $backportPRNumber = $response.number - # we can have a comment that wanted to backport to several PRs, that would mean that we create a backport pr branch + # we can have a comment that wants to backport to several PRs, that would mean that we create a backport per branch $parameters = @() From d586b11997d3c45631fe463dcc0a50d86e25113d Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Fri, 5 Feb 2021 15:55:43 -0500 Subject: [PATCH 3/5] Use '-is' operator. --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index be0f17a..3e53efd 100644 --- a/action.yml +++ b/action.yml @@ -66,7 +66,7 @@ runs: $parameters = @() - if ($backportTargetBranch.GetType().Name -eq "String") { # uh, this is ugly, but String also has length and we can iterate, so we need the type + if ($backportTargetBranch -is [string]) { # uh, this is ugly, but String also has length and we can iterate, so we need the type $parameters.Add( @{ BackportRepoName = "$repoName"; From 11468adbff26005537f2174d50cbff556b930ec7 Mon Sep 17 00:00:00 2001 From: Manuel de la Pena Date: Tue, 16 Feb 2021 11:46:08 -0500 Subject: [PATCH 4/5] pwsh arrays cannot be mutated. --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 8ca1f6a..2d883c7 100644 --- a/action.yml +++ b/action.yml @@ -64,7 +64,7 @@ runs: # we can have a comment that wants to backport to several PRs, that would mean that we create a backport per branch - $parameters = @() + $parameters = [System.Collections.ArrayList]@() if ($backportTargetBranch -is [string]) { # uh, this is ugly, but String also has length and we can iterate, so we need the type $parameters.Add( From abb3284200b212540151a03fdd375d53a4f81129 Mon Sep 17 00:00:00 2001 From: cadsit Date: Tue, 16 Feb 2021 13:44:15 -0500 Subject: [PATCH 5/5] Close hash literal --- action.yml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/action.yml b/action.yml index 2d883c7..52aff6e 100644 --- a/action.yml +++ b/action.yml @@ -62,7 +62,7 @@ runs: $response = Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri "${{ inputs.pull_request_url }}" | ConvertFrom-Json $backportPRNumber = $response.number - # we can have a comment that wants to backport to several PRs, that would mean that we create a backport per branch + # we can have a comment that wants to backport to several PRs, that would mean that we create a backport per branch $parameters = [System.Collections.ArrayList]@() @@ -123,15 +123,16 @@ runs: try { $jsonBody = @{ - previewRun = false; - templateParameters = $parameters; - resources = @{ - repositories = @{ - self = @{ - refName = "refs/heads/yaml-pipeline" - } + previewRun = false; + templateParameters = $parameters; + resources = @{ + repositories = @{ + self = @{ + refName = "refs/heads/yaml-pipeline" } - } | ConvertTo-Json -Depth 10 + } + } + } | ConvertTo-Json -Depth 10 Write-Host "Posting to $launchURI" Write-Host $jsonBody @@ -161,12 +162,12 @@ runs: return $statusCode } # block - - # a little ugly, but not terribly ugly, we are going add the status code per callback and use that as our return, if everything work, we always get 0 and we return 0, else we return the number of errors + + # a little ugly, but not terribly ugly, we are going add the status code per callback and use that as our return, if everything work, we always get 0 and we return 0, else we return the number of errors $exitCode = 0 foreach ($p in $backportParameters) { # what a great and nice way to cal a lambda, the & is a must or you wont do a thing, &$ is just nice syntax - $exitCode += &$createBackport($p) + $exitCode += &$createBackport($p) } return $exitCode shell: pwsh