Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update-sponsors: don't require admin token. #13820

Merged
merged 2 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Update maintainers, manpage and completions
name: Update sponsors, maintainers, manpage and completions

on:
push:
paths:
- .github/workflows/maintainers-man-completions.yml
- .github/workflows/sponsors-maintainers-man-completions.yml
- README.md
- Library/Homebrew/cmd/**
- Library/Homebrew/dev-cmd/**
Expand Down Expand Up @@ -54,7 +54,7 @@ jobs:
then
BRANCH="$GITHUB_REF_NAME"
else
BRANCH=maintainers-man-completions
BRANCH=sponsors-maintainers-man-completions
fi
echo "::set-output name=branch::${BRANCH}"

Expand All @@ -69,13 +69,21 @@ jobs:
git checkout --no-track -B "${BRANCH}" origin/master
fi

if brew sponsors
then
git add "${GITHUB_WORKSPACE}/README.md"
git commit -m "Update sponsors." \
-m "Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow."
COMMITTED=true
fi

if brew update-maintainers
then
git add "${GITHUB_WORKSPACE}/README.md" \
"${GITHUB_WORKSPACE}/docs/Manpage.md" \
"${GITHUB_WORKSPACE}/manpages/brew.1"
git commit -m "Update maintainers." \
-m "Autogenerated by the [update-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/maintainers-man-completions.yml) workflow."
-m "Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow."
COMMITTED=true
fi

Expand All @@ -86,7 +94,7 @@ jobs:
"${GITHUB_WORKSPACE}/manpages/brew.1" \
"${GITHUB_WORKSPACE}/completions"
git commit -m "Update manpage and completions." \
-m "Autogenerated by the [update-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/maintainers-man-completions.yml) workflow."
-m "Autogenerated by the [sponsors-maintainers-man-completions](https://github.com/Homebrew/brew/blob/HEAD/.github/workflows/sponsors-maintainers-man-completions.yml) workflow."
COMMITTED=true
fi

Expand Down
31 changes: 13 additions & 18 deletions Library/Homebrew/dev-cmd/update-sponsors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ module Homebrew

module_function

NAMED_TIER_AMOUNT = 100
URL_TIER_AMOUNT = 1000
NAMED_MONTHLY_AMOUNT = 100
URL_MONTHLY_AMOUNT = 1000

sig { returns(CLI::Parser) }
def update_sponsors_args
Expand All @@ -23,16 +23,16 @@ def update_sponsors_args
end
end

def sponsor_name(s)
s["name"] || s["login"]
def sponsor_name(sponsor)
sponsor[:name] || sponsor[:login]
end

def sponsor_logo(s)
"https://github.com/#{s["login"]}.png?size=64"
def sponsor_logo(sponsor)
"https://github.com/#{sponsor[:login]}.png?size=64"
end

def sponsor_url(s)
"https://github.com/#{s["login"]}"
def sponsor_url(sponsor)
"https://github.com/#{sponsor[:login]}"
end

def update_sponsors
Expand All @@ -41,18 +41,13 @@ def update_sponsors
named_sponsors = []
logo_sponsors = []

GitHub.sponsors_by_tier("Homebrew").each do |tier|
if tier["tier"] >= NAMED_TIER_AMOUNT
named_sponsors += tier["sponsors"].map do |s|
"[#{sponsor_name(s)}](#{sponsor_url(s)})"
end
end
GitHub.sponsorships("Homebrew").each do |s|
largest_monthly_amount = [s[:monthly_amount], s[:closest_tier_monthly_amount]].compact.max
named_sponsors << "[#{sponsor_name(s)}](#{sponsor_url(s)})" if largest_monthly_amount >= NAMED_MONTHLY_AMOUNT

next if tier["tier"] < URL_TIER_AMOUNT
next if largest_monthly_amount < URL_MONTHLY_AMOUNT

logo_sponsors += tier["sponsors"].map do |s|
"[![#{sponsor_name(s)}](#{sponsor_logo(s)})](#{sponsor_url(s)})"
end
logo_sponsors << "[![#{sponsor_name(s)}](#{sponsor_logo(s)})](#{sponsor_url(s)})"
end

named_sponsors << "many other users and organisations via [GitHub Sponsors](https://github.com/sponsors/Homebrew)"
Expand Down
8 changes: 0 additions & 8 deletions Library/Homebrew/test/utils/github_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,6 @@
end
end

describe "::sponsors_by_tier", :needs_network do
it "errors on an unauthenticated token" do
expect {
described_class.sponsors_by_tier("Homebrew")
}.to raise_error(/INSUFFICIENT_SCOPES|FORBIDDEN|token needs the 'admin:org' scope/)
end
end

describe "::get_artifact_url", :needs_network do
it "fails to find a nonexistent workflow" do
expect {
Expand Down
94 changes: 55 additions & 39 deletions Library/Homebrew/utils/github.rb
Original file line number Diff line number Diff line change
Expand Up @@ -403,59 +403,75 @@ def members_by_team(org, team)
result["organization"]["team"]["members"]["nodes"].to_h { |member| [member["login"], member["name"]] }
end

def sponsors_by_tier(user)
query = <<~EOS
{ organization(login: "#{user}") {
sponsorsListing {
tiers(first: 10, orderBy: {field: MONTHLY_PRICE_IN_CENTS, direction: DESC}) {
def sponsorships(user)
has_next_page = true
after = ""
sponsorships = []
errors = []
while has_next_page
query = <<~EOS
{ organization(login: "#{user}") {
sponsorshipsAsMaintainer(first: 100 #{after}) {
pageInfo {
startCursor
hasNextPage
endCursor
}
totalCount
nodes {
monthlyPriceInDollars
adminInfo {
sponsorships(first: 100, includePrivate: true) {
totalCount
nodes {
privacyLevel
sponsorEntity {
__typename
... on Organization { login name }
... on User { login name }
}
}
tier {
monthlyPriceInDollars
closestLesserValueTier {
monthlyPriceInDollars
}
}
sponsorEntity {
__typename
... on Organization { login name }
... on User { login name }
}
}
}
}
}
}
EOS
result = API.open_graphql(query, scopes: ["admin:org", "user"])
EOS
# Some organisations do not permit themselves to be queried through the
# API like this and raise an error so handle these errors later.
# This has been reported to GitHub.
result = API.open_graphql(query, scopes: ["user"], raise_errors: false)
errors += result["errors"] if result["errors"].present?

tiers = result["organization"]["sponsorsListing"]["tiers"]["nodes"]
current_sponsorships = result["data"]["organization"]["sponsorshipsAsMaintainer"]

tiers.map do |t|
tier = t["monthlyPriceInDollars"]
raise API::Error, "Your token needs the 'admin:org' scope to access this API" if t["adminInfo"].nil?
# The organisations mentioned above will show up as nil nodes.
sponsorships += current_sponsorships["nodes"].compact

sponsorships = t["adminInfo"]["sponsorships"]
count = sponsorships["totalCount"]
sponsors = sponsorships["nodes"].map do |sponsor|
next unless sponsor["privacyLevel"] == "PUBLIC"
if (page_info = current_sponsorships["pageInfo"].presence) &&
page_info["hasNextPage"].presence
after = %Q(, after: "#{page_info["endCursor"]}")
else
has_next_page = false
end
end

se = sponsor["sponsorEntity"]
{
"name" => se["name"].presence || sponsor["login"],
"login" => se["login"],
"type" => se["__typename"].downcase,
}
end.compact
# Only raise errors if we didn't get any sponsorships.
if sponsorships.blank? && errors.present?
raise API::Error, errors.map { |e| "#{e["type"]}: #{e["message"]}" }.join("\n")
end

sponsorships.map do |sponsorship|
closest_tier_monthly_amount = sponsorship["tier"].fetch("closestLesserValueTier", nil)
&.fetch("monthlyPriceInDollars", nil)
monthly_amount = sponsorship["tier"]["monthlyPriceInDollars"]
sponsor = sponsorship["sponsorEntity"]

{
"tier" => tier,
"count" => count,
"sponsors" => sponsors,
name: sponsor["name"].presence || sponsor["login"],
login: sponsor["login"],
monthly_amount: monthly_amount,
closest_tier_monthly_amount: closest_tier_monthly_amount || 0,
}
end.compact
end
end

def get_repo_license(user, repo)
Expand Down
16 changes: 9 additions & 7 deletions Library/Homebrew/utils/github/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,17 +252,19 @@ def paginate_rest(url, per_page: 100)
end
end

def open_graphql(query, variables: nil, scopes: [].freeze)
def open_graphql(query, variables: nil, scopes: [].freeze, raise_errors: true)
data = { query: query, variables: variables }
result = open_rest("#{API_URL}/graphql", scopes: scopes, data: data, request_method: "POST")

if result["errors"].present?
raise Error, result["errors"].map { |e|
"#{e["type"]}: #{e["message"]}"
}.join("\n")
end
if raise_errors
if result["errors"].present?
raise Error, result["errors"].map { |e| "#{e["type"]}: #{e["message"]}" }.join("\n")
end

result["data"]
result["data"]
else
result
end
end

def raise_error(output, errors, http_code, headers, scopes)
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,6 @@ Flaky test detection and tracking is provided by [BuildPulse](https://buildpulse
[![DNSimple](https://cdn.dnsimple.com/assets/resolving-with-us/logo-light.png)](https://dnsimple.com/resolving/homebrew#gh-light-mode-only)
[![DNSimple](https://cdn.dnsimple.com/assets/resolving-with-us/logo-dark.png)](https://dnsimple.com/resolving/homebrew#gh-dark-mode-only)

Homebrew is generously supported by [Randy Reddig](https://github.com/ydnar), [Codecademy](https://github.com/Codecademy), [Appwrite](https://github.com/appwrite), [embark-studios](https://github.com/embark-studios) and many other users and organisations via [GitHub Sponsors](https://github.com/sponsors/Homebrew).
Homebrew is generously supported by [GitHub](https://github.com/github), [Custom Ink](https://github.com/customink), [Randy Reddig](https://github.com/ydnar), [Christian (Xian) M. Lilley](https://github.com/xml), [David Fernandez](https://github.com/lidstromberg), [embark-studios](https://github.com/embark-studios) and many other users and organisations via [GitHub Sponsors](https://github.com/sponsors/Homebrew).

[![GitHub](https://github.com/github.png?size=64)](https://github.com/github)