gitlab-qa 9.1.2 → 10.1.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +106 -149
  3. data/.simplecov +9 -0
  4. data/Gemfile.lock +15 -1
  5. data/README.md +5 -4
  6. data/docs/what_tests_can_be_run.md +73 -35
  7. data/gitlab-qa.gemspec +3 -0
  8. data/lib/gitlab/qa/component/base.rb +8 -1
  9. data/lib/gitlab/qa/component/gitaly.rb +1 -1
  10. data/lib/gitlab/qa/component/gitlab.rb +2 -2
  11. data/lib/gitlab/qa/component/mock_server.rb +13 -0
  12. data/lib/gitlab/qa/report/gitlab_issue_client.rb +1 -1
  13. data/lib/gitlab/qa/report/relate_failure_issue.rb +116 -20
  14. data/lib/gitlab/qa/report/report_as_issue.rb +1 -1
  15. data/lib/gitlab/qa/report/test_result.rb +2 -1
  16. data/lib/gitlab/qa/reporter.rb +8 -0
  17. data/lib/gitlab/qa/runtime/env.rb +17 -4
  18. data/lib/gitlab/qa/runtime/omnibus_configurations/decomposition_multiple_db.rb +1 -1
  19. data/lib/gitlab/qa/scenario/test/integration/oauth.rb +68 -0
  20. data/lib/gitlab/qa/scenario/test/omnibus/update_from_previous.rb +3 -2
  21. data/lib/gitlab/qa/system_logs/finders/json_log_finder.rb +65 -0
  22. data/lib/gitlab/qa/system_logs/finders/rails/api_log_finder.rb +21 -0
  23. data/lib/gitlab/qa/system_logs/finders/rails/application_log_finder.rb +21 -0
  24. data/lib/gitlab/qa/system_logs/finders/rails/exception_log_finder.rb +21 -0
  25. data/lib/gitlab/qa/system_logs/finders/rails/graphql_log_finder.rb +21 -0
  26. data/lib/gitlab/qa/system_logs/log_types/log.rb +38 -0
  27. data/lib/gitlab/qa/system_logs/log_types/rails/api_log.rb +34 -0
  28. data/lib/gitlab/qa/system_logs/log_types/rails/application_log.rb +27 -0
  29. data/lib/gitlab/qa/system_logs/log_types/rails/exception_log.rb +23 -0
  30. data/lib/gitlab/qa/system_logs/log_types/rails/graphql_log.rb +30 -0
  31. data/lib/gitlab/qa/system_logs/shared_fields.rb +29 -0
  32. data/lib/gitlab/qa/system_logs/system_logs_formatter.rb +65 -0
  33. data/lib/gitlab/qa/version.rb +1 -1
  34. data/scripts/build-package-and-test-env +15 -0
  35. metadata +59 -47
  36. data/.gitlab/ci/jobs/airgapped.gitlab-ci.yml +0 -23
  37. data/.gitlab/ci/jobs/base.gitlab-ci.yml +0 -273
  38. data/.gitlab/ci/jobs/chaos.gitlab-ci.yml +0 -22
  39. data/.gitlab/ci/jobs/cloud_activation.gitlab-ci.yml +0 -24
  40. data/.gitlab/ci/jobs/custom_parallel.gitlab-ci.yml +0 -21
  41. data/.gitlab/ci/jobs/decomposition_multiple_db.gitlab-ci.yml +0 -27
  42. data/.gitlab/ci/jobs/decomposition_single_db.gitlab-ci.yml +0 -25
  43. data/.gitlab/ci/jobs/ee_previous_to_ce_update.gitlab-ci.yml +0 -18
  44. data/.gitlab/ci/jobs/elasticsearch.gitlab-ci.yml +0 -20
  45. data/.gitlab/ci/jobs/geo.gitlab-ci.yml +0 -18
  46. data/.gitlab/ci/jobs/gitaly_cluster.gitlab-ci.yml +0 -41
  47. data/.gitlab/ci/jobs/gitlab_pages.gitlab-ci.yml +0 -19
  48. data/.gitlab/ci/jobs/group_saml.gitlab-ci.yml +0 -20
  49. data/.gitlab/ci/jobs/instance.gitlab-ci.yml +0 -55
  50. data/.gitlab/ci/jobs/instance_saml.gitlab-ci.yml +0 -41
  51. data/.gitlab/ci/jobs/integrations.gitlab-ci.yml +0 -14
  52. data/.gitlab/ci/jobs/jira.gitlab-ci.yml +0 -41
  53. data/.gitlab/ci/jobs/large_setup.gitlab-ci.yml +0 -19
  54. data/.gitlab/ci/jobs/ldap_no_server.gitlab-ci.yml +0 -20
  55. data/.gitlab/ci/jobs/ldap_no_tls.gitlab-ci.yml +0 -41
  56. data/.gitlab/ci/jobs/ldap_tls.gitlab-ci.yml +0 -41
  57. data/.gitlab/ci/jobs/mattermost.gitlab-ci.yml +0 -41
  58. data/.gitlab/ci/jobs/metrics.gitlab-ci.yml +0 -41
  59. data/.gitlab/ci/jobs/mtls.gitlab-ci.yml +0 -19
  60. data/.gitlab/ci/jobs/object_storage.gitlab-ci.yml +0 -49
  61. data/.gitlab/ci/jobs/object_storage_aws.gitlab-ci.yml +0 -25
  62. data/.gitlab/ci/jobs/object_storage_gcs.gitlab-ci.yml +0 -23
  63. data/.gitlab/ci/jobs/object_storage_registry_tls.gitlab-ci.yml +0 -41
  64. data/.gitlab/ci/jobs/omnibus_image.gitlab-ci.yml +0 -15
  65. data/.gitlab/ci/jobs/omnibus_upgrade.gitlab-ci.yml +0 -28
  66. data/.gitlab/ci/jobs/opensearch.gitlab-ci.yml +0 -20
  67. data/.gitlab/ci/jobs/packages.gitlab-ci.yml +0 -25
  68. data/.gitlab/ci/jobs/praefect.gitlab-ci.yml +0 -71
  69. data/.gitlab/ci/jobs/registry.gitlab-ci.yml +0 -41
  70. data/.gitlab/ci/jobs/registry_with_cdn.gitlab-ci.yml +0 -55
  71. data/.gitlab/ci/jobs/relative_url.gitlab-ci.yml +0 -65
  72. data/.gitlab/ci/jobs/repository_storage.gitlab-ci.yml +0 -41
  73. data/.gitlab/ci/jobs/sanity_framework.gitlab-ci.yml +0 -24
  74. data/.gitlab/ci/jobs/service_ping_disabled.gitlab-ci.yml +0 -19
  75. data/.gitlab/ci/jobs/smtp.gitlab-ci.yml +0 -19
  76. data/.gitlab/ci/jobs/staging.gitlab-ci.yml +0 -10
  77. data/.gitlab/ci/jobs/update.gitlab-ci.yml +0 -60
  78. data/.gitlab/ci/rules.gitlab-ci.yml +0 -183
  79. data/lib/gitlab/qa/scenario/test/omnibus/update.rb +0 -72
  80. data/scripts/generate-qa-jobs.rb +0 -99
@@ -1,183 +0,0 @@
1
- ##############
2
- # Conditions #
3
- ##############
4
- .if-default-refs-or-ce: &if-default-refs-or-ce
5
- if: '$RELEASE == null || $RELEASE == "" || $RELEASE =~ /gitlab-ce/ || $CI_MERGE_REQUEST_ID || $CI_COMMIT_REF_NAME == "master"'
6
-
7
- .if-default-refs-or-ee: &if-default-refs-or-ee
8
- if: '$RELEASE == null || $RELEASE == "" || $RELEASE =~ /gitlab-ee/ || $CI_MERGE_REQUEST_ID || $CI_COMMIT_REF_NAME == "master"'
9
-
10
- .if-default-refs-or-ce-or-ee: &if-default-refs-or-ce-or-ee
11
- if: '$RELEASE == null || $RELEASE == "" || $RELEASE =~ /gitlab-ce|gitlab-ee/ || $CI_MERGE_REQUEST_ID || $CI_COMMIT_REF_NAME == "master"'
12
-
13
- # In trigger jobs, such as `trigger-generated-jobs`, if a variable does not have a value set, the job will receive it literally as is i.e., "$RELEASE" in this case.
14
- .if-not-gitlab-qa-release: &if-not-gitlab-qa-release
15
- if: '$CI_SERVER_HOST == "gitlab.com" && $CI_PROJECT_PATH == "gitlab-org/gitlab-qa" && ($RELEASE == null || $RELEASE == "" || $RELEASE == "$RELEASE")'
16
-
17
- .if-staging-and-not-release: &if-staging-and-not-release
18
- if: '($RELEASE == null || $RELEASE == "") && $CI_JOB_NAME =~ /staging/'
19
-
20
- .if-quarantine-or-custom-and-not-release: &if-quarantine-or-custom-and-not-release
21
- if: '($RELEASE == null || $RELEASE == "") && $CI_JOB_NAME =~ /quarantine|custom/'
22
-
23
- .if-quarantine-or-custom-and-ee-release: &if-quarantine-or-custom-and-ee-release
24
- if: '$RELEASE =~ /gitlab-ee/ && $CI_JOB_NAME =~ /quarantine|custom/'
25
-
26
- .if-quarantine-or-custom-and-ce-release: &if-quarantine-or-custom-and-ce-release
27
- if: '$RELEASE =~ /gitlab-ce/ && $CI_JOB_NAME =~ /quarantine|custom/'
28
-
29
- .if-quarantine-or-custom-and-merge-request: &if-quarantine-or-custom-and-merge-request
30
- if: '$CI_MERGE_REQUEST_ID && $CI_JOB_NAME =~ /quarantine|custom/'
31
-
32
- .if-tag-or-ee-release: &if-tag-or-ee-release
33
- if: '$CI_COMMIT_TAG || $RELEASE =~ /gitlab-ee/'
34
-
35
- .if-tag-or-ce-release: &if-tag-or-ce-release
36
- if: '$CI_COMMIT_TAG || $RELEASE =~ /gitlab-ce/'
37
-
38
- .if-tag-or-release: &if-tag-or-release
39
- if: '$CI_COMMIT_TAG || ($RELEASE != null && $RELEASE != "")'
40
-
41
- .if-set-feature-flag: &if-set-feature-flag
42
- if: '$GITLAB_QA_OPTIONS =~ /--set-feature-flags/'
43
-
44
- .if-qa-tests-specified: &if-qa-tests-specified
45
- if: '$QA_TESTS != null && $QA_TESTS != ""'
46
-
47
- .if-qa-tests-not-specified: &if-qa-tests-not-specified
48
- if: '$QA_TESTS == null || $QA_TESTS == ""'
49
-
50
- #########
51
- # Rules #
52
- #########
53
-
54
- .rules:ce-qa:
55
- rules:
56
- - <<: *if-not-gitlab-qa-release
57
- changes: ["lib/**/version.rb"]
58
- when: never
59
- - <<: *if-tag-or-ee-release
60
- when: never
61
- - <<: *if-quarantine-or-custom-and-not-release
62
- when: manual
63
- - <<: *if-quarantine-or-custom-and-ce-release
64
- when: manual
65
- - <<: *if-quarantine-or-custom-and-merge-request
66
- when: manual
67
- - <<: *if-default-refs-or-ce
68
-
69
- .rules:ee-qa:
70
- rules:
71
- - <<: *if-not-gitlab-qa-release
72
- changes: ["lib/**/version.rb"]
73
- when: never
74
- - <<: *if-tag-or-ce-release
75
- when: never
76
- - <<: *if-quarantine-or-custom-and-not-release
77
- when: manual
78
- - <<: *if-quarantine-or-custom-and-ee-release
79
- when: manual
80
- - <<: *if-quarantine-or-custom-and-merge-request
81
- when: manual
82
- - <<: *if-default-refs-or-ee
83
-
84
- .rules:never-on-version-change-or-tag:
85
- rules:
86
- - <<: *if-not-gitlab-qa-release
87
- changes: ["lib/**/version.rb"]
88
- when: never
89
- - if: '$CI_COMMIT_TAG'
90
- when: never
91
- - <<: *if-default-refs-or-ce-or-ee
92
-
93
- .rules:only-qa:
94
- rules:
95
- - <<: *if-not-gitlab-qa-release
96
- changes: ["lib/**/version.rb"]
97
- when: never
98
- - <<: *if-tag-or-release
99
- when: never
100
- - <<: *if-staging-and-not-release
101
- when: manual
102
-
103
- .rules:ce-never-when-triggered-by-feature-flag-definition-change:
104
- rules:
105
- - <<: *if-set-feature-flag
106
- when: never
107
- - !reference [".rules:ce-qa", rules]
108
-
109
- .rules:ee-never-when-triggered-by-feature-flag-definition-change:
110
- rules:
111
- - <<: *if-set-feature-flag
112
- when: never
113
- - !reference [".rules:ee-qa", rules]
114
-
115
- .rules:only-qa-never-when-triggered-by-feature-flag-definition-change:
116
- rules:
117
- - <<: *if-set-feature-flag
118
- when: never
119
- - !reference [".rules:only-qa", rules]
120
-
121
- # === When QA_TESTS variable has a value ===
122
-
123
- .rules:ce-never-when-qa-tests-specified:
124
- rules:
125
- - <<: *if-qa-tests-specified
126
- when: never
127
- - !reference [".rules:ce-qa", rules]
128
-
129
- .rules:ee-never-when-qa-tests-specified:
130
- rules:
131
- - <<: *if-qa-tests-specified
132
- when: never
133
- - !reference [".rules:ee-qa", rules]
134
-
135
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified:
136
- rules:
137
- - <<: *if-qa-tests-specified
138
- when: never
139
- - !reference [".rules:ce-never-when-triggered-by-feature-flag-definition-change", rules]
140
-
141
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified:
142
- rules:
143
- - <<: *if-qa-tests-specified
144
- when: never
145
- - !reference [".rules:ee-never-when-triggered-by-feature-flag-definition-change", rules]
146
-
147
- .rules:only-qa-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified:
148
- rules:
149
- - <<: *if-qa-tests-specified
150
- when: never
151
- - !reference [".rules:only-qa-never-when-triggered-by-feature-flag-definition-change", rules]
152
-
153
- # === When QA_TESTS variable does not have a value ===
154
-
155
- .rules:ce-never-when-qa-tests-not-specified:
156
- rules:
157
- - <<: *if-qa-tests-not-specified
158
- when: never
159
- - !reference [".rules:ce-qa", rules]
160
-
161
- .rules:ee-never-when-qa-tests-not-specified:
162
- rules:
163
- - <<: *if-qa-tests-not-specified
164
- when: never
165
- - !reference [".rules:ee-qa", rules]
166
-
167
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified:
168
- rules:
169
- - <<: *if-qa-tests-not-specified
170
- when: never
171
- - !reference [".rules:ce-never-when-triggered-by-feature-flag-definition-change", rules]
172
-
173
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified:
174
- rules:
175
- - <<: *if-qa-tests-not-specified
176
- when: never
177
- - !reference [".rules:ee-never-when-triggered-by-feature-flag-definition-change", rules]
178
-
179
- .rules:only-qa-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified:
180
- rules:
181
- - <<: *if-qa-tests-not-specified
182
- when: never
183
- - !reference [".rules:only-qa-never-when-triggered-by-feature-flag-definition-change", rules]
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'tmpdir'
4
- require 'fileutils'
5
-
6
- module Gitlab
7
- module QA
8
- module Scenario
9
- module Test
10
- module Omnibus
11
- class Update < Scenario::Template
12
- def perform(from_release, to_release = nil, *rspec_args)
13
- version = Component::Gitlab.perform do |gitlab|
14
- gitlab.release = from_release
15
- gitlab.act do
16
- pull
17
- package_version
18
- end
19
- end
20
-
21
- if version
22
- # Sub any plus symbols in version eg. "15.1.2+ce.0"
23
- version.tr!('+', '-')
24
- Runtime::Logger.info("Found previous version '#{version}'")
25
-
26
- current_release = QA::Release.new(to_release || from_release)
27
-
28
- type = current_release.ee? ? 'ee' : 'ce'
29
-
30
- existing_previous = Component::Gitlab.perform do |gitlab|
31
- gitlab.act do
32
- next "gitlab/gitlab-#{type}:#{version}" if exist?("gitlab/gitlab-#{type}", version)
33
-
34
- next "gitlab/gitlab-#{type}:#{version}-#{type}.0" if exist?("gitlab/gitlab-#{type}", "#{version}-#{type}.0")
35
-
36
- nil
37
- end
38
- end
39
- else
40
- Runtime::Logger.info("Could not find previous image version")
41
- existing_previous = nil
42
- end
43
-
44
- previous_release = if existing_previous
45
- Runtime::Logger.info("Using previous image '#{existing_previous}'")
46
- QA::Release.new(existing_previous)
47
- else
48
- Runtime::Logger.info("Using stable as previous image")
49
- QA::Release.new(from_release).previous_stable
50
- end
51
-
52
- Docker::Volumes.new.with_temporary_volumes do |volumes|
53
- Component::Gitlab.perform do |gitlab|
54
- gitlab.release = previous_release
55
- gitlab.volumes = volumes
56
- gitlab.network = 'test'
57
- gitlab.seed_admin_token = false
58
- gitlab.launch_and_teardown_instance
59
- end
60
-
61
- Scenario::Test::Instance::Image
62
- .perform(current_release, *rspec_args) do |scenario|
63
- scenario.volumes = volumes
64
- end
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
71
- end
72
- end
@@ -1,99 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'yaml'
5
-
6
- class GenerateQAJobs
7
- def initialize(no_of_example_files)
8
- @no_of_example_files = no_of_example_files
9
- puts "no_of_example_files: #{@no_of_example_files}"
10
- end
11
-
12
- # rubocop:disable Metrics/AbcSize
13
- def execute
14
- jobs = load_yml_contents('base')
15
- jobs.merge!(load_yml_contents('sanity_framework'))
16
- jobs.merge!(load_yml_contents('custom_parallel'))
17
- jobs.merge!(load_yml_contents('instance', should_automatically_run?('test_instance_all')))
18
- jobs.merge!(load_yml_contents('relative_url', should_automatically_run?('test_instance_all')))
19
- jobs.merge!(load_yml_contents('decomposition_single_db', should_automatically_run?('test_instance_all')))
20
- jobs.merge!(load_yml_contents('decomposition_multiple_db', should_automatically_run?('test_instance_all')))
21
- jobs.merge!(load_yml_contents('repository_storage', should_automatically_run?('test_instance_all_repository_storage')))
22
- jobs.merge!(load_yml_contents('omnibus_image'))
23
- jobs.merge!(load_yml_contents('update', should_automatically_run?('test_instance_all')))
24
- jobs.merge!(load_yml_contents('omnibus_upgrade'))
25
- jobs.merge!(load_yml_contents('ee_previous_to_ce_update'))
26
- jobs.merge!(load_yml_contents('airgapped', should_automatically_run?('test_instance_all')))
27
- jobs.merge!(load_yml_contents('mattermost', should_automatically_run?('test_integration_mattermost')))
28
- jobs.merge!(load_yml_contents('service_ping_disabled', should_automatically_run?('test_integration_servicepingdisabled')))
29
- jobs.merge!(load_yml_contents('ldap_no_tls', should_automatically_run?('test_integration_ldapnotls')))
30
- jobs.merge!(load_yml_contents('ldap_tls', should_automatically_run?('test_integration_ldaptls')))
31
- jobs.merge!(load_yml_contents('ldap_no_server', should_automatically_run?('test_integration_ldapnoserver')))
32
- jobs.merge!(load_yml_contents('instance_saml', should_automatically_run?('test_integration_instancesaml')))
33
- jobs.merge!(load_yml_contents('group_saml', should_automatically_run?('test_integration_groupsaml')))
34
- jobs.merge!(load_yml_contents('object_storage', should_automatically_run?('test_instance_all_object_storage')))
35
- jobs.merge!(load_yml_contents('object_storage_aws', should_automatically_run?('test_instance_all_object_storage')))
36
- jobs.merge!(load_yml_contents('object_storage_gcs', should_automatically_run?('test_instance_all_object_storage')))
37
- jobs.merge!(load_yml_contents('object_storage_registry_tls', should_automatically_run?('test_integration_registrytls')))
38
- jobs.merge!(load_yml_contents('registry', should_automatically_run?('test_integration_registry')))
39
- jobs.merge!(load_yml_contents('packages', should_automatically_run?('test_instance_all_packages')))
40
- jobs.merge!(load_yml_contents('elasticsearch', should_automatically_run?('test_integration_elasticsearch')))
41
- jobs.merge!(load_yml_contents('opensearch', should_automatically_run?('test_integration_opensearch')))
42
- jobs.merge!(load_yml_contents('praefect', should_automatically_run?('test_instance_all')))
43
- jobs.merge!(load_yml_contents('gitaly_cluster', should_automatically_run?('test_instance_all')))
44
- jobs.merge!(load_yml_contents('gitlab_pages', should_automatically_run?('test_instance_all_gitlab_pages')))
45
- jobs.merge!(load_yml_contents('mtls', should_automatically_run?('test_instance_all_mtls')))
46
- jobs.merge!(load_yml_contents('smtp', should_automatically_run?('test_integration_smtp')))
47
- jobs.merge!(load_yml_contents('jira', should_automatically_run?('test_instance_all_jira')))
48
- jobs.merge!(load_yml_contents('integrations', should_automatically_run?('test_instance_all_integrations')))
49
- jobs.merge!(load_yml_contents('large_setup', should_automatically_run?('test_instance_all_can_use_large_setup')))
50
- jobs.merge!(load_yml_contents('cloud_activation', should_automatically_run?('test_instance_all_cloud_activation')))
51
- jobs.merge!(load_yml_contents('registry_with_cdn', should_automatically_run?('test_integration_registrywithcdn')))
52
- jobs.merge!(load_yml_contents('chaos', should_automatically_run?('test_integration_chaos')))
53
- jobs.merge!(load_yml_contents('staging'))
54
- jobs.merge!(load_yml_contents('metrics', should_automatically_run?('test_instance_all_metrics')))
55
-
56
- # Disabling geo jobs temporarily due to https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/774
57
- # jobs.merge!(load_yml_contents('geo', should_automatically_run?('scenario_test_geo')))
58
-
59
- yaml_string = jobs.to_yaml
60
- de_stringify_reference(yaml_string)
61
-
62
- yaml_string
63
- end
64
-
65
- # rubocop:enable Metrics/AbcSize
66
-
67
- private
68
-
69
- def should_automatically_run?(example_file_name)
70
- @no_of_example_files.include?(example_file_name)
71
- end
72
-
73
- def load_yml_contents(file_prefix, automatic = true)
74
- jobs_dir_path = File.expand_path('../.gitlab/ci/jobs', __dir__)
75
- file_contents = File.read(File.join(jobs_dir_path, "#{file_prefix}.gitlab-ci.yml"))
76
-
77
- # Enclose !reference in double quotes at it is not supported with YAML.load
78
- stringify_reference(file_contents)
79
- yaml_hash = YAML.safe_load(file_contents)
80
-
81
- yaml_hash.each { |key, value| value.merge!("when" => "manual") } unless automatic
82
-
83
- yaml_hash
84
- end
85
-
86
- def stringify_reference(str)
87
- match_data = str.match(/!reference \[[a-zA-Z_, ]*\]/)
88
- str.gsub!(match_data[0], "\"#{match_data[0]}\"") if match_data
89
- end
90
-
91
- def de_stringify_reference(str)
92
- match_data = str.match(/"(!reference \[[a-zA-Z_, ]*\])"/)
93
- str.gsub!(match_data[0], match_data[1]) if match_data
94
- end
95
- end
96
-
97
- jobs = GenerateQAJobs.new(Dir.glob('no_of_examples/*').map { |s| File.basename(s, '.*') }).execute
98
-
99
- File.open('generated-qa-jobs.yml', 'w') { |f| f.write(jobs) }