Class: Apadmi::Grout::JiraBoardService
- Inherits:
-
BoardService
- Object
- BoardService
- Apadmi::Grout::JiraBoardService
- Defined in:
- lib/apadmi/grout/service/board_service/jira_board_service.rb
Overview
Provides a layer of abstraction on top of the Jira api
Instance Method Summary collapse
- #add_comment(key, comment) ⇒ Object
-
#add_version_related_work(version_name, url, title) ⇒ Object
Adds a related work link to a Jira version, skipping if a link with the same URL already exists.
- #all_versions ⇒ Array<JIRA::Resource::Version>
-
#assign_fixversion_to_tickets(issues, version_names) ⇒ Object
Assigns one or more fix versions to all given issues that are missing them.
- #assign_fixversions(key, version_strings) ⇒ Object
- #create_version(release_date, name) ⇒ JIRA::Resource::Version
- #delete_version(version_id, move_version_id) ⇒ Object
- #find_issues_by_keys(keys) ⇒ Array<Apadmi::Grout::Issue>
- #flag_ticket(key, comment) ⇒ Object
-
#flagged?(key) ⇒ Boolean
Bool.
- #get_ticket_fixversions(key) ⇒ Array<String>
- #get_ticket_prs(issue) ⇒ Array<PullRequest>
- #get_ticket_status(key) ⇒ String
- #get_ticket_subtask(keys, component = nil) ⇒ Array<Apadmi::Grout::Issue>
- #get_tickets_by_component(component_key) ⇒ Array<Apadmi::Grout::Issue>
- #get_top_comment(key) ⇒ JIRA::Resource::Comment
- #get_transitions(key) ⇒ Object
-
#initialize(jira_config, network_service) ⇒ JiraBoardService
constructor
A new instance of JiraBoardService.
- #remove_comment(key, comment_id) ⇒ Object
-
#remove_fixversions(key, version_names) ⇒ Object
Removes specific fix versions from a ticket using the update.remove operation.
- #search_unblocked_issues(component, status, ticket_types = [], options = nil) ⇒ Array<Apadmi::Grout::Issue>
- #transition_issue(issue, state_name) ⇒ Object
- #un_flag_ticket(key) ⇒ Object
- #update_version(version_name, released: nil, description: nil) ⇒ Object
Constructor Details
#initialize(jira_config, network_service) ⇒ JiraBoardService
Returns a new instance of JiraBoardService.
11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 11 def initialize(jira_config, network_service) @options = { username: jira_config.username, password: jira_config.api_token, site: jira_config.base_url, context_path: jira_config.context_path, auth_type: :basic } @project = jira_config.project_key @network_service = network_service @jira_client = JIRA::Client.new(@options) end |
Instance Method Details
#add_comment(key, comment) ⇒ Object
97 98 99 100 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 97 def add_comment(key, comment) payload = "{\"issueKeys\":[\"#{key}\"],\"commentVisibility\":\"\",\"comment\":\"#{comment}\"}" @network_service.do_post("/rest/greenhopper/1.0/xboard/issue/flag/flag.json", payload) end |
#add_version_related_work(version_name, url, title) ⇒ Object
Adds a related work link to a Jira version, skipping if a link with the same URL already exists.
263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 263 def (version_name, url, title) version = create_or_get_versions([version_name]).find { |v| v.name == version_name } raise "Version '#{version_name}' not found" if version.nil? response = @network_service.do_get("/rest/api/3/version/#{version.id}/relatedwork") existing_links = JSON.parse(response.body) || [] return if existing_links.any? { |link| link["url"] == url } payload = { category: "link", url: url, title: title }.to_json @network_service.do_post("/rest/api/3/version/#{version.id}/relatedwork", payload) end |
#all_versions ⇒ Array<JIRA::Resource::Version>
189 190 191 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 189 def all_versions @jira_client.Project.find(@project).versions end |
#assign_fixversion_to_tickets(issues, version_names) ⇒ Object
Assigns one or more fix versions to all given issues that are missing them. Filters in-memory from the already-fetched issue objects — no extra network calls. Each issue gets a single PUT containing only the versions it is missing.
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 213 def assign_fixversion_to_tickets(issues, version_names) return if issues.empty? || version_names.empty? versions = create_or_get_versions(version_names) issues.each do |issue| if issue.raw_object.nil? warn "Skipping fix version assignment for unclassified fallback issue #{issue.key}" next end existing_ids = issue.raw_object.fixVersions.map(&:id) missing = versions.reject { |v| existing_ids.include?(v.id) } next if missing.empty? adds = missing.map { |v| "{\"add\": {\"id\": \"#{v.id}\"}}" }.join(", ") @network_service.do_put("/rest/api/2/issue/#{issue.key}", "{\"update\": {\"fixVersions\": [#{adds}]}}") end end |
#assign_fixversions(key, version_strings) ⇒ Object
235 236 237 238 239 240 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 235 def assign_fixversions(key, version_strings) versions = create_or_get_versions(version_strings) fixversions = versions.map { |v| "{\"id\": \"#{v.id}\"}" }.join(", ") payload = "{\"fields\" : {\"fixVersions\": [#{fixversions}] }}" @network_service.do_put("/rest/api/2/issue/#{key}", payload) end |
#create_version(release_date, name) ⇒ JIRA::Resource::Version
170 171 172 173 174 175 176 177 178 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 170 def create_version(release_date, name) version = @jira_client.Version.build version.save!({ project: @project, name: name, startDate: release_date }) version end |
#delete_version(version_id, move_version_id) ⇒ Object
182 183 184 185 186 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 182 def delete_version(version_id, move_version_id) payload = "{\"moveFixIssuesTo\": #{move_version_id}, \"moveAffectedIssuesTo\": #{move_version_id}, " \ "\"customFieldReplacementList\": []}" @network_service.do_post("/rest/api/2/version/#{version_id}/removeAndSwap", payload) end |
#find_issues_by_keys(keys) ⇒ Array<Apadmi::Grout::Issue>
26 27 28 29 30 31 32 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 26 def find_issues_by_keys(keys) return [] if keys.length <= 0 jql_search = "project = '#{@project}' AND issue IN (#{keys.join(", ")})" issues = @jira_client.Issue.jql(jql_search, { max_results: 1000, fields: ["*navigable"] }).uniq convert(issues) end |
#flag_ticket(key, comment) ⇒ Object
74 75 76 77 78 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 74 def flag_ticket(key, comment) payload = "{\"flag\":true,\"issueKeys\":[\"#{key}\"],\"commentVisibility\":\"\",\"comment\":\"#{comment}\"}" @network_service.do_post("/rest/greenhopper/1.0/xboard/issue/flag/flag.json", payload) sleep 2 # Seems to take a while for flagging and unflagging to register end |
#flagged?(key) ⇒ Boolean
Returns bool.
89 90 91 92 93 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 89 def flagged?(key) jql_search = "project = '#{@project}' AND issue IN (#{key}) AND Flagged is not EMPTY" response = @jira_client.Issue.jql(jql_search, { max_results: 1000, fields: ["*navigable"] }).uniq response != [] end |
#get_ticket_fixversions(key) ⇒ Array<String>
254 255 256 257 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 254 def get_ticket_fixversions(key) response = @network_service.do_get("/rest/api/2/issue/#{key}") JSON.parse(response.body)["fields"]["fixVersions"].map { |v| v["name"] } || [] end |
#get_ticket_prs(issue) ⇒ Array<PullRequest>
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 139 def get_ticket_prs(issue) if issue.raw_object.nil? warn "Skipping PR lookup for unclassified fallback issue #{issue.key}" return [] end query_string = "issueId=#{issue.raw_object.id}&applicationType=bitbucket&dataType=pullrequest" response = @network_service.do_get("/rest/dev-status/latest/issue/details?#{query_string}") parsed_detail = JSON.parse(response.body)["detail"] return [] if parsed_detail.empty? return [] unless parsed_detail[0].key?("pullRequests") parsed_detail[0]["pullRequests"].map do |pr| PullRequest.new(pr["id"], pr["name"], pr["status"].to_s == "MERGED", pr["status"].to_s == "DECLINED") end end |
#get_ticket_status(key) ⇒ String
132 133 134 135 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 132 def get_ticket_status(key) issue = @jira_client.Issue.find(key) issue.status.name end |
#get_ticket_subtask(keys, component = nil) ⇒ Array<Apadmi::Grout::Issue>
161 162 163 164 165 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 161 def get_ticket_subtask(keys, component = nil) jql_search = "project = '#{@project}' AND parent IN #{keys.to_s.gsub("[", "(").gsub("]", ")")}" \ + (component.nil? ? "" : " AND component IN ('#{component}')") convert(@jira_client.Issue.jql(jql_search, { max_results: 1000, fields: ["*navigable"] }).uniq) end |
#get_tickets_by_component(component_key) ⇒ Array<Apadmi::Grout::Issue>
119 120 121 122 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 119 def get_tickets_by_component(component_key) jql_search = "project = '#{@project}' AND component IN ('#{component_key}')" convert(@jira_client.Issue.jql(jql_search, { max_results: 1000, fields: ["*navigable"] }).uniq) end |
#get_top_comment(key) ⇒ JIRA::Resource::Comment
104 105 106 107 108 109 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 104 def get_top_comment(key) jql_search = "project = '#{@project}' AND issue IN (#{key})" response = @jira_client.Issue.jql(jql_search, { fields: ["comment"], max_results: 1000 }).uniq comments = response[0].comments.reverse comments.empty? ? nil : comments[0] end |
#get_transitions(key) ⇒ Object
125 126 127 128 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 125 def get_transitions(key) issue = @jira_client.Issue.find(key) @jira_client.Transition.all(issue: issue) end |
#remove_comment(key, comment_id) ⇒ Object
113 114 115 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 113 def remove_comment(key, comment_id) @network_service.do_delete("/rest/api/2/issue/#{key}/comment/#{comment_id}") end |
#remove_fixversions(key, version_names) ⇒ Object
Removes specific fix versions from a ticket using the update.remove operation.
245 246 247 248 249 250 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 245 def remove_fixversions(key, version_names) return if version_names.empty? removes = version_names.map { |name| "{\"remove\": {\"name\": \"#{name}\"}}" }.join(", ") @network_service.do_put("/rest/api/2/issue/#{key}", "{\"update\": {\"fixVersions\": [#{removes}]}}") end |
#search_unblocked_issues(component, status, ticket_types = [], options = nil) ⇒ Array<Apadmi::Grout::Issue>
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 39 def search_unblocked_issues(component, status, ticket_types = [], = nil) allow_no_sprint = &.include_no_sprint_tickets || false component_filter = (" AND component = '#{component}' " unless component.empty?) || "" status_filter = (" AND status = '#{status}' " unless status.empty?) || "" type_filter = ("AND (#{ticket_types.map { |type| "type = #{type}" }.join("OR ")})" unless ticket_types.empty?) || "" empty_sprint_condition = ("OR sprint is EMPTY" if allow_no_sprint) || "" jql_search = %{ project = '#{@project}' #{status_filter} #{component_filter} #{type_filter} AND (sprint in openSprints() #{empty_sprint_condition}) AND (labels not in(Blocked) or labels is EMPTY) AND Flagged is EMPTY } issues = @jira_client.Issue.jql(jql_search, { max_results: 1000, fields: ["*navigable"] }).uniq convert(issues) end |
#transition_issue(issue, state_name) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 59 def transition_issue(issue, state_name) if issue.raw_object.nil? warn "Skipping transition for unclassified fallback issue #{issue.key}" return end transitions = @jira_client.Transition.all(issue: issue.raw_object) transition = transitions.find { |elem| elem.name.downcase == state_name.downcase } trans = issue.raw_object.transitions.build trans.save!("transition" => { "id" => transition.id }) end |
#un_flag_ticket(key) ⇒ Object
81 82 83 84 85 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 81 def un_flag_ticket(key) payload = "{\"flag\":false,\"issueKeys\":[\"#{key}\"],\"commentVisibility\":\"\",\"comment\":\"Unflagged by CI\"}" @network_service.do_post("/rest/greenhopper/1.0/xboard/issue/flag/flag.json", payload) sleep 2 # Seems to take a while for flagging and unflagging to register end |
#update_version(version_name, released: nil, description: nil) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/apadmi/grout/service/board_service/jira_board_service.rb', line 196 def update_version(version_name, released: nil, description: nil) raise ArgumentError, "Must provide at least one of: released, description" if released.nil? && description.nil? version = create_or_get_versions([version_name]).first raise "Version '#{version_name}' not found" if version.nil? fields = {} fields[:released] = released unless released.nil? fields[:description] = description unless description.nil? @network_service.do_put("/rest/api/2/version/#{version.id}", fields.to_json) end |