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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/lib/standard_automation_library/api_clients/app_center.rb +104 -0
  3. data/lib/standard_automation_library/api_clients/bugsnag.rb +94 -0
  4. data/lib/standard_automation_library/api_clients/github.rb +371 -0
  5. data/lib/standard_automation_library/api_clients/jira.rb +326 -0
  6. data/lib/standard_automation_library/api_clients/pagerduty.rb +101 -0
  7. data/lib/standard_automation_library/api_clients/slack.rb +499 -0
  8. data/lib/standard_automation_library/danger/danger_jira.rb +169 -0
  9. data/lib/standard_automation_library/errors/slack_api_error.rb +6 -0
  10. data/lib/standard_automation_library/personnel/release_management_team.rb +85 -0
  11. data/lib/standard_automation_library/personnel/team.rb +41 -0
  12. data/lib/standard_automation_library/personnel/user.rb +68 -0
  13. data/lib/standard_automation_library/services/bugsnag_service.rb +251 -0
  14. data/lib/standard_automation_library/services/jira_service.rb +64 -0
  15. data/lib/standard_automation_library/services/merge_driver_service.rb +48 -0
  16. data/lib/standard_automation_library/services/mobile_tech_debt_logging_service.rb +176 -0
  17. data/lib/standard_automation_library/services/monorepo_platform_service.rb +18 -0
  18. data/lib/standard_automation_library/services/perf_tracker_logging_service.rb +87 -0
  19. data/lib/standard_automation_library/services/platform_service.rb +34 -0
  20. data/lib/standard_automation_library/services/repo_service.rb +17 -0
  21. data/lib/standard_automation_library/services/slack_service.rb +383 -0
  22. data/lib/standard_automation_library/util/automerge_configuration.rb +134 -0
  23. data/lib/standard_automation_library/util/bundler.rb +18 -0
  24. data/lib/standard_automation_library/util/datetime_helper.rb +23 -0
  25. data/lib/standard_automation_library/util/file_content.rb +15 -0
  26. data/lib/standard_automation_library/util/git.rb +235 -0
  27. data/lib/standard_automation_library/util/git_merge_error_message_cleaner.rb +27 -0
  28. data/lib/standard_automation_library/util/network.rb +39 -0
  29. data/lib/standard_automation_library/util/path_container.rb +17 -0
  30. data/lib/standard_automation_library/util/platform_picker.rb +150 -0
  31. data/lib/standard_automation_library/util/shared_constants.rb +27 -0
  32. data/lib/standard_automation_library/util/shell_helper.rb +54 -0
  33. data/lib/standard_automation_library/util/slack_constants.rb +40 -0
  34. data/lib/standard_automation_library/util/version.rb +31 -0
  35. data/lib/standard_automation_library/version.rb +5 -0
  36. data/lib/standard_automation_library.rb +8 -0
  37. 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