Skip to content

Commit

Permalink
cmd/gist-logs: On 404, the PAT probably needs more permissions
Browse files Browse the repository at this point in the history
- This 404 error is from GitHub, and GitHub doesn't give us any more
  informations about scopes for the gist endpoint (for some reason). But we can
  safely assume, as it happens a lot, that "Error: Not Found" (404) is because
  the user hasn't granted their `HOMEBREW_GITHUB_API_TOKEN` the `gist` scope.

Before:

```shell
$ HOMEBREW_GITHUB_API_TOKEN=<token_without_gist_scope> brew gist-logs -p logrotate
Error: Not Found
```

After:

```shell
❯ HOMEBREW_GITHUB_API_TOKEN=<token_without_gist_scope> brew gist-logs logrotate
Error: Your GitHub API token likely doesn't have the `gist` scope.
Create a GitHub personal access token:
https://github.com/settings/tokens/new?scopes=gist&description=Homebrew
echo 'export HOMEBREW_GITHUB_API_TOKEN=your_token_here' >> ~/.zshrc
```
  • Loading branch information
issyl0 committed Feb 6, 2023
1 parent 39e158f commit e6a2ce1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
10 changes: 9 additions & 1 deletion Library/Homebrew/cmd/gist-logs.rb
Expand Up @@ -63,7 +63,15 @@ def gistify_logs(f, args:)
else
"#{f.name} (#{f.full_name}) on #{OS_VERSION} - Homebrew build logs"
end
url = GitHub.create_gist(files, descr, private: args.private?)

begin
url = GitHub.create_gist(files, descr, private: args.private?)
rescue GitHub::API::HTTPNotFoundError
odie <<~EOS
Your GitHub API token likely doesn't have the `gist` scope.
#{GitHub.pat_blurb(GitHub::CREATE_GIST_SCOPES)}
EOS
end

url = GitHub.create_issue(f.tap, "#{f.name} failed to build on #{MacOS.full_version}", url) if args.new_issue?

Expand Down
25 changes: 14 additions & 11 deletions Library/Homebrew/utils/github/api.rb
Expand Up @@ -5,7 +5,18 @@
require "utils/shell"
require "utils/formatter"

# A module that interfaces with GitHub, code like PAT scopes, credential handling and API errors.
module GitHub
def self.pat_blurb(scopes)
<<~EOS
Create a GitHub personal access token:
#{Formatter.url(
"https://github.com/settings/tokens/new?scopes=#{scopes.join(",")}&description=Homebrew",
)}
#{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")}
EOS
end

API_URL = "https://api.github.com"
API_MAX_PAGES = 50
API_MAX_ITEMS = 5000
Expand All @@ -14,14 +25,6 @@ module GitHub
CREATE_ISSUE_FORK_OR_PR_SCOPES = ["repo"].freeze
CREATE_WORKFLOW_SCOPES = ["workflow"].freeze
ALL_SCOPES = (CREATE_GIST_SCOPES + CREATE_ISSUE_FORK_OR_PR_SCOPES + CREATE_WORKFLOW_SCOPES).freeze
ALL_SCOPES_URL = Formatter.url(
"https://github.com/settings/tokens/new?scopes=#{ALL_SCOPES.join(",")}&description=Homebrew",
).freeze
CREATE_GITHUB_PAT_MESSAGE = <<~EOS
Create a GitHub personal access token:
#{ALL_SCOPES_URL}
#{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")}
EOS
GITHUB_PERSONAL_ACCESS_TOKEN_REGEX = /^(?:[a-f0-9]{40}|gh[po]_\w{36,251})$/.freeze

# Helper functions to access the GitHub API.
Expand Down Expand Up @@ -49,7 +52,7 @@ def initialize(github_message)
class RateLimitExceededError < Error
def initialize(reset, github_message)
@github_message = github_message
new_pat_message = ", or:\n#{CREATE_GITHUB_PAT_MESSAGE}" if API.credentials.blank?
new_pat_message = ", or:\n#{pat_blurb}" if API.credentials.blank?
super <<~EOS
GitHub API Error: #{github_message}
Try again in #{pretty_ratelimit_reset(reset)}#{new_pat_message}
Expand Down Expand Up @@ -87,7 +90,7 @@ def initialize(github_message)
class MissingAuthenticationError < Error
def initialize
message = +"No GitHub credentials found in macOS Keychain or environment.\n"
message << CREATE_GITHUB_PAT_MESSAGE
message << pat_blurb
super message
end
end
Expand Down Expand Up @@ -177,7 +180,7 @@ def credentials_error_message(response_headers, needed_scopes)
Your #{what} credentials do not have sufficient scope!
Scopes required: #{needed_scopes}
Scopes present: #{credentials_scopes}
#{CREATE_GITHUB_PAT_MESSAGE}
#{pat_blurb}
EOS
end

Expand Down

0 comments on commit e6a2ce1

Please sign in to comment.