standard_automation_library 0.2.1.pre.temp
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 +7 -0
- data/lib/standard_automation_library/api_clients/app_center.rb +104 -0
- data/lib/standard_automation_library/api_clients/bugsnag.rb +94 -0
- data/lib/standard_automation_library/api_clients/github.rb +371 -0
- data/lib/standard_automation_library/api_clients/jira.rb +326 -0
- data/lib/standard_automation_library/api_clients/pagerduty.rb +101 -0
- data/lib/standard_automation_library/api_clients/slack.rb +499 -0
- data/lib/standard_automation_library/danger/danger_jira.rb +169 -0
- data/lib/standard_automation_library/errors/slack_api_error.rb +6 -0
- data/lib/standard_automation_library/personnel/release_management_team.rb +85 -0
- data/lib/standard_automation_library/personnel/team.rb +41 -0
- data/lib/standard_automation_library/personnel/user.rb +68 -0
- data/lib/standard_automation_library/services/bugsnag_service.rb +251 -0
- data/lib/standard_automation_library/services/jira_service.rb +64 -0
- data/lib/standard_automation_library/services/merge_driver_service.rb +48 -0
- data/lib/standard_automation_library/services/mobile_tech_debt_logging_service.rb +176 -0
- data/lib/standard_automation_library/services/monorepo_platform_service.rb +18 -0
- data/lib/standard_automation_library/services/perf_tracker_logging_service.rb +87 -0
- data/lib/standard_automation_library/services/platform_service.rb +34 -0
- data/lib/standard_automation_library/services/repo_service.rb +17 -0
- data/lib/standard_automation_library/services/slack_service.rb +383 -0
- data/lib/standard_automation_library/util/automerge_configuration.rb +134 -0
- data/lib/standard_automation_library/util/bundler.rb +18 -0
- data/lib/standard_automation_library/util/datetime_helper.rb +23 -0
- data/lib/standard_automation_library/util/file_content.rb +15 -0
- data/lib/standard_automation_library/util/git.rb +235 -0
- data/lib/standard_automation_library/util/git_merge_error_message_cleaner.rb +27 -0
- data/lib/standard_automation_library/util/network.rb +39 -0
- data/lib/standard_automation_library/util/path_container.rb +17 -0
- data/lib/standard_automation_library/util/platform_picker.rb +150 -0
- data/lib/standard_automation_library/util/shared_constants.rb +27 -0
- data/lib/standard_automation_library/util/shell_helper.rb +54 -0
- data/lib/standard_automation_library/util/slack_constants.rb +40 -0
- data/lib/standard_automation_library/util/version.rb +31 -0
- data/lib/standard_automation_library/version.rb +5 -0
- data/lib/standard_automation_library.rb +8 -0
- metadata +296 -0
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'datadog_api_client'
|
3
|
+
|
4
|
+
# Sends repo/source file count data to Datadog for modularization tracking:
|
5
|
+
# https://app.datadoghq.com/dashboard/pep-25j-j3d/build-mobile-modularization-dashboard
|
6
|
+
class MobileTechDebtLoggingService
|
7
|
+
SOURCE = 'build_mobile_tech_debt'.freeze
|
8
|
+
SERVICE = 'build-mobile'.freeze
|
9
|
+
|
10
|
+
# @param [DatadogAPIClient::V2::LogsAPI] logs_client A DotaDog logs API client
|
11
|
+
def initialize(logs_client)
|
12
|
+
@logs_api = logs_client
|
13
|
+
submit_pgf_logs
|
14
|
+
submit_ios_logs
|
15
|
+
submit_android_logs
|
16
|
+
end
|
17
|
+
|
18
|
+
# Generate PGF data and send logs
|
19
|
+
def submit_pgf_logs
|
20
|
+
@pgf_legacy_file_count = Dir.glob('../../pgf/legacy/src/**/*.kt').length
|
21
|
+
@pgf_repositories = Dir.glob('../../pgf/**/*Repository.kt')
|
22
|
+
# For each module in pgf, send log with the module name + total count of .kt files
|
23
|
+
@pgf_folder_paths = Dir.glob('../../pgf/**')
|
24
|
+
@pgf_folder_names = []
|
25
|
+
# Get each module name
|
26
|
+
@pgf_folder_paths.each do |folder_path|
|
27
|
+
next unless File.directory?(folder_path)
|
28
|
+
next if folder_path.include? 'pgf/feature'
|
29
|
+
|
30
|
+
@pgf_folder_names.push(
|
31
|
+
folder_path.slice(folder_path.rindex('/') + 1, folder_path.length)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
# Get file count for each module
|
35
|
+
@pgf_folder_names.each do |name|
|
36
|
+
@pgf_repositories.each do |file_path|
|
37
|
+
next unless file_path.include? "../../pgf/#{name}"
|
38
|
+
end
|
39
|
+
@pgf_file_count = Dir.glob("../../pgf/#{name}/**/*.kt").length
|
40
|
+
_submit_pgf_logs(name, @pgf_file_count)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Repeat for submodules inside feature module
|
44
|
+
# Get each module name inside pgf/feature
|
45
|
+
@pgf_feature_paths = Dir.glob('../../pgf/feature/**')
|
46
|
+
@pgf_feature_folder_names = []
|
47
|
+
@pgf_feature_paths.each do |folder_path|
|
48
|
+
next unless File.directory?(folder_path)
|
49
|
+
|
50
|
+
@pgf_feature_folder_names.push(
|
51
|
+
folder_path.slice(folder_path.rindex('/') + 1, folder_path.length)
|
52
|
+
)
|
53
|
+
end
|
54
|
+
# Get file count for each module
|
55
|
+
@pgf_feature_folder_names.each do |name|
|
56
|
+
@pgf_repositories.each do |file_path|
|
57
|
+
next unless file_path.include? "../../pgf/feature/#{name}"
|
58
|
+
end
|
59
|
+
@pgf_feature_file_count = Dir.glob("../../pgf/feature/#{name}/**/*.kt").length
|
60
|
+
_submit_pgf_logs(name, @pgf_feature_file_count)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Generate Android data and send logs
|
65
|
+
def submit_android_logs
|
66
|
+
@android_app_module_source_file_count = Dir.glob('../../android/app/src/main/**/*.kt').length +
|
67
|
+
Dir.glob('../../android/app/src/main/**/*.java').length
|
68
|
+
|
69
|
+
# Get the name of each submodule inside the Android folder
|
70
|
+
@android_folder_paths = Dir.glob('../../android/**')
|
71
|
+
@android_folder_names = []
|
72
|
+
@android_folder_paths.each do |folder_path|
|
73
|
+
next unless File.directory?(folder_path)
|
74
|
+
|
75
|
+
@android_folder_names.push(
|
76
|
+
folder_path.slice(folder_path.rindex('/') + 1, folder_path.length)
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
# If submodule contains .kt files, send log with the name + total count of .kt files
|
81
|
+
@android_folder_names.each do |name|
|
82
|
+
@folder_count = Dir.glob("../../android/#{name}/**/*.kt").length
|
83
|
+
next unless @folder_count.positive?
|
84
|
+
|
85
|
+
_submit_android_logs(name, @folder_count)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Generate iOS data and send logs
|
90
|
+
def submit_ios_logs
|
91
|
+
@ios_source_file_count = Dir.glob('../../ios/PlanGrid/PlanGrid/**/*.swift').length +
|
92
|
+
Dir.glob('../../ios/PlanGrid/PlanGrid/**/*.m').length
|
93
|
+
|
94
|
+
@ios_project_paths = Dir.glob('../../ios/**')
|
95
|
+
@ios_projects = []
|
96
|
+
@ios_project_paths.each do |path|
|
97
|
+
next unless File.directory?(path)
|
98
|
+
|
99
|
+
@ios_projects.push(
|
100
|
+
path.slice(path.rindex('/') + 1, path.length)
|
101
|
+
)
|
102
|
+
end
|
103
|
+
@ios_default_projects = ['PGSharedTestUtils', 'PlanGrid.xcworkspace', 'Pods', 'scripts', 'fastlane', +
|
104
|
+
'AlloyComponents', 'jenkins', 'danger']
|
105
|
+
|
106
|
+
@ios_projects.each do |name|
|
107
|
+
next if @ios_default_projects.include? name
|
108
|
+
|
109
|
+
@ios_file_count = Dir.glob("../../ios/#{name}/**/*.swift").length + \
|
110
|
+
Dir.glob("../../ios/#{name}/**/*.m").length
|
111
|
+
_submit_ios_logs(name, @ios_file_count)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def _submit_pgf_logs(pgf_module_name, pgf_file_count)
|
118
|
+
body = generate_pgf_http_log_items(pgf_module_name, pgf_file_count)
|
119
|
+
p body
|
120
|
+
p @logs_api.submit_log(body)
|
121
|
+
end
|
122
|
+
|
123
|
+
def generate_pgf_http_log_items(pgf_module_name, pgf_file_count)
|
124
|
+
DatadogAPIClient::V2::HTTPLogItem.new(
|
125
|
+
{
|
126
|
+
ddsource: SOURCE,
|
127
|
+
service: SERVICE,
|
128
|
+
build_mobile_tech_debt_pgf_info: {
|
129
|
+
pgf_module: pgf_module_name,
|
130
|
+
pgf_module_file_count: pgf_file_count,
|
131
|
+
pgf_legacy_file_count: @pgf_legacy_file_count
|
132
|
+
}
|
133
|
+
}
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
def _submit_android_logs(android_module_name, folder_count)
|
138
|
+
body = generate_android_http_log_items(android_module_name, folder_count)
|
139
|
+
p body
|
140
|
+
p @logs_api.submit_log(body)
|
141
|
+
end
|
142
|
+
|
143
|
+
def generate_android_http_log_items(android_module_name, folder_count)
|
144
|
+
DatadogAPIClient::V2::HTTPLogItem.new(
|
145
|
+
{
|
146
|
+
ddsource: SOURCE,
|
147
|
+
service: SERVICE,
|
148
|
+
build_mobile_tech_debt_android_info: {
|
149
|
+
android_module: android_module_name,
|
150
|
+
android_module_file_count: folder_count,
|
151
|
+
android_app_module_source_file_count: @android_app_module_source_file_count
|
152
|
+
}
|
153
|
+
}
|
154
|
+
)
|
155
|
+
end
|
156
|
+
|
157
|
+
def _submit_ios_logs(ios_project_name, ios_file_count)
|
158
|
+
body = generate_ios_http_log_items(ios_project_name, ios_file_count)
|
159
|
+
p body
|
160
|
+
p @logs_api.submit_log(body)
|
161
|
+
end
|
162
|
+
|
163
|
+
def generate_ios_http_log_items(ios_project_name, ios_file_count)
|
164
|
+
DatadogAPIClient::V2::HTTPLogItem.new(
|
165
|
+
{
|
166
|
+
ddsource: SOURCE,
|
167
|
+
service: SERVICE,
|
168
|
+
build_mobile_tech_debt_ios_info: {
|
169
|
+
ios_source_file_count: @ios_source_file_count,
|
170
|
+
ios_project_name: ios_project_name,
|
171
|
+
ios_project_file_count: ios_file_count
|
172
|
+
}
|
173
|
+
}
|
174
|
+
)
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'platform_service'
|
2
|
+
|
3
|
+
# Abstract class that defines even more methods that
|
4
|
+
# a platform service must implement if it is part of the
|
5
|
+
# monorepo
|
6
|
+
class MonorepoPlatformService < PlatformService
|
7
|
+
def automerge_configuration; end
|
8
|
+
|
9
|
+
def branching_model; end
|
10
|
+
|
11
|
+
def release_manager_team; end
|
12
|
+
|
13
|
+
def released_version; end
|
14
|
+
|
15
|
+
def slack_channels; end
|
16
|
+
|
17
|
+
def version_bump_modification; end
|
18
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'datadog_api_client'
|
3
|
+
require 'csv'
|
4
|
+
|
5
|
+
# Sends perf tracking logs to an analytics service (DataDog).
|
6
|
+
# Related Jenkins job: https://c05-acs.jenkins.autodesk.com/job/ACS/job/Custom-Deploy-Tasks/job/Mobile-Common/job/Mobile-Performance-Tracker/
|
7
|
+
class PerfTrackerLoggingService
|
8
|
+
VERSION = 0.1
|
9
|
+
SOURCE = 'build_mobile_perf_tracking'.freeze
|
10
|
+
SERVICE = 'Custom-Deploy-Tasks/Build-Mobile-Performance-Tracker'.freeze
|
11
|
+
|
12
|
+
#############################
|
13
|
+
# Sample benchmark.csv file #
|
14
|
+
#############################
|
15
|
+
#
|
16
|
+
# scenario,incremental_build_abi_change_android_app_module,incremental_build_abi_change_pgf_module
|
17
|
+
# version,Gradle 7.5,Gradle 7.5
|
18
|
+
# tasks,assembleAltDebug,:pgf:assembleDebug
|
19
|
+
# value,total execution time,total execution time
|
20
|
+
# warm-up build #1,510100,89209
|
21
|
+
# measured build #1,252134,59647
|
22
|
+
# measured build #2,254684,55937
|
23
|
+
|
24
|
+
SCENARIO = 0
|
25
|
+
BUILD_SYSTEM = 1
|
26
|
+
TASKS = 2
|
27
|
+
VALUE = 3
|
28
|
+
|
29
|
+
WARM_UP_BUILD = 'warm-up build #'.freeze
|
30
|
+
MEASURED_BUILD = 'measured build #'.freeze
|
31
|
+
# TODO: pass this filepath as an argument to this script
|
32
|
+
BENCHMARK_CSV_FILEPATH = '../../profile-out/benchmark.csv'.freeze
|
33
|
+
|
34
|
+
MS_TO_MINS_FACTOR = 1.0 / 1000 / 60
|
35
|
+
|
36
|
+
# @param [DatadogAPIClient::V2::LogsAPI] logs_client A DotaDog logs API client
|
37
|
+
def initialize(logs_client)
|
38
|
+
@logs_api = logs_client
|
39
|
+
end
|
40
|
+
|
41
|
+
def submit_logs
|
42
|
+
_submit_logs(BENCHMARK_CSV_FILEPATH)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def _submit_logs(benchmark_filepath)
|
48
|
+
benchmark = CSV.read(benchmark_filepath)
|
49
|
+
body = generate_http_log_items(benchmark)
|
50
|
+
p body
|
51
|
+
p @logs_api.submit_log(body)
|
52
|
+
end
|
53
|
+
|
54
|
+
def generate_http_log_items(benchmark)
|
55
|
+
scenarios = benchmark[SCENARIO]
|
56
|
+
body = []
|
57
|
+
scenarios.each_with_index do |scenario_name, scenario_index|
|
58
|
+
next unless scenario_index.positive?
|
59
|
+
|
60
|
+
num_of_runs = 0
|
61
|
+
running_total_in_ms = 0
|
62
|
+
benchmark.each do |row|
|
63
|
+
if row[0].start_with?(MEASURED_BUILD)
|
64
|
+
num_of_runs += 1
|
65
|
+
running_total_in_ms += row[scenario_index].to_i
|
66
|
+
end
|
67
|
+
end
|
68
|
+
average_time_in_mins = (running_total_in_ms * MS_TO_MINS_FACTOR) / num_of_runs
|
69
|
+
body.push(
|
70
|
+
DatadogAPIClient::V2::HTTPLogItem.new(
|
71
|
+
{
|
72
|
+
ddsource: SOURCE,
|
73
|
+
ddtags: "version:#{VERSION}",
|
74
|
+
service: SERVICE,
|
75
|
+
perf_info: {
|
76
|
+
build_system: benchmark[BUILD_SYSTEM][scenario_index],
|
77
|
+
scenario_name: scenario_name,
|
78
|
+
average_time: average_time_in_mins,
|
79
|
+
tasks: benchmark[TASKS][scenario_index]
|
80
|
+
}
|
81
|
+
}
|
82
|
+
)
|
83
|
+
)
|
84
|
+
end
|
85
|
+
body
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Abstract class for a set of common functions
|
2
|
+
# each platform needs to implement. Keep
|
3
|
+
# alphabetized.
|
4
|
+
class PlatformService
|
5
|
+
ORIGIN_REMOTE_NAME = 'origin'.freeze
|
6
|
+
|
7
|
+
def app_version(git_ref = nil); end
|
8
|
+
|
9
|
+
def dry_run?; end
|
10
|
+
|
11
|
+
# absolute path to gemfile
|
12
|
+
def gemfile_path; end
|
13
|
+
|
14
|
+
def platform_name; end
|
15
|
+
|
16
|
+
def release_name(release_identifier)
|
17
|
+
release_identifier
|
18
|
+
end
|
19
|
+
|
20
|
+
def remote_branch(branch_name)
|
21
|
+
"#{remote_repository_name}/#{branch_name}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def remote_repository_name
|
25
|
+
ORIGIN_REMOTE_NAME
|
26
|
+
end
|
27
|
+
|
28
|
+
def repo_name; end
|
29
|
+
|
30
|
+
def update_app_version(new_app_version); end
|
31
|
+
|
32
|
+
# File path is an absolute path
|
33
|
+
def version_file_path; end
|
34
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# class for housing repository related information
|
2
|
+
class RepositoryService
|
3
|
+
ORIGIN_REMOTE_NAME = 'origin'.freeze
|
4
|
+
|
5
|
+
def initialize(repository_name, remote_repository_name = ORIGIN_REMOTE_NAME)
|
6
|
+
@repository_name = repository_name
|
7
|
+
@remote_repository_name = remote_repository_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def remote_branch(branch_name)
|
11
|
+
"#{remote_repository_name}/#{branch_name}"
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :remote_repository_name
|
15
|
+
|
16
|
+
attr_reader :repository_name
|
17
|
+
end
|