From deda28e5aded2817bcc7956f377378576372816f Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Mon, 31 May 2021 23:14:54 +0100 Subject: [PATCH] feat(github): perform authenticated GitHub API requests when GITHUB_TOKEN env var is set This should let people on shared connections use the script if they have a GitHub Personal Access Token available in the GITHUB_TOKEN environment variable. When making unauthenticated API requests to GitHub, requests are rate limited to 60 requests per hour based on source IP address. Hence on shared connections the rate limit may easily be exceeded. When making authenticated API requests to GitHub, up to 5000 requests per hour is allowed, based on the authenticated user rather than source IP address. --- README.md | 1 + build-emacs-for-macos | 50 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 200cf16..eadb3bd 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ Options: --[no-]rsvg Enable/disable SVG image support via librsvg (default: enabled) --no-titlebar Apply no-titlebar patch (default: disabled) --no-frame-refocus Apply no-frame-refocus patch (default: disabled) + --[no-]github-auth Make authenticated GitHub API requests if GITHUB_TOKEN environment variable is set.(default: enabled) --work-dir DIR Specify a working directory where tarballs, sources, and builds will be stored and worked with --plan FILE Follow given plan file, instead of using given git ref/sha ``` diff --git a/build-emacs-for-macos b/build-emacs-for-macos index 5ddd271..3ca9a3a 100755 --- a/build-emacs-for-macos +++ b/build-emacs-for-macos @@ -71,9 +71,8 @@ end class Build include Output - DOWNLOAD_URL = 'https://github.com/emacs-mirror/emacs/tarball/%s' - LATEST_URL = 'https://api.github.com/repos/emacs-mirror/emacs/commits/%s' - NATIVE_COMP_REF_REGEXP = %r{^feature/native-comp}.freeze + EMACS_MIRROR_REPO = 'emacs-mirror/emacs' + DOWNLOAD_URL = 'https://api.github.com/repos/emacs-mirror/emacs/tarball/%s' attr_reader :root_dir attr_reader :source_dir @@ -162,8 +161,20 @@ class Build info 'Downloading tarball from GitHub. This could take a while, ' \ 'please be patient.' - result = run_cmd('curl', '-L', url, '-o', target) - err 'Download failed.' unless result + + args = ['curl', '-L', url, '-o', target] + log_args = args.clone + + if options[:github_auth] && ENV['GITHUB_TOKEN'] + args = [args[0]] + + ['-H', "Authorization: Token #{ENV['GITHUB_TOKEN']}"] + args[1..-1] + log_args = [log_args[0]] + + ['-H', '"Authorization: Token $GITHUB_TOKEN"'] + + log_args[1..-1] + end + + out "CMD: #{log_args.join(' ')}" + system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}") target end @@ -442,8 +453,9 @@ class Build ref_sha = options[:git_sha] || ref info "Fetching info for git ref: #{ref_sha}" - url = format(LATEST_URL, ref_sha) - commit_json = http_get(url) + commit_json = github_api_get( + "/repos/#{EMACS_MIRROR_REPO}/commits/#{ref_sha}" + ) err "Failed to get commit info about: #{ref_sha}" if commit_json.nil? commit = JSON.parse(commit_json) @@ -456,8 +468,18 @@ class Build @meta = meta end - def http_get(url) - response = Net::HTTP.get_response(URI.parse(url)) + def github_api_get(uri) + uri = URI.join('https://api.github.com/', uri) + + http = Net::HTTP.new(uri.hostname, uri.port) + http.use_ssl = true if uri.scheme == 'https' + + request = Net::HTTP::Get.new(uri) + if options[:github_auth] && ENV['GITHUB_TOKEN'] + request['Authorization'] = "Token #{ENV['GITHUB_TOKEN']}" + end + + response = http.request(request) return unless response.code == '200' response.body @@ -860,7 +882,8 @@ if __FILE__ == $PROGRAM_NAME native_full_aot: false, parallel: Etc.nprocessors, rsvg: true, - xwidgets: true + xwidgets: true, + github_auth: true } begin @@ -919,6 +942,13 @@ if __FILE__ == $PROGRAM_NAME cli_options[:no_frame_refocus] = true end + opts.on('--[no-]github-auth', + 'Make authenticated GitHub API requests if GITHUB_TOKEN ' \ + 'environment variable is set.' \ + '(default: enabled)') do |v| + cli_options[:github_auth] = v + end + opts.on('--work-dir DIR', 'Specify a working directory where tarballs, sources, and ' \ 'builds will be stored and worked with') do |v|