|
| 1 | +require 'sinatra' |
| 2 | +require 'json' |
| 3 | +require 'rest-client' |
| 4 | + |
| 5 | +$github_api_token = ENV['GITHUB_API_TOKEN'] |
| 6 | +$github_secret_token = ENV['SECRET_TOKEN'] |
| 7 | + |
| 8 | +post '/payload' do |
| 9 | + |
| 10 | + # Only validate secret token if set |
| 11 | + if !$github_secret_token.nil? |
| 12 | + payload_body = request.body.read |
| 13 | + verify_signature(payload_body) |
| 14 | + end |
| 15 | + |
| 16 | + github_event = request.env['HTTP_X_GITHUB_EVENT'] |
| 17 | + if github_event == "push" |
| 18 | + request.body.rewind |
| 19 | + parsed = JSON.parse(request.body.read) |
| 20 | + |
| 21 | + # Get branch information |
| 22 | + branch_name = parsed['ref'] |
| 23 | + removed_slice = branch_name.slice!("refs/heads/") |
| 24 | + if removed_slice.nil? |
| 25 | + return "Not a branch. Nothing to do." |
| 26 | + end |
| 27 | + |
| 28 | + # Get Repository owner |
| 29 | + repo_owner = parsed["repository"]["owner"]["name"] |
| 30 | + |
| 31 | + # Create URL to look up Pull Requests for this branch |
| 32 | + # e.g. https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number} |
| 33 | + pulls_url = parsed['repository']['pulls_url'] |
| 34 | + |
| 35 | + # Pull off the "{/number}" and search for all Pull Requests |
| 36 | + # that include the branch |
| 37 | + pulls_url_filtered = pulls_url.split('{').first + "?head=#{repo_owner}:#{branch_name}" |
| 38 | + pulls = get(pulls_url_filtered) |
| 39 | + |
| 40 | + # parse pull requests |
| 41 | + if pulls.empty? |
| 42 | + puts "empty" |
| 43 | + else |
| 44 | + pulls.each do |pull_request| |
| 45 | + |
| 46 | + # Get all Reviews for a Pull Request via API |
| 47 | + review_url_orig = pull_request["url"] + "/reviews" |
| 48 | + reviews = get(review_url_orig) |
| 49 | + |
| 50 | + reviews.each do |review| |
| 51 | + |
| 52 | + # Dismiss all Reviews in 'APPROVED' state via API |
| 53 | + if review["state"] == "APPROVED" |
| 54 | + puts "INFO: found an approved Review" |
| 55 | + review_id = review["id"] |
| 56 | + dismiss_url = review_url_orig + "/#{review_id}/dismissals" |
| 57 | + put(dismiss_url) |
| 58 | + end |
| 59 | + end.empty? and begin |
| 60 | + puts "no reviews" |
| 61 | + end |
| 62 | + end |
| 63 | + end |
| 64 | + elsif github_event == "ping" |
| 65 | + puts github_event |
| 66 | + else |
| 67 | + puts github_event |
| 68 | + end |
| 69 | + "message received" |
| 70 | +end |
| 71 | + |
| 72 | +def put(url) |
| 73 | + jdata = JSON.generate({ message: "Auto-dismissing"}) |
| 74 | + headers = { |
| 75 | + params: |
| 76 | + { |
| 77 | + access_token: $github_api_token |
| 78 | + }, |
| 79 | + accept: "application/vnd.github.black-cat-preview+json" |
| 80 | + } |
| 81 | + response = RestClient.put(url, jdata, headers) |
| 82 | + JSON.parse(response.body) |
| 83 | +end |
| 84 | + |
| 85 | +def get(url) |
| 86 | + headers = { |
| 87 | + params: { |
| 88 | + access_token: $github_api_token |
| 89 | + }, |
| 90 | + accept: "application/vnd.github.black-cat-preview+json" |
| 91 | + } |
| 92 | + response = RestClient.get(url, headers) |
| 93 | + JSON.parse(response.body) |
| 94 | +end |
| 95 | + |
| 96 | +def verify_signature(payload_body) |
| 97 | + signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), ENV['SECRET_TOKEN'], payload_body) |
| 98 | + return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE']) |
| 99 | +end |
0 commit comments