apadmi_grout 2.6.1 → 2.8.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 +6 -0
- data/lib/apadmi/grout/actions/check_unfinished_releases_action.rb +58 -0
- data/lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_jira_action.rb +14 -6
- data/lib/apadmi/grout/di.rb +2 -2
- data/lib/apadmi/grout/models/bitrise.rb +2 -2
- data/lib/apadmi/grout/models/find_tickets_options.rb +4 -3
- data/lib/apadmi/grout/utils/git_utils.rb +92 -12
- data/lib/apadmi/grout/version.rb +1 -1
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75c06e02304d0547ca158b319c9c88e895753233fd06da8d864c402ae89946e1
|
4
|
+
data.tar.gz: 6fda7788c5401a14481f715f4007dec869219438304b0206dfce5eb3735c3e07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b34320096c5d746f833c48ab31d00933188fdfe86c607a5529f58f03f15b8fb2636ba752b8d5a2743bf4b0d98563c39d21a64b950fb8706b278cc4ddca2500fb
|
7
|
+
data.tar.gz: 38c1b2705c12d5fb8480270a26022f1266f0bb9b15da84ffde2447ada05e7de497356a46ae759a1fc3a91fefb1aa50524a30bf52094e0da6fec31ebcdc9f763c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Core Changelog
|
2
2
|
|
3
|
+
## [2.8.0] - 2025-05-22
|
4
|
+
* Add ability to disable use of the undocumented JIRA apis
|
5
|
+
|
6
|
+
## [2.7.0] - 2024-09-24
|
7
|
+
* Add utility for checking for unmerged release branches before deployments
|
8
|
+
|
3
9
|
## [2.6.1] - 2024-01-09
|
4
10
|
* Fix: missing blank? method because ActiveSupport requires you to load the extensions explicitly from 7.1
|
5
11
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "semantic" # We'll use this gem for semantic versioning comparison
|
4
|
+
|
5
|
+
module Apadmi
|
6
|
+
module Grout
|
7
|
+
# Checks that all releases before this one are ancestors in the commit
|
8
|
+
# history to ensure that any unmerged fixes don't get missed
|
9
|
+
class CheckUnfinishedReleasesAction
|
10
|
+
# @param [Apadmi::Grout::GitUtils]
|
11
|
+
# @param [Apadmi::Grout::DefaultLogger] // or your own logger!
|
12
|
+
def initialize(git_utils, logger)
|
13
|
+
@git_utils = git_utils
|
14
|
+
@logger = logger
|
15
|
+
end
|
16
|
+
|
17
|
+
# Runs the action.
|
18
|
+
# @param current_version [String] The version of this release.
|
19
|
+
# @param suppress_error_versions [Array<String>] Errors from unmerged versions in this list will be suppressed
|
20
|
+
def run(current_version, suppress_error_versions)
|
21
|
+
@git_utils.fetch_all
|
22
|
+
|
23
|
+
@logger.message("Checking for unmerged versions")
|
24
|
+
@logger.message("Suppressing checks for versions: #{suppress_error_versions}") if suppress_error_versions
|
25
|
+
this_version = Semantic::Version.new current_version
|
26
|
+
versions = extract_non_ancestor_versions
|
27
|
+
suppressed = suppress_error_versions.map do |version|
|
28
|
+
Semantic::Version.new version
|
29
|
+
end
|
30
|
+
|
31
|
+
# Only older versions should cause errors since features in newer
|
32
|
+
# versions have legitimate reasons not to be in this release
|
33
|
+
versions.select do |version|
|
34
|
+
version < this_version && !suppressed.include?(version)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def extract_non_ancestor_versions
|
41
|
+
refs = @git_utils.list_tags(
|
42
|
+
"--no-merged"
|
43
|
+
) + @git_utils.branch(
|
44
|
+
" --list '*release*' '*hotfix*' --all --no-merged"
|
45
|
+
).split("\n")
|
46
|
+
|
47
|
+
version_strings = refs.map do |ref|
|
48
|
+
match = ref.match(/.*(\d+\.\d+\.\d.*)/)
|
49
|
+
match[1] if match
|
50
|
+
end.compact
|
51
|
+
@logger.message("Found versions to compare #{version_strings}")
|
52
|
+
version_strings.map do |version_string|
|
53
|
+
Semantic::Version.new version_string
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_jira_action.rb
CHANGED
@@ -39,7 +39,7 @@ module Apadmi
|
|
39
39
|
options = nil
|
40
40
|
)
|
41
41
|
custom_flag_messages ||= Apadmi::Grout::FlagMessages.default(status)
|
42
|
-
options ||= Apadmi::Grout::JiraFindTicketsOptions.new(include_no_sprint_tickets: false)
|
42
|
+
options ||= Apadmi::Grout::JiraFindTicketsOptions.new(include_no_sprint_tickets: false, inspect_prs: true)
|
43
43
|
|
44
44
|
issues = @jira_board_service.search_unblocked_issues(
|
45
45
|
component, status, [], options
|
@@ -55,11 +55,7 @@ module Apadmi
|
|
55
55
|
@git_utils.merge_changelog(issue_keys)
|
56
56
|
)
|
57
57
|
|
58
|
-
final_list = issues
|
59
|
-
# Decide whether to include this ticket based on PRs
|
60
|
-
status = process_prs(issue, custom_flag_messages)
|
61
|
-
decide_should_include(issue, status, changelog_ids)
|
62
|
-
end
|
58
|
+
final_list = filter_on_prs(changelog_ids, custom_flag_messages, issues, options)
|
63
59
|
|
64
60
|
@logger.message("Final list: #{final_list.map(&:key).join(", ")}")
|
65
61
|
final_list
|
@@ -67,6 +63,18 @@ module Apadmi
|
|
67
63
|
|
68
64
|
private
|
69
65
|
|
66
|
+
def filter_on_prs(changelog_ids, custom_flag_messages, issues, options)
|
67
|
+
if options.inspect_prs
|
68
|
+
issues.filter do |issue|
|
69
|
+
# Decide whether to include this ticket based on PRs
|
70
|
+
status = process_prs(issue, custom_flag_messages)
|
71
|
+
decide_should_include(issue, status, changelog_ids)
|
72
|
+
end
|
73
|
+
else
|
74
|
+
issues
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
70
78
|
# @param issue [Apadmi::Grout::Issue]
|
71
79
|
# @param pr_status [Int] status of whether or not we can move
|
72
80
|
# @param changelog_ids [Array<String>] the ticket ids pulled from git
|
data/lib/apadmi/grout/di.rb
CHANGED
@@ -27,7 +27,7 @@ module Apadmi
|
|
27
27
|
)
|
28
28
|
network_service = Apadmi::Grout::NetworkService.init_for_basic_auth(username, token, base_url)
|
29
29
|
jira_board_service = Apadmi::Grout::JiraBoardService.new(username, token, base_url, context_path, project, network_service)
|
30
|
-
git_utils = Apadmi::Grout::GitUtils
|
30
|
+
git_utils = Apadmi::Grout::GitUtils.new
|
31
31
|
issues_from_changelog_action = Apadmi::Grout::IssuesFromChangelogAction.new(jira_board_service, "#{project}-", logger)
|
32
32
|
|
33
33
|
DependencyInjector.new(
|
@@ -53,7 +53,7 @@ module Apadmi
|
|
53
53
|
ticket_prefix = "#"
|
54
54
|
network_service = Apadmi::Grout::NetworkService.init_for_basic_auth("", personal_access_token, base_url)
|
55
55
|
ado_board_service = Apadmi::Grout::AdoBoardService.new(network_service, ado_config, logger)
|
56
|
-
git_utils = Apadmi::Grout::GitUtils
|
56
|
+
git_utils = Apadmi::Grout::GitUtils.new
|
57
57
|
issues_from_changelog_action = Apadmi::Grout::IssuesFromChangelogAction.new(ado_board_service, ticket_prefix, logger)
|
58
58
|
|
59
59
|
DependencyInjector.new(
|
@@ -10,7 +10,7 @@ module Apadmi
|
|
10
10
|
|
11
11
|
BitriseBuild = Struct.new(:triggered_at, :slug, :status, :commit_hash) do
|
12
12
|
def finished_with_success
|
13
|
-
|
13
|
+
status == STATUS_SUCCESS
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -18,7 +18,7 @@ module Apadmi
|
|
18
18
|
|
19
19
|
TriggeredBitriseBuild = Struct.new(:build_number, :build_slug, :build_url, :message, :service, :slug, :status, :triggered_workflow) do
|
20
20
|
def finished_with_success
|
21
|
-
|
21
|
+
status == STATUS_SUCCESS
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.from_json(json)
|
@@ -7,11 +7,12 @@ module Apadmi
|
|
7
7
|
|
8
8
|
# Jira specific find tickets options
|
9
9
|
class JiraFindTicketsOptions < FindTicketsOptions
|
10
|
-
attr_reader :include_no_sprint_tickets
|
10
|
+
attr_reader :include_no_sprint_tickets, :inspect_prs
|
11
11
|
|
12
12
|
# @param include_no_sprint_tickets [String] whether or not to include tickets with no sprint assigned
|
13
|
-
def initialize(include_no_sprint_tickets: false)
|
13
|
+
def initialize(include_no_sprint_tickets: false, inspect_prs: true)
|
14
14
|
@include_no_sprint_tickets = include_no_sprint_tickets
|
15
|
+
@inspect_prs = inspect_prs
|
15
16
|
end
|
16
17
|
|
17
18
|
def ==(other)
|
@@ -19,7 +20,7 @@ module Apadmi
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def state
|
22
|
-
[@include_no_sprint_tickets]
|
23
|
+
[@include_no_sprint_tickets, @inspect_prs]
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
@@ -6,60 +6,140 @@ module Apadmi
|
|
6
6
|
module Grout
|
7
7
|
# Generic Git related utils
|
8
8
|
class GitUtils
|
9
|
+
def initialize(repo_path = nil)
|
10
|
+
@repo_path_arg = repo_path.nil? ? "" : " -C #{repo_path} "
|
11
|
+
end
|
12
|
+
|
13
|
+
# rubocop:disable Style/ClassVars:
|
14
|
+
@@default = Apadmi::Grout::GitUtils.new(nil)
|
15
|
+
# rubocop:enable Style/ClassVars:
|
16
|
+
|
9
17
|
# Gets the root of the Git repo we're in
|
10
18
|
# @return [String] The full path for the root of this Git repo
|
11
|
-
def
|
12
|
-
stdout, stderr, status = Open3.capture3("git rev-parse --show-toplevel")
|
19
|
+
def git_root
|
20
|
+
stdout, stderr, status = Open3.capture3("git #{@repo_path_arg} rev-parse --show-toplevel")
|
13
21
|
raise "Failed to get git root: #{stderr}" unless status.success?
|
14
22
|
|
15
23
|
stdout.strip
|
16
24
|
end
|
17
25
|
|
26
|
+
def self.git_root
|
27
|
+
@@default.git_root
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns all the tags in the repo
|
31
|
+
# @return [String[]] The tags
|
32
|
+
def list_tags(args = "")
|
33
|
+
stdout, stderr, status = Open3.capture3("git #{@repo_path_arg} tag --list #{args}")
|
34
|
+
raise "Failed to list tags: #{stderr}" unless status.success?
|
35
|
+
|
36
|
+
stdout.strip.split("\n")
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns all the tags in the repo
|
40
|
+
# @return [String[]] The tags
|
41
|
+
def self.list_tags(args = "")
|
42
|
+
@@default.list_tags(args)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Runs git branch command with given args
|
46
|
+
def branch(args = "")
|
47
|
+
stdout, stderr, status = Open3.capture3("git #{@repo_path_arg} branch #{args}")
|
48
|
+
raise "Failed to run branch: #{stderr}" unless status.success?
|
49
|
+
|
50
|
+
stdout.strip
|
51
|
+
end
|
52
|
+
|
53
|
+
# Runs git branch command with given args
|
54
|
+
def self.branch(args = "")
|
55
|
+
@@default.branch(args)
|
56
|
+
end
|
57
|
+
|
18
58
|
# Gets the commit hash of the current HEAD
|
19
|
-
def
|
20
|
-
stdout, stderr, status = Open3.capture3("git rev-parse HEAD")
|
59
|
+
def commit_hash
|
60
|
+
stdout, stderr, status = Open3.capture3("git #{@repo_path_arg} rev-parse HEAD")
|
21
61
|
raise "Failed to get hash: #{stderr}" unless status.success?
|
22
62
|
|
23
63
|
stdout.strip
|
24
64
|
end
|
25
65
|
|
66
|
+
# Gets the commit hash of the current HEAD
|
67
|
+
def self.commit_hash
|
68
|
+
@@default.commit_hash
|
69
|
+
end
|
70
|
+
|
26
71
|
# Gets the number of commits accessible from HEAD treating the history as a graph.
|
27
72
|
# See more details here: https://git-scm.com/docs/git-rev-list
|
28
73
|
# @return [String] The number of commits
|
29
|
-
def
|
30
|
-
|
74
|
+
def number_of_commits
|
75
|
+
raise "Repo is a shallow clone so this method will always return 1" if is_shallow_clone
|
76
|
+
|
77
|
+
stdout, stderr, status = Open3.capture3("git #{@repo_path_arg} rev-list HEAD --count")
|
31
78
|
raise "Failed to get commit number: #{stderr}" unless status.success?
|
32
79
|
|
33
80
|
stdout.strip
|
34
81
|
end
|
35
82
|
|
83
|
+
# Helper function to check if a repo is a shallow clone
|
84
|
+
# @return [Boolean] If the repo is a shallow clone
|
85
|
+
def is_shallow_clone
|
86
|
+
stdout, stderr, status = Open3.capture3("git #{@repo_path_arg} rev-parse --is-shallow-repository")
|
87
|
+
raise "Failed to check if repo is shallow clone: #{stderr}" unless status.success?
|
88
|
+
|
89
|
+
stdout.strip.downcase == "true"
|
90
|
+
end
|
91
|
+
|
92
|
+
# Gets the number of commits accessible from HEAD treating the history as a graph.
|
93
|
+
# See more details here: https://git-scm.com/docs/git-rev-list
|
94
|
+
# @return [String] The number of commits
|
95
|
+
def self.number_of_commits
|
96
|
+
@@default.number_of_commits
|
97
|
+
end
|
98
|
+
|
36
99
|
# Runs a git fetch all
|
37
|
-
def
|
38
|
-
stdout, stderr, status = Open3.capture3("git fetch --all")
|
100
|
+
def fetch_all
|
101
|
+
stdout, stderr, status = Open3.capture3("git #{@repo_path_arg} fetch --all")
|
39
102
|
raise "Failed to fetch #{stderr}" unless status.success?
|
40
103
|
|
41
104
|
stdout.strip
|
42
105
|
end
|
43
106
|
|
107
|
+
# Runs a git fetch all
|
108
|
+
def self.fetch_all
|
109
|
+
@@default.fetch_all
|
110
|
+
end
|
111
|
+
|
44
112
|
# Gets all the merges accessible from the current HEAD which matches at least one of the given grep conditions
|
45
113
|
# @param grep_conditions [Array<String>] values to be passed in as grep cases (https://git-scm.com/docs/git-log)
|
46
|
-
def
|
47
|
-
command = "git log HEAD --merges --format=%s#{grep_conditions.map { |c| " --grep #{c}" }.join(" ")}"
|
114
|
+
def merge_changelog(grep_conditions)
|
115
|
+
command = "git #{@repo_path_arg} log HEAD --merges --format=%s#{grep_conditions.map { |c| " --grep #{c}" }.join(" ")}"
|
48
116
|
stdout, stderr, status = Open3.capture3(command)
|
49
117
|
raise "Failed to get changelog: #{stderr}" unless status.success?
|
50
118
|
|
51
119
|
stdout
|
52
120
|
end
|
53
121
|
|
122
|
+
# Gets all the merges accessible from the current HEAD which matches at least one of the given grep conditions
|
123
|
+
# @param grep_conditions [Array<String>] values to be passed in as grep cases (https://git-scm.com/docs/git-log)
|
124
|
+
def self.merge_changelog(grep_conditions)
|
125
|
+
@@default.merge_changelog(grep_conditions)
|
126
|
+
end
|
127
|
+
|
54
128
|
# Gets all the merges that are NOT accessible from HEAD which matches at least one of the given grep conditions
|
55
129
|
# @param grep_conditions [Array<String>] values to be passed in as grep cases (https://git-scm.com/docs/git-log)
|
56
|
-
def
|
57
|
-
command = "git log --all ^HEAD --merges --format=%s#{grep_conditions.map { |c| " --grep #{c}" }.join(" ")}"
|
130
|
+
def invert_changelog(grep_conditions)
|
131
|
+
command = "git #{@repo_path_arg} log --all ^HEAD --merges --format=%s#{grep_conditions.map { |c| " --grep #{c}" }.join(" ")}"
|
58
132
|
stdout, stderr, status = Open3.capture3(command)
|
59
133
|
raise "Failed to get changelog: #{stderr}" unless status.success?
|
60
134
|
|
61
135
|
stdout
|
62
136
|
end
|
137
|
+
|
138
|
+
# Gets all the merges that are NOT accessible from HEAD which matches at least one of the given grep conditions
|
139
|
+
# @param grep_conditions [Array<String>] values to be passed in as grep cases (https://git-scm.com/docs/git-log)
|
140
|
+
def self.invert_changelog(grep_conditions)
|
141
|
+
@@default.invert_changelog(grep_conditions)
|
142
|
+
end
|
63
143
|
end
|
64
144
|
end
|
65
145
|
end
|
data/lib/apadmi/grout/version.rb
CHANGED
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: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Apadmi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: semantic
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.5.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.5.0
|
55
69
|
description: Apadmi build tool utils for use through Fastlane on Android and iOS.
|
56
70
|
email:
|
57
71
|
- samdc@apadmi.com
|
@@ -63,6 +77,7 @@ files:
|
|
63
77
|
- CODE_OF_CONDUCT.md
|
64
78
|
- LICENSE
|
65
79
|
- README.md
|
80
|
+
- lib/apadmi/grout/actions/check_unfinished_releases_action.rb
|
66
81
|
- lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_action.rb
|
67
82
|
- lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_ado_action.rb
|
68
83
|
- lib/apadmi/grout/actions/find_tickets_to_move_action/find_tickets_to_move_jira_action.rb
|
@@ -105,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
120
|
requirements:
|
106
121
|
- - ">="
|
107
122
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
123
|
+
version: 3.0.0
|
109
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
125
|
requirements:
|
111
126
|
- - ">="
|