Support bottle uploads to GitHub Releases
Co-authored-by: Mike McQuaid <mike@mikemcquaid.com>
This commit is contained in:
parent
455965de80
commit
f6601cee10
@ -148,11 +148,7 @@ class Bintray
|
||||
end
|
||||
end
|
||||
|
||||
def upload_bottle_json(json_files, publish_package: false, warn_on_error: false)
|
||||
bottles_hash = json_files.reduce({}) do |hash, json_file|
|
||||
hash.deep_merge(JSON.parse(IO.read(json_file)))
|
||||
end
|
||||
|
||||
def upload_bottles(bottles_hash, publish_package: false, warn_on_error: false)
|
||||
formula_packaged = {}
|
||||
|
||||
bottles_hash.each do |formula_name, bottle_hash|
|
||||
|
||||
@ -11,7 +11,7 @@ module Homebrew
|
||||
usage_banner <<~EOS
|
||||
`pr-upload` [<options>]
|
||||
|
||||
Apply the bottle commit and publish bottles to Bintray.
|
||||
Apply the bottle commit and publish bottles to Bintray or GitHub Releases.
|
||||
EOS
|
||||
switch "--no-publish",
|
||||
description: "Apply the bottle commit and upload the bottles, but don't publish them."
|
||||
@ -30,30 +30,37 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def check_bottled_formulae(json_files)
|
||||
hashes = json_files.reduce({}) do |hash, json|
|
||||
hash.deep_merge(JSON.parse(IO.read(json)))
|
||||
end
|
||||
|
||||
hashes.each do |name, hash|
|
||||
formula_path = HOMEBREW_REPOSITORY/hash["formula"]["path"]
|
||||
def check_bottled_formulae(bottles_hash)
|
||||
bottles_hash.each do |name, bottle_hash|
|
||||
formula_path = HOMEBREW_REPOSITORY/bottle_hash["formula"]["path"]
|
||||
formula_version = Formulary.factory(formula_path).pkg_version
|
||||
bottle_version = PkgVersion.parse hash["formula"]["pkg_version"]
|
||||
bottle_version = PkgVersion.parse bottle_hash["formula"]["pkg_version"]
|
||||
next if formula_version == bottle_version
|
||||
|
||||
odie "Bottles are for #{name} #{bottle_version} but formula is version #{formula_version}!"
|
||||
end
|
||||
end
|
||||
|
||||
def github_releases?(bottles_hash)
|
||||
@github_releases ||= bottles_hash.values.all? do |bottle_hash|
|
||||
root_url = bottle_hash["bottle"]["root_url"]
|
||||
url_match = root_url.match HOMEBREW_RELEASES_URL_REGEX
|
||||
_, _, _, tag = *url_match
|
||||
|
||||
tag
|
||||
end
|
||||
end
|
||||
|
||||
def pr_upload
|
||||
args = pr_upload_args.parse
|
||||
|
||||
bintray_org = args.bintray_org || "homebrew"
|
||||
bintray = Bintray.new(org: bintray_org)
|
||||
|
||||
json_files = Dir["*.json"]
|
||||
odie "No JSON files found in the current working directory" if json_files.empty?
|
||||
|
||||
bottles_hash = json_files.reduce({}) do |hash, json_file|
|
||||
hash.deep_merge(JSON.parse(IO.read(json_file)))
|
||||
end
|
||||
|
||||
bottle_args = ["bottle", "--merge", "--write"]
|
||||
bottle_args << "--verbose" if args.verbose?
|
||||
bottle_args << "--debug" if args.debug?
|
||||
@ -62,14 +69,51 @@ module Homebrew
|
||||
bottle_args += json_files
|
||||
|
||||
if args.dry_run?
|
||||
service = if github_releases?(bottles_hash)
|
||||
"GitHub Releases"
|
||||
else
|
||||
"Bintray"
|
||||
end
|
||||
puts "brew #{bottle_args.join " "}"
|
||||
puts "Upload bottles described by these JSON files to Bintray:\n #{json_files.join("\n ")}"
|
||||
puts "Upload bottles described by these JSON files to #{service}:\n #{json_files.join("\n ")}"
|
||||
return
|
||||
end
|
||||
|
||||
check_bottled_formulae(bottles_hash)
|
||||
|
||||
safe_system HOMEBREW_BREW_FILE, *bottle_args
|
||||
|
||||
if github_releases?(bottles_hash)
|
||||
# Handle uploading to GitHub Releases.
|
||||
bottles_hash.each_value do |bottle_hash|
|
||||
root_url = bottle_hash["bottle"]["root_url"]
|
||||
url_match = root_url.match HOMEBREW_RELEASES_URL_REGEX
|
||||
_, user, repo, tag = *url_match
|
||||
|
||||
# Ensure a release is created.
|
||||
release = begin
|
||||
GitHub.get_release user, repo, tag
|
||||
odebug "Existing GitHub release \"#{tag}\" found"
|
||||
rescue GitHub::HTTPNotFoundError
|
||||
odebug "Creating new GitHub release \"#{tag}\""
|
||||
GitHub.create_or_update_release user, repo, tag
|
||||
end
|
||||
|
||||
# Upload bottles as release assets.
|
||||
bottle_hash["bottle"]["tags"].each_value do |tag_hash|
|
||||
remote_file = tag_hash["filename"]
|
||||
local_file = tag_hash["local_filename"]
|
||||
odebug "Uploading #{remote_file}"
|
||||
GitHub.upload_release_asset user, repo, release["id"], local_file: local_file, remote_file: remote_file
|
||||
end
|
||||
end
|
||||
else
|
||||
check_bottled_formulae(json_files)
|
||||
safe_system HOMEBREW_BREW_FILE, *bottle_args
|
||||
bintray.upload_bottle_json(json_files,
|
||||
publish_package: !args.no_publish?,
|
||||
warn_on_error: args.warn_on_upload_failure?)
|
||||
# Handle uploading to Bintray.
|
||||
bintray_org = args.bintray_org || "homebrew"
|
||||
bintray = Bintray.new(org: bintray_org)
|
||||
bintray.upload_bottles(bottles_hash,
|
||||
publish_package: !args.no_publish?,
|
||||
warn_on_error: args.warn_on_upload_failure?)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -112,6 +112,8 @@ HOMEBREW_PULL_API_REGEX =
|
||||
%r{https://api\.github\.com/repos/([\w-]+)/([\w-]+)?/pulls/(\d+)}.freeze
|
||||
HOMEBREW_PULL_OR_COMMIT_URL_REGEX =
|
||||
%r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})].freeze
|
||||
HOMEBREW_RELEASES_URL_REGEX =
|
||||
%r{https://github\.com/([\w-]+)/([\w-]+)?/releases/download/(.+)}.freeze
|
||||
|
||||
require "PATH"
|
||||
|
||||
|
||||
@ -175,7 +175,7 @@ module GitHub
|
||||
end
|
||||
end
|
||||
|
||||
def open_api(url, data: nil, request_method: nil, scopes: [].freeze, parse_json: true)
|
||||
def open_api(url, data: nil, data_binary_path: nil, request_method: nil, scopes: [].freeze, parse_json: true)
|
||||
# This is a no-op if the user is opting out of using the GitHub API.
|
||||
return block_given? ? yield({}) : {} if Homebrew::EnvConfig.no_github_api?
|
||||
|
||||
@ -200,6 +200,11 @@ module GitHub
|
||||
end
|
||||
end
|
||||
|
||||
if data_binary_path.present?
|
||||
args += ["--data-binary", "@#{data_binary_path}"]
|
||||
args += ["--header", "Content-Type: application/gzip"]
|
||||
end
|
||||
|
||||
headers_tmpfile = Tempfile.new("github_api_headers", HOMEBREW_TEMP)
|
||||
begin
|
||||
if data
|
||||
@ -467,6 +472,33 @@ module GitHub
|
||||
scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES)
|
||||
end
|
||||
|
||||
def get_release(user, repo, tag)
|
||||
url = "#{API_URL}/repos/#{user}/#{repo}/releases/tags/#{tag}"
|
||||
open_api(url, request_method: :GET)
|
||||
end
|
||||
|
||||
def create_or_update_release(user, repo, tag, id: nil, name: nil, draft: false)
|
||||
url = "#{API_URL}/repos/#{user}/#{repo}/releases"
|
||||
method = if id
|
||||
url += "/#{id}"
|
||||
:PATCH
|
||||
else
|
||||
:POST
|
||||
end
|
||||
data = {
|
||||
tag_name: tag,
|
||||
name: name || tag,
|
||||
draft: draft,
|
||||
}
|
||||
open_api(url, data: data, request_method: method, scopes: CREATE_ISSUE_FORK_OR_PR_SCOPES)
|
||||
end
|
||||
|
||||
def upload_release_asset(user, repo, id, local_file: nil, remote_file: nil)
|
||||
url = "https://uploads.github.com/repos/#{user}/#{repo}/releases/#{id}/assets"
|
||||
url += "?name=#{remote_file}" if remote_file
|
||||
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")
|
||||
scopes = CREATE_ISSUE_FORK_OR_PR_SCOPES
|
||||
base_url = "#{API_URL}/repos/#{user}/#{repo}"
|
||||
|
||||
@ -1113,7 +1113,7 @@ Requires write access to the repository.
|
||||
|
||||
### `pr-upload` [*`options`*]
|
||||
|
||||
Apply the bottle commit and publish bottles to Bintray.
|
||||
Apply the bottle commit and publish bottles to Bintray or GitHub Releases.
|
||||
|
||||
* `--no-publish`:
|
||||
Apply the bottle commit and upload the bottles, but don't publish them.
|
||||
|
||||
@ -1547,7 +1547,7 @@ Use the specified \fIURL\fR as the root of the bottle\'s URL instead of Homebrew
|
||||
Use the specified Bintray repository to automatically mirror stable URLs defined in the formulae (default: \fBmirror\fR)\.
|
||||
.
|
||||
.SS "\fBpr\-upload\fR [\fIoptions\fR]"
|
||||
Apply the bottle commit and publish bottles to Bintray\.
|
||||
Apply the bottle commit and publish bottles to Bintray or GitHub Releases\.
|
||||
.
|
||||
.TP
|
||||
\fB\-\-no\-publish\fR
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user