Merge pull request #17097 from ZhongRuoyu/artifact-actions-v4

pr-pull: support globbing artifacts
This commit is contained in:
Ruoyu Zhong 2024-04-18 00:58:44 +08:00 committed by GitHub
commit 84d731888e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 46 additions and 32 deletions

View File

@ -55,8 +55,8 @@ module Homebrew
flag "--message=",
depends_on: "--autosquash",
description: "Message to include when autosquashing revision bumps, deletions and rebuilds."
flag "--artifact=",
description: "Download artifacts with the specified name (default: `bottles`)."
flag "--artifact-pattern=", "--artifact=",
description: "Download artifacts with the specified pattern (default: `bottles{,_*}`)."
flag "--tap=",
description: "Target tap repository (default: `homebrew/core`)."
flag "--root-url=",
@ -81,7 +81,7 @@ module Homebrew
ensure_executable!("unzip", reason: "extracting CI artifacts")
workflows = args.workflows.presence || ["tests.yml"]
artifact = args.artifact || "bottles"
artifact_pattern = args.artifact_pattern || "bottles{,_*}"
tap = Tap.fetch(args.tap || CoreTap.instance.name)
raise TapUnavailableError, tap.name unless tap.installed?
@ -143,7 +143,7 @@ module Homebrew
workflows.each do |workflow|
workflow_run = GitHub.get_workflow_run(
user, repo, pr, workflow_id: workflow, artifact_name: artifact
user, repo, pr, workflow_id: workflow, artifact_pattern:
)
if args.ignore_missing_artifacts.present? &&
T.must(args.ignore_missing_artifacts).include?(workflow) &&
@ -155,8 +155,9 @@ module Homebrew
end
ohai "Downloading bottles for workflow: #{workflow}"
url = GitHub.get_artifact_url(workflow_run)
GitHub.download_artifact(url, pr)
urls = GitHub.get_artifact_urls(workflow_run)
urls.each { |url| GitHub.download_artifact(url, pr) }
end
next if args.no_upload?

View File

@ -8,6 +8,9 @@ class Homebrew::CLI::Args
sig { returns(T.nilable(String)) }
def artifact; end
sig { returns(T.nilable(String)) }
def artifact_pattern; end
sig { returns(T::Boolean) }
def autosquash?; end

View File

@ -46,10 +46,10 @@ RSpec.describe GitHub do
end
end
describe "::get_artifact_url", :needs_network do
describe "::get_artifact_urls", :needs_network do
it "fails to find a nonexistent workflow" do
expect do
described_class.get_artifact_url(
described_class.get_artifact_urls(
described_class.get_workflow_run("Homebrew", "homebrew-core", "1"),
)
end.to raise_error(/No matching check suite found/)
@ -57,19 +57,27 @@ RSpec.describe GitHub do
it "fails to find artifacts that don't exist" do
expect do
described_class.get_artifact_url(
described_class.get_artifact_urls(
described_class.get_workflow_run("Homebrew", "homebrew-core", "135608",
workflow_id: "triage.yml", artifact_name: "false_artifact"),
workflow_id: "triage.yml", artifact_pattern: "false_artifact"),
)
end.to raise_error(/No artifact .+ was found/)
end.to raise_error(/No artifacts with the pattern .+ were found/)
end
it "gets an artifact link" do
url = described_class.get_artifact_url(
it "gets artifact URLs" do
urls = described_class.get_artifact_urls(
described_class.get_workflow_run("Homebrew", "homebrew-core", "135608",
workflow_id: "triage.yml", artifact_name: "event_payload"),
workflow_id: "triage.yml", artifact_pattern: "event_payload"),
)
expect(url).to eq("https://api.github.com/repos/Homebrew/homebrew-core/actions/artifacts/781984175/zip")
expect(urls).to eq(["https://api.github.com/repos/Homebrew/homebrew-core/actions/artifacts/781984175/zip"])
end
it "supports pattern matching" do
urls = described_class.get_artifact_urls(
described_class.get_workflow_run("Homebrew", "brew", "17068",
workflow_id: "pkg-installer.yml", artifact_pattern: "Homebrew-*.pkg"),
)
expect(urls).to eq(["https://api.github.com/repos/Homebrew/brew/actions/artifacts/1405050842/zip"])
end
end

View File

@ -283,7 +283,7 @@ module GitHub
API.open_rest(url, data_binary_path: local_file, request_method: :POST, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES)
end
def self.get_workflow_run(user, repo, pull_request, workflow_id: "tests.yml", artifact_name: "bottles")
def self.get_workflow_run(user, repo, pull_request, workflow_id: "tests.yml", artifact_pattern: "bottles{,_*}")
scopes = CREATE_ISSUE_FORK_OR_PR_SCOPES
# GraphQL unfortunately has no way to get the workflow yml name, so we need an extra REST call.
@ -333,11 +333,11 @@ module GitHub
[]
end
[check_suite, user, repo, pull_request, workflow_id, scopes, artifact_name]
[check_suite, user, repo, pull_request, workflow_id, scopes, artifact_pattern]
end
def self.get_artifact_url(workflow_array)
check_suite, user, repo, pr, workflow_id, scopes, artifact_name = *workflow_array
def self.get_artifact_urls(workflow_array)
check_suite, user, repo, pr, workflow_id, scopes, artifact_pattern = *workflow_array
if check_suite.empty?
raise API::Error, <<~EOS
No matching check suite found for these criteria!
@ -357,18 +357,20 @@ module GitHub
run_id = check_suite.last["workflowRun"]["databaseId"]
artifacts = API.open_rest("#{API_URL}/repos/#{user}/#{repo}/actions/runs/#{run_id}/artifacts", scopes:)
artifact = artifacts["artifacts"].select do |art|
art["name"] == artifact_name
end
matching_artifacts =
artifacts["artifacts"]
.group_by { |art| art["name"] }
.select { |name| File.fnmatch?(artifact_pattern, name, File::FNM_EXTGLOB) }
.map { |_, arts| arts.last }
if artifact.empty?
if matching_artifacts.empty?
raise API::Error, <<~EOS
No artifact with the name `#{artifact_name}` was found!
No artifacts with the pattern `#{artifact_pattern}` were found!
#{Formatter.url check_suite.last["workflowRun"]["url"]}
EOS
end
artifact.last["archive_download_url"]
matching_artifacts.map { |art| art["archive_download_url"] }
end
def self.public_member_usernames(org, per_page: 100)

View File

@ -1760,7 +1760,7 @@ _brew_pr_pull() {
case "${cur}" in
-*)
__brewcomp "
--artifact
--artifact-pattern
--autosquash
--branch-okay
--clean

View File

@ -1191,7 +1191,7 @@ __fish_brew_complete_arg 'pr-publish' -l workflow -d 'Target workflow filename (
__fish_brew_complete_cmd 'pr-pull' 'Download and publish bottles, and apply the bottle commit from a pull request with artifacts generated by GitHub Actions'
__fish_brew_complete_arg 'pr-pull' -l artifact -d 'Download artifacts with the specified name (default: `bottles`)'
__fish_brew_complete_arg 'pr-pull' -l artifact-pattern -d 'Download artifacts with the specified pattern (default: `bottles{,_*}`)'
__fish_brew_complete_arg 'pr-pull' -l autosquash -d 'Automatically reformat and reword commits in the pull request to our preferred format'
__fish_brew_complete_arg 'pr-pull' -l branch-okay -d 'Do not warn if pulling to a branch besides the repository default (useful for testing)'
__fish_brew_complete_arg 'pr-pull' -l clean -d 'Do not amend the commits from pull requests'

View File

@ -1482,7 +1482,7 @@ _brew_pr_publish() {
# brew pr-pull
_brew_pr_pull() {
_arguments \
'--artifact[Download artifacts with the specified name (default: `bottles`)]' \
'--artifact-pattern[Download artifacts with the specified pattern (default: `bottles{,_*}`)]' \
'(--clean)--autosquash[Automatically reformat and reword commits in the pull request to our preferred format]' \
'--branch-okay[Do not warn if pulling to a branch besides the repository default (useful for testing)]' \
'(--autosquash)--clean[Do not amend the commits from pull requests]' \

View File

@ -2423,9 +2423,9 @@ repository.
: Message to include when autosquashing revision bumps, deletions and rebuilds.
`--artifact`
`--artifact-pattern`
: Download artifacts with the specified name (default: `bottles`).
: Download artifacts with the specified pattern (default: `bottles{,_*}`).
`--tap`

View File

@ -1543,8 +1543,8 @@ Specify a committer name and email in \fBgit\fP\[u2019]s standard author format\
\fB\-\-message\fP
Message to include when autosquashing revision bumps, deletions and rebuilds\.
.TP
\fB\-\-artifact\fP
Download artifacts with the specified name (default: \fBbottles\fP)\.
\fB\-\-artifact\-pattern\fP
Download artifacts with the specified pattern (default: \fBbottles{,_*}\fP)\.
.TP
\fB\-\-tap\fP
Target tap repository (default: \fBhomebrew/core\fP)\.