From 1fc3d22ab40a79fca4ddc08ba6f925c5f983af4d Mon Sep 17 00:00:00 2001
From: Michka Popoff <michkapopoff@gmail.com>
Date: Sun, 22 Nov 2020 15:14:42 +0100
Subject: [PATCH] pr-pull: allow to pull from multiple workflows

and allow to skip missing workflows

Can be used like this:
brew pr-pull --workflows=tests.yml,wheezy_tests.yml --ignore-missing-artifacts=wheezy_tests.yml PRNUMBER
---
 Library/Homebrew/dev-cmd/pr-pull.rb        | 34 +++++++++++++++++++---
 Library/Homebrew/test/utils/github_spec.rb | 12 ++++++--
 Library/Homebrew/utils/github.rb           |  7 ++++-
 docs/Manpage.md                            |  6 +++-
 manpages/brew.1                            | 10 ++++++-
 5 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/Library/Homebrew/dev-cmd/pr-pull.rb b/Library/Homebrew/dev-cmd/pr-pull.rb
index 010d3e6acc..7e059fc478 100644
--- a/Library/Homebrew/dev-cmd/pr-pull.rb
+++ b/Library/Homebrew/dev-cmd/pr-pull.rb
@@ -50,7 +50,8 @@ module Homebrew
              depends_on:  "--autosquash",
              description: "Message to include when autosquashing revision bumps, deletions, and rebuilds."
       flag   "--workflow=",
-             description: "Retrieve artifacts from the specified workflow (default: `tests.yml`)."
+             description: "Retrieve artifacts from the specified workflow (default: `tests.yml`). "\
+                          "Legacy: use --workflows instead"
       flag   "--artifact=",
              description: "Download artifacts with the specified name (default: `bottles`)."
       flag   "--bintray-org=",
@@ -62,6 +63,11 @@ module Homebrew
       flag   "--bintray-mirror=",
              description: "Use the specified Bintray repository to automatically mirror stable URLs "\
                           "defined in the formulae (default: `mirror`)."
+      comma_array "--workflows=",
+                  description: "Retrieve artifacts from the specified workflow (default: `tests.yml`) "\
+                               "Comma-separated list to include multiple workflows."
+      comma_array "--ignore-missing-artifacts=",
+                  description: "Comma-separated list of workflows which can be ignored if they have not been run."
 
       conflicts "--clean", "--autosquash"
       min_named 1
@@ -357,7 +363,13 @@ module Homebrew
   def pr_pull
     args = pr_pull_args.parse
 
-    workflow = args.workflow || "tests.yml"
+    odeprecated "`brew pr-pull --workflow`", "`brew pr-pull --workflows=`" if args.workflow.presence
+
+    workflows = if args.workflow.blank?
+      args.workflows.presence || ["tests.yml"]
+    else
+      [args.workflow].compact.presence || ["tests.yml"]
+    end
     artifact = args.artifact || "bottles"
     bintray_org = args.bintray_org || "homebrew"
     mirror_repo = args.bintray_mirror || "mirror"
@@ -401,8 +413,22 @@ module Homebrew
             next
           end
 
-          url = GitHub.get_artifact_url(user, repo, pr, workflow_id: workflow, artifact_name: artifact)
-          download_artifact(url, dir, pr)
+          workflows.each do |workflow|
+            workflow_run = GitHub.get_workflow_run(
+              user, repo, pr, workflow_id: workflow, artifact_name: artifact
+            )
+            if args.ignore_missing_artifacts.present? &&
+               args.ignore_missing_artifacts.include?(workflow) &&
+               workflow_run.empty?
+              # Ignore that workflow as it was not executed and we specified
+              # that we could skip it.
+              next
+            end
+
+            ohai "Downloading bottles for workflow: #{workflow}"
+            url = GitHub.get_artifact_url(workflow_run)
+            download_artifact(url, dir, pr)
+          end
 
           next if args.no_upload?
 
diff --git a/Library/Homebrew/test/utils/github_spec.rb b/Library/Homebrew/test/utils/github_spec.rb
index 1949123d28..8704b8f6a5 100644
--- a/Library/Homebrew/test/utils/github_spec.rb
+++ b/Library/Homebrew/test/utils/github_spec.rb
@@ -61,18 +61,24 @@ describe GitHub do
   describe "::get_artifact_url", :needs_network do
     it "fails to find a nonexistant workflow" do
       expect {
-        subject.get_artifact_url("Homebrew", "homebrew-core", 1)
+        subject.get_artifact_url(
+          subject.get_workflow_run("Homebrew", "homebrew-core", 1),
+        )
       }.to raise_error(/No matching workflow run found/)
     end
 
     it "fails to find artifacts that don't exist" do
       expect {
-        subject.get_artifact_url("Homebrew", "homebrew-core", 51971, artifact_name: "false_bottles")
+        subject.get_artifact_url(
+          subject.get_workflow_run("Homebrew", "homebrew-core", 51971, artifact_name: "false_bottles"),
+        )
       }.to raise_error(/No artifact .+ was found/)
     end
 
     it "gets an artifact link" do
-      url = subject.get_artifact_url("Homebrew", "homebrew-core", 51971, artifact_name: "bottles")
+      url = subject.get_artifact_url(
+        subject.get_workflow_run("Homebrew", "homebrew-core", 51971, artifact_name: "bottles"),
+      )
       expect(url).to eq("https://api.github.com/repos/Homebrew/homebrew-core/actions/artifacts/3557392/zip")
     end
   end
diff --git a/Library/Homebrew/utils/github.rb b/Library/Homebrew/utils/github.rb
index a235b77d74..3c2ada9ba8 100644
--- a/Library/Homebrew/utils/github.rb
+++ b/Library/Homebrew/utils/github.rb
@@ -510,7 +510,7 @@ module GitHub
     open_api(url, data_binary_path: local_file, request_method: :POST, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES)
   end
 
-  def get_artifact_url(user, repo, pr, workflow_id: "tests.yml", artifact_name: "bottles")
+  def get_workflow_run(user, repo, pr, workflow_id: "tests.yml", artifact_name: "bottles")
     scopes = CREATE_ISSUE_FORK_OR_PR_SCOPES
     base_url = "#{API_URL}/repos/#{user}/#{repo}"
     pr_payload = open_api("#{base_url}/pulls/#{pr}", scopes: scopes)
@@ -523,6 +523,11 @@ module GitHub
       run["head_sha"] == pr_sha
     end
 
+    [workflow_run, pr_sha, pr_branch, pr, workflow_id, scopes, artifact_name]
+  end
+
+  def get_artifact_url(workflow_array)
+    workflow_run, pr_sha, pr_branch, pr, workflow_id, scopes, artifact_name = *workflow_array
     if workflow_run.empty?
       raise Error, <<~EOS
         No matching workflow run found for these criteria!
diff --git a/docs/Manpage.md b/docs/Manpage.md
index 586a1639b7..014d4413dd 100644
--- a/docs/Manpage.md
+++ b/docs/Manpage.md
@@ -1158,7 +1158,7 @@ Requires write access to the repository.
 * `--message`:
   Message to include when autosquashing revision bumps, deletions, and rebuilds.
 * `--workflow`:
-  Retrieve artifacts from the specified workflow (default: `tests.yml`).
+  Retrieve artifacts from the specified workflow (default: `tests.yml`). Legacy: use --workflows instead
 * `--artifact`:
   Download artifacts with the specified name (default: `bottles`).
 * `--bintray-org`:
@@ -1169,6 +1169,10 @@ Requires write access to the repository.
   Use the specified *`URL`* as the root of the bottle's URL instead of Homebrew's default.
 * `--bintray-mirror`:
   Use the specified Bintray repository to automatically mirror stable URLs defined in the formulae (default: `mirror`).
+* `--workflows`:
+  Retrieve artifacts from the specified workflow (default: `tests.yml`) Comma-separated list to include multiple workflows.
+* `--ignore-missing-artifacts`:
+  Comma-separated list of workflows which can be ignored if they have not been run.
 
 ### `pr-upload` [*`options`*]
 
diff --git a/manpages/brew.1 b/manpages/brew.1
index 0b237b463f..8fa25bf1ae 100644
--- a/manpages/brew.1
+++ b/manpages/brew.1
@@ -1618,7 +1618,7 @@ Message to include when autosquashing revision bumps, deletions, and rebuilds\.
 .
 .TP
 \fB\-\-workflow\fR
-Retrieve artifacts from the specified workflow (default: \fBtests\.yml\fR)\.
+Retrieve artifacts from the specified workflow (default: \fBtests\.yml\fR)\. Legacy: use \-\-workflows instead
 .
 .TP
 \fB\-\-artifact\fR
@@ -1640,6 +1640,14 @@ Use the specified \fIURL\fR as the root of the bottle\'s URL instead of Homebrew
 \fB\-\-bintray\-mirror\fR
 Use the specified Bintray repository to automatically mirror stable URLs defined in the formulae (default: \fBmirror\fR)\.
 .
+.TP
+\fB\-\-workflows\fR
+Retrieve artifacts from the specified workflow (default: \fBtests\.yml\fR) Comma\-separated list to include multiple workflows\.
+.
+.TP
+\fB\-\-ignore\-missing\-artifacts\fR
+Comma\-separated list of workflows which can be ignored if they have not been run\.
+.
 .SS "\fBpr\-upload\fR [\fIoptions\fR]"
 Apply the bottle commit and publish bottles to Bintray or GitHub Releases\.
 .
-- 
GitLab