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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_action.rb +24 -0
- data/lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_ado_action.rb +91 -0
- data/lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_jira_action.rb +114 -0
- data/lib/apadmi/grout/actions/generate_release_notes_action/generate_release_notes_action.rb +48 -0
- data/lib/apadmi/grout/actions/generate_release_notes_action/issue_classifier.rb +51 -0
- data/lib/apadmi/grout/{release_notes/actions → actions}/issues_from_changelog_action.rb +11 -8
- data/lib/apadmi/grout/actions/move_tickets_action.rb +34 -0
- data/lib/apadmi/grout/di.rb +54 -9
- data/lib/apadmi/grout/models/ado_config.rb +10 -0
- data/lib/apadmi/grout/models/find_tickets_options.rb +44 -0
- data/lib/apadmi/grout/models/flag_messages.rb +25 -0
- data/lib/apadmi/grout/models/issue.rb +49 -0
- data/lib/apadmi/grout/{jira/models → models}/pull_request.rb +0 -0
- data/lib/apadmi/grout/models/release_notes_config.rb +47 -0
- data/lib/apadmi/grout/{release_notes/models → models}/release_notes_templates.rb +6 -6
- data/lib/apadmi/grout/service/board_service/ado_board_service.rb +199 -0
- data/lib/apadmi/grout/service/board_service/board_service.rb +59 -0
- data/lib/apadmi/grout/{jira/wrapper/jira_wrapper.rb → service/board_service/jira_board_service.rb} +68 -107
- data/lib/apadmi/grout/utils/filename_utils.rb +40 -0
- data/lib/apadmi/grout/utils/git_utils.rb +57 -0
- data/lib/apadmi/grout/utils/network_service.rb +88 -0
- data/lib/apadmi/grout/version.rb +1 -1
- data/lib/apadmi_grout.rb +3 -18
- metadata +23 -13
- data/lib/apadmi/grout/jira/actions/find_tickets_to_move_action.rb +0 -76
- data/lib/apadmi/grout/jira/actions/move_jira_tickets_action.rb +0 -58
- data/lib/apadmi/grout/jira/models/flag_messages.rb +0 -8
- data/lib/apadmi/grout/jira/models/version.rb +0 -23
- data/lib/apadmi/grout/release_notes/actions/generate_release_notes_action.rb +0 -39
- 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
|
data/lib/apadmi/grout/version.rb
CHANGED
data/lib/apadmi_grout.rb
CHANGED
@@ -1,20 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
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:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Apadmi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-05-
|
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/
|
68
|
-
- lib/apadmi/grout/
|
69
|
-
- lib/apadmi/grout/
|
70
|
-
- lib/apadmi/grout/
|
71
|
-
- lib/apadmi/grout/
|
72
|
-
- lib/apadmi/grout/
|
73
|
-
- lib/apadmi/grout/
|
74
|
-
- lib/apadmi/grout/
|
75
|
-
- lib/apadmi/grout/
|
76
|
-
- lib/apadmi/grout/
|
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,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
|