# frozen_string_literal: true require "date" require "jira-ruby" module Groundskeeper # Wraps an interface to Jira. class Jira JIRA_USERNAME_KEY = "JIRA_USERNAME" JIRA_PASSWORD_KEY = "JIRA_PASSWORD" JIRA_SITE_KEY = "JIRA_SITE" DEPLOY_TO_STAGING = "Deploy to Staging" DELIVER = "Deliver" TRANSITION_IDS = { DEPLOY_TO_STAGING => 231, DELIVER => 201 }.freeze attr_reader :client, :prefix ISSUE_PATTERN = "%s-\\d+" # Wraps the jira-ruby Client class. class JiraClient attr_reader :client def initialize @client = JIRA::Client.new( username: ENV[JIRA_USERNAME_KEY], password: ENV[JIRA_PASSWORD_KEY], site: ENV[JIRA_SITE_KEY], context_path: "", auth_type: :basic, read_timeout: 120 ) end def create_version(name:, prefix:) client.Version .build .save(name: name, project: prefix) end def add_version_to_issue(issue_id:, version_name:) client.Issue .find(issue_id) .save(update: { fixVersions: [{ add: { name: version_name } }] }) end def transition_issue(issue_id:, transition_id:) client.Issue .find(issue_id) .transitions .build .save(transition: { id: transition_id }) end def fetch_issues_by_fix_version(version:) search_path = "/rest/api/2/search" query = "fixVersion = \"#{version}\"" response = client.get("#{search_path}?fields=key&jql=#{URI.escape(query)}").body JSON.parse(response)["issues"].map { |issue| issue["key"] } end end def self.build(prefix) new( prefix: prefix, client: JiraClient.new ) end def initialize(client: nil, prefix: nil) @prefix = prefix @client = client end def credentials? ENV[JIRA_USERNAME_KEY].present? && ENV[JIRA_PASSWORD_KEY].present? && ENV[JIRA_SITE_KEY].present? end # Returns the list of Jira issues found in a set of commit messages. def included_issues(changes) issue_expression = /#{format(ISSUE_PATTERN, prefix)}/ changes .map { |change| change.scan(issue_expression) } .flatten .compact .sort end def create_remote_version(name) client.create_version(name: name, prefix: prefix) end def add_version_to_remote_issues(name, issue_ids) issue_ids.each do |issue_id| client.add_version_to_issue(issue_id: issue_id, version_name: name) end end def transition_remote_issues(transition_type, issue_ids) issue_ids.each do |issue_id| client.transition_issue( issue_id: issue_id, transition_id: TRANSITION_IDS[transition_type] ) end end def fetch_issues_by_fix_version(version) client.fetch_issues_by_fix_version(version: version) end end end