Class: Danger::GitHub

Inherits:
Object
  • Object
show all
Defined in:
lib/danger/request_sources/github.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ci_source, environment) ⇒ GitHub

Returns a new instance of GitHub.



11
12
13
14
15
16
17
# File 'lib/danger/request_sources/github.rb', line 11

def initialize(ci_source, environment)
  self.ci_source = ci_source
  self.environment = environment
  self.support_tokenless_auth = false

  Octokit.auto_paginate = true
end

Instance Attribute Details

#base_commitObject

Returns the value of attribute base_commit.



9
10
11
# File 'lib/danger/request_sources/github.rb', line 9

def base_commit
  @base_commit
end

#ci_sourceObject

Returns the value of attribute ci_source.



9
10
11
# File 'lib/danger/request_sources/github.rb', line 9

def ci_source
  @ci_source
end

#environmentObject

Returns the value of attribute environment.



9
10
11
# File 'lib/danger/request_sources/github.rb', line 9

def environment
  @environment
end

#head_commitObject

Returns the value of attribute head_commit.



9
10
11
# File 'lib/danger/request_sources/github.rb', line 9

def head_commit
  @head_commit
end

#issue_jsonObject

Returns the value of attribute issue_json.



9
10
11
# File 'lib/danger/request_sources/github.rb', line 9

def issue_json
  @issue_json
end

#pr_jsonObject

Returns the value of attribute pr_json.



9
10
11
# File 'lib/danger/request_sources/github.rb', line 9

def pr_json
  @pr_json
end

#support_tokenless_authObject

Returns the value of attribute support_tokenless_auth.



9
10
11
# File 'lib/danger/request_sources/github.rb', line 9

def support_tokenless_auth
  @support_tokenless_auth
end

Instance Method Details

#clientObject



19
20
21
22
23
24
25
26
# File 'lib/danger/request_sources/github.rb', line 19

def client
  token = @environment["DANGER_GITHUB_API_TOKEN"]
  raise "No API given, please provide one using `DANGER_GITHUB_API_TOKEN`" if !token && !support_tokenless_auth

  @client ||= Octokit::Client.new(
    access_token: token
  )
end

#delete_old_comments!(except: nil) ⇒ Object

Get rid of the previously posted comment, to only have the latest one



110
111
112
113
114
115
116
117
# File 'lib/danger/request_sources/github.rb', line 110

def delete_old_comments!(except: nil)
  issues = client.issue_comments(ci_source.repo_slug, ci_source.pull_request_id)
  issues.each do |issue|
    next unless issue[:body].include?("generated_by_danger")
    next if issue[:id] == except
    client.delete_comment(ci_source.repo_slug, issue[:id])
  end
end

#fetch_detailsObject



28
29
30
31
# File 'lib/danger/request_sources/github.rb', line 28

def fetch_details
  self.pr_json = client.pull_request(ci_source.repo_slug, ci_source.pull_request_id)
  fetch_issue_details(self.pr_json)
end

#fetch_issue_details(pr_json) ⇒ Object



33
34
35
36
# File 'lib/danger/request_sources/github.rb', line 33

def fetch_issue_details(pr_json)
  href = pr_json[:_links][:issue][:href]
  self.issue_json = client.get(href)
end

#generate_comment(warnings: [], errors: [], messages: []) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/danger/request_sources/github.rb', line 133

def generate_comment(warnings: [], errors: [], messages: [])
  require 'erb'

  md_template = File.join(Danger.gem_path, "lib/danger/comment_generators/github.md.erb")

  # erb: http://www.rrn.dk/rubys-erb-templating-system
  # for the extra args: http://stackoverflow.com/questions/4632879/erb-template-removing-the-trailing-line
  @tables = [
    { name: "Error", emoji: "no_entry_sign", content: errors },
    { name: "Warning", emoji: "warning", content: warnings },
    { name: "Message", emoji: "book", content: messages }
  ]
  return ERB.new(File.read(md_template), 0, "-").result(binding)
end

#generate_github_description(warnings: nil, errors: nil) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/danger/request_sources/github.rb', line 119

def generate_github_description(warnings: nil, errors: nil)
  if errors.empty? && warnings.empty?
    compliment = ["Well done.", "Congrats.", "Woo!",
                  "Yay.", "Jolly good show.", "Good on 'ya.", "Nice work."]
    return "All green. #{compliment.sample}"
  else
    message = ""
    message += "#{errors.count} Error#{errors.count == 1 ? '' : 's'}. " unless errors.empty?
    message += "#{warnings.count} Warning#{warnings.count == 1 ? '' : 's'}. " unless warnings.empty?
    message += "Don't worry, everything is fixable."
    return message
  end
end

#pr_authorObject



54
55
56
# File 'lib/danger/request_sources/github.rb', line 54

def pr_author
  self.pr_json[:user][:login]
end

#pr_bodyObject



50
51
52
# File 'lib/danger/request_sources/github.rb', line 50

def pr_body
  self.pr_json[:body]
end

#pr_labelsObject



58
59
60
# File 'lib/danger/request_sources/github.rb', line 58

def pr_labels
  self.issue_json[:labels].map { |l| l[:name] }
end

#pr_titleObject



46
47
48
# File 'lib/danger/request_sources/github.rb', line 46

def pr_title
  self.pr_json[:title]
end

#submit_pull_request_status!(warnings: nil, errors: nil, details_url: nil) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/danger/request_sources/github.rb', line 89

def submit_pull_request_status!(warnings: nil, errors: nil, details_url: nil)
  status = (errors.count == 0 ? 'success' : 'failure')
  message = generate_github_description(warnings: warnings, errors: errors)
  client.create_status(ci_source.repo_slug, latest_pr_commit_ref, status, {
    description: message,
    context: "KrauseFx/danger",
    target_url: details_url
  })
rescue
  # This usually means the user has no commit access to this repo
  # That's always the case for open source projects where you can only
  # use a read-only GitHub account
  if errors.count > 0
    # We need to fail the actual build here
    abort("\nDanger has failed this build. \nFound #{errors.count} error(s) and I don't have write access to the PR set a PR status.")
  else
    puts message
  end
end

#update_pull_request!(warnings: nil, errors: nil, messages: nil) ⇒ Object

Sending data to GitHub



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/danger/request_sources/github.rb', line 63

def update_pull_request!(warnings: nil, errors: nil, messages: nil)
  comment_result = {}

  if (warnings + errors + messages).empty?
    # Just remove the comment, if there's nothing to say.
    delete_old_comments!
  else
    issues = client.issue_comments(ci_source.repo_slug, ci_source.pull_request_id)
    editable_issues = issues.reject { |issue| issue[:body].include?("generated_by_danger") == false }
    body = generate_comment(warnings: warnings, errors: errors, messages: messages)

    if editable_issues.empty?
      comment_result = client.add_comment(ci_source.repo_slug, ci_source.pull_request_id, body)
    else
      original_id = editable_issues.first[:id]
      comment_result = client.update_comment(ci_source.repo_slug, original_id, body)
    end
  end

  # Now, set the pull request status.
  # Note: this can terminate the entire process.
  submit_pull_request_status!(warnings: warnings,
                                errors: errors,
                           details_url: comment_result['html_url'])
end