apadmi_grout 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -1
  3. data/lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_action.rb +24 -0
  4. data/lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_ado_action.rb +91 -0
  5. data/lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_jira_action.rb +114 -0
  6. data/lib/apadmi/grout/actions/generate_release_notes_action/generate_release_notes_action.rb +48 -0
  7. data/lib/apadmi/grout/actions/generate_release_notes_action/issue_classifier.rb +51 -0
  8. data/lib/apadmi/grout/{release_notes/actions → actions}/issues_from_changelog_action.rb +11 -8
  9. data/lib/apadmi/grout/actions/move_tickets_action.rb +34 -0
  10. data/lib/apadmi/grout/di.rb +54 -9
  11. data/lib/apadmi/grout/models/ado_config.rb +10 -0
  12. data/lib/apadmi/grout/models/find_tickets_options.rb +44 -0
  13. data/lib/apadmi/grout/models/flag_messages.rb +25 -0
  14. data/lib/apadmi/grout/models/issue.rb +49 -0
  15. data/lib/apadmi/grout/{jira/models → models}/pull_request.rb +0 -0
  16. data/lib/apadmi/grout/models/release_notes_config.rb +47 -0
  17. data/lib/apadmi/grout/{release_notes/models → models}/release_notes_templates.rb +6 -6
  18. data/lib/apadmi/grout/service/board_service/ado_board_service.rb +199 -0
  19. data/lib/apadmi/grout/service/board_service/board_service.rb +59 -0
  20. data/lib/apadmi/grout/{jira/wrapper/jira_wrapper.rb → service/board_service/jira_board_service.rb} +68 -107
  21. data/lib/apadmi/grout/utils/filename_utils.rb +40 -0
  22. data/lib/apadmi/grout/utils/git_utils.rb +57 -0
  23. data/lib/apadmi/grout/utils/network_service.rb +88 -0
  24. data/lib/apadmi/grout/version.rb +1 -1
  25. data/lib/apadmi_grout.rb +3 -18
  26. metadata +23 -13
  27. data/lib/apadmi/grout/jira/actions/find_tickets_to_move_action.rb +0 -76
  28. data/lib/apadmi/grout/jira/actions/move_jira_tickets_action.rb +0 -58
  29. data/lib/apadmi/grout/jira/models/flag_messages.rb +0 -8
  30. data/lib/apadmi/grout/jira/models/version.rb +0 -23
  31. data/lib/apadmi/grout/release_notes/actions/generate_release_notes_action.rb +0 -39
  32. data/lib/apadmi/grout/release_notes/models/release_notes_config.rb +0 -74
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apadmi
4
+ module Grout
5
+ # Generic Filename Utils
6
+ class FilenameUtils
7
+ # Constructs a standard Apadmi filename for a build output binary
8
+ # @param [Hash] options the options to create a filename with
9
+ # @option options [String] :client_name The client name
10
+ # @option options [String] :product_name The product name
11
+ # @option options [String] :platform The product's platform
12
+ # @option options [String] :version Version number
13
+ # @option options [String] :build_number Build number
14
+ # @option options [String] :data (Today) The date for the file
15
+ # @option options [String] :suffix Suffix to identify what this output is (e.g. SOURCE, UAT, QA, DEV)
16
+ # @return [String] A filename formatted such as "Apadmi-Grout-Ruby-v1.0.0(2921)-2021-06-22-DEV"
17
+ def self.binary_output_filename(options = {})
18
+ client_name = options[:client_name]
19
+ raise ":client_name shouldn't be empty" if client_name.blank?
20
+
21
+ product_name = options[:product_name]
22
+ raise ":product_name shouldn't be empty" if product_name.blank?
23
+
24
+ platform = options[:platform]
25
+ raise ":platform shouldn't be empty" if platform.blank?
26
+
27
+ version = options[:version]
28
+ raise ":version shouldn't be empty" if version.blank?
29
+
30
+ build_number = options[:build_number]
31
+ raise ":build_number shouldn't be empty" if build_number.blank?
32
+
33
+ date = options[:date] || Time.now.strftime("%Y-%m-%d")
34
+ suffix = ("-#{options[:suffix]}" unless options[:suffix].blank?) || ""
35
+
36
+ "#{client_name}-#{product_name}-#{platform}-v#{version}(#{build_number})-#{date}#{suffix}"
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+
5
+ module Apadmi
6
+ module Grout
7
+ # Generic Git related utils
8
+ class GitUtils
9
+ # Gets the root of the Git repo we're in
10
+ # @return [String] The full path for the root of this Git repo
11
+ def self.git_root
12
+ stdout, stderr, = Open3.capture3("git rev-parse --show-toplevel")
13
+ raise "Failed to get git root: #{stderr}" unless stderr.strip.empty?
14
+
15
+ stdout.strip
16
+ end
17
+
18
+ # Gets the number of commits accessible from HEAD treating the history as a graph.
19
+ # See more details here: https://git-scm.com/docs/git-rev-list
20
+ # @return [String] The number of commits
21
+ def self.number_of_commits
22
+ stdout, stderr, = Open3.capture3("git rev-list HEAD --count")
23
+ raise "Failed to get commit number: #{stderr}" unless stderr.strip.empty?
24
+
25
+ stdout.strip
26
+ end
27
+
28
+ # Runs a git fetch all
29
+ def self.fetch_all
30
+ stdout, stderr, = Open3.capture3("git fetch --all")
31
+ raise "Failed to fetch #{stderr}" unless stderr.strip.empty?
32
+
33
+ stdout.strip
34
+ end
35
+
36
+ # Gets all the merges accessible from the current HEAD which matches at least one of the given grep conditions
37
+ # @param grep_conditions [Array<String>] values to be passed in as grep cases (https://git-scm.com/docs/git-log)
38
+ def self.merge_changelog(grep_conditions)
39
+ command = "git log HEAD --merges --format=%s#{grep_conditions.map { |c| " --grep #{c}" }.join(" ")}"
40
+ stdout, stderr, = Open3.capture3(command)
41
+ raise "Failed to get changelog: #{stderr}" unless stderr.strip.empty?
42
+
43
+ stdout
44
+ end
45
+
46
+ # Gets all the merges that are NOT accessible from HEAD which matches at least one of the given grep conditions
47
+ # @param grep_conditions [Array<String>] values to be passed in as grep cases (https://git-scm.com/docs/git-log)
48
+ def self.invert_changelog(grep_conditions)
49
+ command = "git log --all ^HEAD --merges --format=%s#{grep_conditions.map { |c| " --grep #{c}" }.join(" ")}"
50
+ stdout, stderr, = Open3.capture3(command)
51
+ raise "Failed to get changelog: #{stderr}" unless stderr.strip.empty?
52
+
53
+ stdout
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+
5
+ module Apadmi
6
+ module Grout
7
+ # Utility class for running REST network calls
8
+ class NetworkService
9
+ APPLICATION_JSON = "application/json"
10
+ PATCH_CONTENT_TYPE = "application/json-patch+json"
11
+ CONTENT_TYPE = "Content-Type"
12
+ private_constant :CONTENT_TYPE, :APPLICATION_JSON
13
+
14
+ # @param username [String]
15
+ # @param password [String]
16
+ # @param base_url [String]
17
+ # Params are encoded for use in Basic Auth https://datatracker.ietf.org/doc/html/rfc7617
18
+ def initialize(username, password, base_url)
19
+ @username = username
20
+ @password = password
21
+ @base_url = base_url
22
+ end
23
+
24
+ # @param [String] path
25
+ # @return [Faraday::Response]
26
+ def do_get(path)
27
+ conn = setup_con
28
+ response = conn.get("#{@base_url}#{path}", CONTENT_TYPE => APPLICATION_JSON)
29
+ throw_if_error(response)
30
+ response
31
+ end
32
+
33
+ # @param [String] path
34
+ # @param [String] payload
35
+ # @return [Faraday::Response]
36
+ def do_put(path, payload)
37
+ conn = setup_con
38
+ response = conn.put("#{@base_url}#{path}", payload, CONTENT_TYPE => APPLICATION_JSON)
39
+ throw_if_error(response)
40
+ response
41
+ end
42
+
43
+ # @param [String] path
44
+ # @param [String] payload
45
+ # @return [Faraday::Response]
46
+ def do_post(path, payload)
47
+ conn = setup_con
48
+ response = conn.post("#{@base_url}#{path}", payload, CONTENT_TYPE => APPLICATION_JSON)
49
+ throw_if_error(response)
50
+ response
51
+ end
52
+
53
+ # @param [String] path
54
+ # @param [String] payload
55
+ # @return [Faraday::Response]
56
+ def do_patch(path, payload)
57
+ conn = setup_con
58
+ response = conn.patch("#{@base_url}#{path}", payload, CONTENT_TYPE => PATCH_CONTENT_TYPE)
59
+ throw_if_error(response)
60
+ response
61
+ end
62
+
63
+ # @param [String] path
64
+ # @return [Faraday::Response]
65
+ def do_delete(path)
66
+ conn = setup_con
67
+ response = conn.delete("#{@base_url}#{path}", CONTENT_TYPE => APPLICATION_JSON)
68
+ throw_if_error(response)
69
+ response
70
+ end
71
+
72
+ private
73
+
74
+ # @return [Faraday::Connection]
75
+ def setup_con
76
+ auth_str = "#{@username}:#{@password}"
77
+ conn = Faraday.new # create a new Connection with base URL
78
+ conn.headers["Authorization"] = "Basic #{Base64.strict_encode64(auth_str)}"
79
+ conn
80
+ end
81
+
82
+ # @param [Faraday::Response] response
83
+ def throw_if_error(response)
84
+ raise "Network call failed #{response.status} #{response.body}" unless (200..210).include?(response.status)
85
+ end
86
+ end
87
+ end
88
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Apadmi
4
4
  module Grout
5
- VERSION = "1.0.0"
5
+ VERSION = "2.0.0"
6
6
  end
7
7
  end
data/lib/apadmi_grout.rb CHANGED
@@ -1,20 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "apadmi/grout/version"
4
- require_relative "apadmi/grout/di"
5
-
6
- require_relative "apadmi/grout/release_notes/actions/issues_from_changelog_action"
7
- require_relative "apadmi/grout/release_notes/actions/generate_release_notes_action"
8
- require_relative "apadmi/grout/release_notes/models/release_notes_config"
9
- require_relative "apadmi/grout/release_notes/models/release_notes_templates"
10
-
11
- require_relative "apadmi/grout/jira/actions/move_jira_tickets_action"
12
- require_relative "apadmi/grout/jira/actions/find_tickets_to_move_action"
13
-
14
- require_relative "apadmi/grout/jira/wrapper/jira_wrapper"
15
-
16
- require_relative "apadmi/grout/jira/models/pull_request"
17
- require_relative "apadmi/grout/jira/models/version"
18
- require_relative "apadmi/grout/jira/models/flag_messages"
19
-
20
- require_relative "apadmi/grout/utils/logger"
3
+ Dir[File.expand_path("apadmi/grout/**/*.rb", File.dirname(__FILE__))].sort.each do |current|
4
+ require current
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apadmi_grout
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Sam
7
+ - Apadmi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-09 00:00:00.000000000 Z
11
+ date: 2022-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -63,18 +63,28 @@ files:
63
63
  - CODE_OF_CONDUCT.md
64
64
  - LICENSE
65
65
  - README.md
66
+ - lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_action.rb
67
+ - lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_ado_action.rb
68
+ - lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_jira_action.rb
69
+ - lib/apadmi/grout/actions/generate_release_notes_action/generate_release_notes_action.rb
70
+ - lib/apadmi/grout/actions/generate_release_notes_action/issue_classifier.rb
71
+ - lib/apadmi/grout/actions/issues_from_changelog_action.rb
72
+ - lib/apadmi/grout/actions/move_tickets_action.rb
66
73
  - lib/apadmi/grout/di.rb
67
- - lib/apadmi/grout/jira/actions/find_tickets_to_move_action.rb
68
- - lib/apadmi/grout/jira/actions/move_jira_tickets_action.rb
69
- - lib/apadmi/grout/jira/models/flag_messages.rb
70
- - lib/apadmi/grout/jira/models/pull_request.rb
71
- - lib/apadmi/grout/jira/models/version.rb
72
- - lib/apadmi/grout/jira/wrapper/jira_wrapper.rb
73
- - lib/apadmi/grout/release_notes/actions/generate_release_notes_action.rb
74
- - lib/apadmi/grout/release_notes/actions/issues_from_changelog_action.rb
75
- - lib/apadmi/grout/release_notes/models/release_notes_config.rb
76
- - lib/apadmi/grout/release_notes/models/release_notes_templates.rb
74
+ - lib/apadmi/grout/models/ado_config.rb
75
+ - lib/apadmi/grout/models/find_tickets_options.rb
76
+ - lib/apadmi/grout/models/flag_messages.rb
77
+ - lib/apadmi/grout/models/issue.rb
78
+ - lib/apadmi/grout/models/pull_request.rb
79
+ - lib/apadmi/grout/models/release_notes_config.rb
80
+ - lib/apadmi/grout/models/release_notes_templates.rb
81
+ - lib/apadmi/grout/service/board_service/ado_board_service.rb
82
+ - lib/apadmi/grout/service/board_service/board_service.rb
83
+ - lib/apadmi/grout/service/board_service/jira_board_service.rb
84
+ - lib/apadmi/grout/utils/filename_utils.rb
85
+ - lib/apadmi/grout/utils/git_utils.rb
77
86
  - lib/apadmi/grout/utils/logger.rb
87
+ - lib/apadmi/grout/utils/network_service.rb
78
88
  - lib/apadmi/grout/version.rb
79
89
  - lib/apadmi_grout.rb
80
90
  homepage: https://bitbucket.org/apadmi/apadmi-grout-ruby/
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Apadmi
4
- module Grout
5
- # Finds and returns a list of all the issues that are ready to be moved
6
- # Any tickets found that have the given status but *don't* appear ready to be moved will
7
- # be flagged.
8
- class FindTicketsToMoveAction
9
- # @param [Apadmi::Grout::JiraWrapper]
10
- # @param [Apadmi::Grout::DefaultLogger] // or your own logger!
11
- def initialize(jira_wrapper, logger)
12
- @jira_wrapper = jira_wrapper
13
- @logger = logger
14
- end
15
-
16
- # @param component [String] Only include tickets tagged with this component
17
- # @param status [String] The status of tickets to be moved (Usually "Awaiting QA Release")
18
- # @param excluded_ticket_keys [Array<String>] ticket keys to be excluded from consideration
19
- # @param custom_flag_messages [FlagMessages]
20
- # @return [Array<JIRA::Resource::Issue>] the issues ready to move
21
- def run(
22
- component,
23
- status,
24
- excluded_ticket_keys,
25
- custom_flag_messages = FlagMessages.new(
26
- "REASON FOR FLAG: Check this ticket - it was put in #{status} but has no PRs connected to it. CI still moved it",
27
- "REASON FOR FLAG: Check this ticket - it was put in #{status} but has no MERGED PRs and at least one OPEN PR",
28
- "REASON FOR FLAG: Check this ticket - it was put in #{status} but has only DECLINED PRs",
29
- "REASON FOR FLAG: Check this ticket - it was put in #{status} but has no MERGED PRs"
30
- )
31
- )
32
- issues = @jira_wrapper.search_unblocked_issues(component, status).reject do |issue|
33
- puts issue.key
34
- excluded_ticket_keys.include? issue.key
35
- end
36
-
37
- @logger.message("Found issues to consider #{issues.map(&:key).join(", ")}")
38
- final_list = issues.filter do |issue|
39
- # Decide whether to include this ticket based on PRs
40
- process_prs(issue, custom_flag_messages)
41
- end
42
- @logger.message("Final list: #{final_list.map(&:key).join(", ")}")
43
- final_list
44
- end
45
-
46
- private
47
-
48
- # @param issue [JIRA::Resource::Issue]
49
- # @param custom_flag_messages [FlagMessages]
50
- # @return [Boolean] whether or not this ticket can be moved
51
- def process_prs(issue, custom_flag_messages)
52
- prs = @jira_wrapper.get_ticket_prs(issue)
53
-
54
- if prs.empty?
55
- @logger.message("#{issue.key} has no PRs. Flagging it: STILL MOVABLE")
56
- @jira_wrapper.flag_ticket(issue.key, custom_flag_messages.no_prs_flag_msg)
57
- return true
58
- elsif prs.all?(&:open)
59
- @logger.message("#{issue.key} has only open PRs. Flagging it: NOT MOVABLE")
60
- @jira_wrapper.flag_ticket(issue.key, custom_flag_messages.open_prs_flag_msg)
61
- return false
62
- elsif prs.all?(&:declined)
63
- @logger.message("#{issue.key} has only declined PRs. Flagging it: NOT MOVABLE")
64
- @jira_wrapper.flag_ticket(issue.key, custom_flag_messages.declined_prs_flag_msg)
65
- return false
66
- elsif prs.none?(&:merged)
67
- @logger.message("#{issue.key} has no merged PRs. Flagging it: NOT MOVABLE")
68
- @jira_wrapper.flag_ticket(issue.key, custom_flag_messages.no_merged_prs_flag_msg)
69
- return false
70
- end
71
-
72
- true # At least one merged PR, so it's included
73
- end
74
- end
75
- end
76
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Apadmi
4
- module Grout
5
- # Moves all given jira tickets to a given status and assigns fix versions
6
- class MoveJiraTicketsAction
7
- # @param [Apadmi::Grout::JiraWrapper]
8
- # @param [Apadmi::Grout::DefaultLogger] // or your own logger!
9
- def initialize(jira_wrapper, logger)
10
- @jira_wrapper = jira_wrapper
11
- @logger = logger
12
- end
13
-
14
- # @param [Array<String>] version_strings
15
- # @param [Array<JIRA::Resource::Issue>] issues
16
- # @param [String] new_status
17
- def run(version_strings, issues, new_status)
18
- if issues.empty?
19
- @logger.error("No issues found, aborting")
20
- return
21
- end
22
-
23
- @logger.message("Creating versions #{version_strings}")
24
- versions = create_or_get_versions(version_strings)
25
-
26
- @logger.message("Transitioning issues: #{issues.map(&:key).join(", ")}")
27
- issues.each { |issue| move_issue(issue, new_status, versions) }
28
-
29
- @logger.success("Issues transitioned successfully :D")
30
- end
31
-
32
- # @param [Array<String>] version_strings
33
- # @return [Array<JIRA::Resource::Version>]
34
- def create_or_get_versions(version_strings)
35
- all_versions = @jira_wrapper.all_versions
36
- version_strings.map do |version|
37
- existing_version = all_versions.find { |v| v.name == version }
38
- if !existing_version.nil?
39
- existing_version
40
- else
41
- date = Time.now.strftime("%Y-%m-%d")
42
- @jira_wrapper.create_version(date, version)
43
- end
44
- end
45
- end
46
-
47
- # @param [JIRA::Resource::Issue] issue
48
- # @param [String] new_status
49
- # @param [Array<JIRA::Resource::Version>] versions
50
- def move_issue(issue, new_status, versions)
51
- @jira_wrapper.transition_issue(issue, new_status)
52
- @jira_wrapper.assign_fixversions(issue.id, versions)
53
- end
54
-
55
- private :create_or_get_versions, :move_issue
56
- end
57
- end
58
- end
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- FlagMessages = Struct.new(
4
- :no_prs_flag_msg,
5
- :open_prs_flag_msg,
6
- :declined_prs_flag_msg,
7
- :no_merged_prs_flag_msg
8
- )
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Apadmi
4
- module Grout
5
- # Represents a version object derived from the Jira REST API response.
6
- class Version
7
- attr_reader :self, :id, :description, :name, :archived, :released, :release_date, :overdue, :user_release_date, :project_id
8
-
9
- def initialize(json)
10
- @self = json["self"]
11
- @id = json["id"]
12
- @description = json["description"]
13
- @name = json["name"]
14
- @archived = json["archived"]
15
- @released = json["released"]
16
- @release_date = json["release_date"]
17
- @overdue = json["overdue"]
18
- @user_release_date = json["user_release_date"]
19
- @project_id = json["project_id"]
20
- end
21
- end
22
- end
23
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "mustache"
4
-
5
- module Apadmi
6
- module Grout
7
- # Finds and returns a list of all the issues who's ids exist in the given changelog
8
- class GenerateReleaseNotesAction
9
- # @param jira_base_url [String] Jira base url
10
- def initialize(jira_base_url)
11
- @jira_base_url = jira_base_url
12
- end
13
-
14
- # @param config [Apadmi::Grout::ReleaseNotesConfig]
15
- def run(config)
16
- base_url = "#{@jira_base_url}/browse/"
17
-
18
- Mustache.render(
19
- config.templates.document_template,
20
- config: config,
21
- rendered_moved_issues: render_classified_issues(config.templates.list_template, base_url, config.classified_moved_issues),
22
- rendered_release_issues: render_classified_issues(config.templates.list_template, base_url, config.classified_release_issues)
23
- ).strip
24
- end
25
-
26
- private
27
-
28
- def render_classified_issues(template, base_url, classified_issues)
29
- return if classified_issues.empty
30
-
31
- Mustache.render(
32
- template,
33
- classified_issues: classified_issues,
34
- base_url: base_url
35
- )
36
- end
37
- end
38
- end
39
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Apadmi
4
- module Grout
5
- # @param tasks [Array<JIRA::Resource::Issue>]
6
- # @param features [Array<JIRA::Resource::Issue>] aka stories
7
- # @param improvements [Array<JIRA::Resource::Issue>]
8
- # @param defects [Array<JIRA::Resource::Issue>] aka bugs
9
- # @param others [Array<JIRA::Resource::Issue>] any other non-standard issue types
10
- ClassifiedIssues = Struct.new(
11
- :tasks,
12
- :features,
13
- :improvements,
14
- :defects,
15
- :others
16
- ) do
17
- # @return returns true if all categories are empty
18
- def empty
19
- tasks.empty? && features.empty? &&
20
- improvements.empty? && defects.empty? && others.empty?
21
- end
22
- end
23
-
24
- # @param title [String] The title of the document
25
- # @param app_version [String] The app version pertaining to this release
26
- # @param min_os_version [String] The min supported os version of this release
27
- # @param date [String] Today's date
28
- # @param moved_issues [Array<JIRA::Resource::Issue>] Issues moved to a new state by this build job
29
- # @param release_issues [Array<JIRA::Resource::Issue>] Issues considered part of this release
30
- # @param commit_hash [String] Commit hash from which release was built
31
- # @param ci_build_number [String] CI build number which built the release
32
- # @param ci_build_url [String] Link to CI build job
33
- # @param templates [Apadmi::Grout::Templates] Mustache templates to use to generate the document
34
- ReleaseNotesConfig = Struct.new(
35
- :title,
36
- :app_version,
37
- :min_os_version,
38
- :date,
39
- :moved_issues,
40
- :release_issues,
41
- :commit_hash,
42
- :ci_build_number,
43
- :ci_build_url,
44
- :templates
45
- ) do
46
- def classified_moved_issues
47
- classify_issues(moved_issues)
48
- end
49
-
50
- def classified_release_issues
51
- classify_issues(release_issues)
52
- end
53
-
54
- private
55
-
56
- def classify_issues(issues)
57
- ClassifiedIssues.new(
58
- filter_issues_by_type(%w[Task], issues),
59
- filter_issues_by_type(%w[Story Debt], issues),
60
- filter_issues_by_type(%w[Improvement Rework], issues),
61
- filter_issues_by_type(%w[Bug], issues),
62
- issues - filter_issues_by_type(%w[Task Story Debt Improvement Rework Bug], issues)
63
- )
64
- end
65
-
66
- # @param types [Array<String>] List of types to match on
67
- # @param issues [Array<JIRA::Resource::Issue>]
68
- # @return [Array<JIRA::Resource::Issue>]
69
- def filter_issues_by_type(types, issues)
70
- issues.find_all { |issue| types.include?(issue.issuetype.name) }
71
- end
72
- end
73
- end
74
- end