class Danger::DangerJiraSync
Jira and GitHub should be friends, and Danger
brings them closer together with jira_sync
@example You must always configure jira_sync before it can access the Jira
REST API jira_sync.configure( jira_url: "https://myjirainstance.atlassian.net", jira_username: "test@example.com", jira_api_token: "ABC123", )
@example Automatically label Pull Requests with the associated Jira issue's
component names and project key jira_sync.autolabel_pull_request(%w(DEV))
@see roverdotcom/danger-jira_sync @tags jira, github, labels, autolabel, danger, plugin
Public Instance Methods
Labels the Pull Request with Jira Project Keys and Component Names
@param issue_prefixes [Array<String>] An array of issue key prefixes;
this is often the project key. These must be present in the title or body of the Pull Request
@param project [Boolean] Label using the Jira Ticket's Project Key? @param components [Boolean] Label using the Jira Ticket's Component Names? @param labels [Boolean] Label using the Jira Ticket's Labels?
@return [Array<String>, nil] The list of project & component labels
that were applied or nil if no issue or labels were found
# File lib/jira_sync/plugin.rb, line 71 def autolabel_pull_request(issue_prefixes, project: true, components: true, labels: false) raise NotConfiguredError unless @jira_client raise(ArgumentError, "issue_prefixes cannot be empty") if issue_prefixes.empty? issue_keys = extract_issue_keys_from_pull_request(issue_prefixes) return if issue_keys.empty? labels = fetch_labels_from_issues( issue_keys, project: project, components: components, labels: labels ) return if labels.empty? create_missing_github_labels(labels) add_labels_to_issue(labels) labels end
Configures the Jira REST Client with your credentials
@param jira_url [String] The full url to your Jira instance, e.g.,
"https://myjirainstance.atlassian.net"
@param jira_username [String] The username to use for accessing the Jira
instance. Commonly, this is an email address.
@param jira_api_token [String] The API key to use to access the Jira
instance. Generate one here: https://id.atlassian.com/manage/api-tokens
@return [JIRA::Client] The underlying jira-ruby JIRA::Client instance
# File lib/jira_sync/plugin.rb, line 45 def configure(jira_url:, jira_username:, jira_api_token:) warn "danger-jira_sync plugin configuration is missing jira_url" if jira_url.blank? warn "danger-jira_sync plugin configuration is missing jira_username" if jira_username.blank? warn "danger-jira_sync plugin configuration is missing jira_api_token" if jira_api_token.blank? @jira_client = JIRA::Client.new( site: jira_url, username: jira_username, password: jira_api_token, context_path: "", auth_type: :basic ) end
Private Instance Methods
# File lib/jira_sync/plugin.rb, line 149 def add_labels_to_issue(labels) existing_labels = github.api.labels_for_issue(repo, issue_number).map { |label| label[:name] } new_labels = labels - existing_labels github.api.add_labels_to_an_issue(repo, issue_number, new_labels) unless new_labels.empty? rescue Octokit::Error => e warn "#{e.response_status} Error while adding labels [#{labels}] to GitHub issue: #{e.message}" end
# File lib/jira_sync/plugin.rb, line 136 def create_missing_github_labels(labels) missing_labels = labels - github_labels missing_labels.each do |label| color = SecureRandom.hex(3) begin github.api.add_label(repo, label, color) rescue Octokit::Error => e warn "#{e.response_status} Error while creating GitHub label \"#{label}\" with color \"#{color}\": #{e.message}" end end missing_labels end
# File lib/jira_sync/plugin.rb, line 108 def extract_issue_keys_from_pull_request(key_prefixes) # Match all key_prefixes followed by a dash then numbers, e.g. "DEV-12345" re = Regexp.new(/((#{key_prefixes.join("|")})-\d+)/) # Extract keys from the PR title and fallback to the body if none are found keys = [] github.pr_title.gsub(re) { |match| keys << match } github.pr_body.gsub(re) { |match| keys << match } if keys.empty? keys.compact.uniq end
# File lib/jira_sync/plugin.rb, line 119 def fetch_labels_from_issues(issue_keys, project: true, components: true, labels: false) issue_labels = [] issue_keys.each do |key| begin issue = @jira_client.Issue.find(key) issue_labels << issue.project.key if project issue_labels += issue.components.map(&:name) if components issue_labels += issue.fields["labels"] if labels rescue JIRA::HTTPError => e warn "#{e.code} Error while retrieving JIRA issue \"#{key}\": #{e.message}" # No reason to continue if Unauthorized break if e.code == 503 end end issue_labels.compact.uniq end
# File lib/jira_sync/plugin.rb, line 102 def github_labels @github_labels ||= github.api.labels(repo).map { |github_label| github_label[:name] } rescue Octokit::Error => e warn "#{e.response_status} Error while retrieving GitHub labels: #{e.message}" end
# File lib/jira_sync/plugin.rb, line 98 def issue_number @issue_number ||= github.pr_json["number"] end
# File lib/jira_sync/plugin.rb, line 94 def repo @repo ||= github.pr_json[:base][:repo][:full_name] end