github_packages: improve upload error handling

Erroring out in the middle of uploading multiple bottles results in a
state that is tedious to recover from.

Let's try to avoid these situations by performing checks for all the
bottles first before trying to upload any.
This commit is contained in:
Carlo Cabrera 2023-05-03 16:16:32 +08:00
parent e62a839001
commit 31a152208b
No known key found for this signature in database
GPG Key ID: C74D447FC549A1D0

View File

@ -57,9 +57,20 @@ class GitHubPackages
load_schemas! load_schemas!
bottles_hash.each do |formula_full_name, bottle_hash| bottles_hash.each do |formula_full_name, bottle_hash|
# First, check that we won't encounter an error in the middle of uploading bottles.
preupload_check(user, token, skopeo, formula_full_name, bottle_hash,
keep_old: keep_old, dry_run: dry_run, warn_on_error: warn_on_error)
end
# We intentionally iterate over `bottles_hash` twice to
# avoid erroring out in the middle of uploading bottles.
# rubocop:disable Style/CombinableLoops
bottles_hash.each do |formula_full_name, bottle_hash|
# Next, upload the bottles after checking them all.
upload_bottle(user, token, skopeo, formula_full_name, bottle_hash, upload_bottle(user, token, skopeo, formula_full_name, bottle_hash,
keep_old: keep_old, dry_run: dry_run, warn_on_error: warn_on_error) keep_old: keep_old, dry_run: dry_run, warn_on_error: warn_on_error)
end end
# rubocop:enable Style/CombinableLoops
end end
def self.version_rebuild(version, rebuild, bottle_tag = nil) def self.version_rebuild(version, rebuild, bottle_tag = nil)
@ -191,7 +202,7 @@ class GitHubPackages
end end
end end
def upload_bottle(user, token, skopeo, formula_full_name, bottle_hash, keep_old:, dry_run:, warn_on_error:) def preupload_check(user, token, skopeo, _formula_full_name, bottle_hash, keep_old:, dry_run:, warn_on_error:)
formula_name = bottle_hash["formula"]["name"] formula_name = bottle_hash["formula"]["name"]
_, org, repo, = *bottle_hash["bottle"]["root_url"].match(URL_REGEX) _, org, repo, = *bottle_hash["bottle"]["root_url"].match(URL_REGEX)
@ -237,6 +248,16 @@ class GitHubPackages
end end
end end
[formula_name, org, repo, version, rebuild, version_rebuild, image_name, image_uri, keep_old]
end
def upload_bottle(user, token, skopeo, formula_full_name, bottle_hash, keep_old:, dry_run:, warn_on_error:)
# We run the preupload check twice to prevent TOCTOU bugs.
result = preupload_check(user, token, skopeo, formula_full_name, bottle_hash,
keep_old: keep_old, dry_run: dry_run, warn_on_error: warn_on_error)
formula_name, org, repo, version, rebuild, version_rebuild, image_name, image_uri, keep_old = *result
root = Pathname("#{formula_name}--#{version_rebuild}") root = Pathname("#{formula_name}--#{version_rebuild}")
FileUtils.rm_rf root FileUtils.rm_rf root
root.mkpath root.mkpath