123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class GitLab
- class LinkedIssue
- STATES_MAPPING = {
- 'opened' => 'open'
- }.freeze
- QUERY = <<-GRAPHQL.freeze
- query($fullpath: ID!, $issue_id: String) {
- project(fullPath: $fullpath) {
- issue(iid: $issue_id) {
- iid
- webUrl
- title
- state
- milestone {
- title
- }
- assignees {
- edges {
- node {
- name
- }
- }
- }
- labels {
- edges {
- node {
- title
- color
- textColor
- description
- }
- }
- }
- }
- }
- }
- GRAPHQL
- attr_reader :client
- def initialize(client)
- @client = client
- end
- def find_by(url)
- @result = query_by_url(url)
- if @result.blank?
- new_url = query_new_url_by_rest_api(url)
- return if new_url.blank?
- @result = query_by_url(new_url)
- end
- return if @result.blank?
- to_h
- end
- private
- def to_h
- {
- id: @result['iid'],
- title: @result['title'],
- url: @result['webUrl'],
- icon_state: STATES_MAPPING.fetch(@result['state'], @result['state']),
- milestone: milestone,
- assignees: assignees,
- labels: labels,
- }
- end
- def assignees
- @result['assignees']['edges'].map do |assignee|
- assignee['node']['name']
- end
- end
- def labels
- @result['labels']['edges'].map do |label|
- {
- text_color: label['node']['textColor'],
- color: label['node']['color'],
- title: label['node']['title']
- }
- end
- end
- def milestone
- @result.dig('milestone', 'title')
- end
- def query_by_url(url)
- variables = variables(url)
- return if variables.blank?
- response = client.perform(
- query: GitLab::LinkedIssue::QUERY,
- variables: variables
- )
- response.dig('data', 'project', 'issue')
- end
- def query_new_url_by_rest_api(url)
- variables = variables(url)
- return if variables.blank?
- response = client.perform_rest_get_request(variables)
- return if response.blank?
- response['web_url']
- end
- def variables(url)
- if url !~ %r{^https?://([^/]+)/(.*)/-/issues/(\d+)$}
- raise Exceptions::UnprocessableEntity, __('Invalid GitLab issue link format')
- end
- host = $1
- fullpath = $2
- id = $3
- if client.endpoint_path.present?
- fullpath.sub!(client.endpoint_path, '')
- end
- if client.endpoint.exclude?(host)
- raise Exceptions::UnprocessableEntity, "Issue link doesn't match configured GitLab endpoint '#{client.endpoint}'"
- end
- {
- fullpath: fullpath,
- issue_id: id
- }
- end
- end
- end
|