gitlab-qa 12.2.1 → 12.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d415adc65e11bf7cb6e51536436a6569e8477bb37cb16ef6834148e1966b3a97
4
- data.tar.gz: 18bb3333e27085779c061807124eef6921cb9e272d1bbca9f36f4c5b8fc1e703
3
+ metadata.gz: 06d3630b5975bd6c560b29280de76f5c6fdfeec2acf65775ca48646c2b413c06
4
+ data.tar.gz: 21d8d5abef70cf7fdcc47af4700d1c3392739efb2e923c0de71fe2614317e7e3
5
5
  SHA512:
6
- metadata.gz: a3af2c133956e35c0fc594811d9027a0a61798407632c790dbefb7873605db3701ec56c0b7c7f2dc046ea4b0f711b15a40d8bb746b15c2f0d285b8bb942b7a1a
7
- data.tar.gz: f188e6ea775ecc41d6e31de86a609a2ce479ab52055cb28f9e3c6c08feeea8d549494e578dd3c09daa46e659a654fed1ef464ab465a67033b0b7ecb6f211f9c4
6
+ metadata.gz: fad44c2bdf42d67c7b71686907cf62990ee96948e0b759615cb79745d57c0c8ec91ab75298992972712dab3139fa464b69c0eb078cc3d22ef4ae2db5e2efb807
7
+ data.tar.gz: 2117d2c4e221dc908ef562800302c1c821f55a2cb9040f3b82529989579613da4cceeddd280497a73de45860e44ce3e611934b2907b2ded4c8a7a65e6eaa9d30
data/.gitlab-ci.yml CHANGED
@@ -34,7 +34,7 @@ workflow:
34
34
  # For merge requests, create a pipeline.
35
35
  - if: '$CI_MERGE_REQUEST_IID'
36
36
  # For the default branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
37
- - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
37
+ - if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH || $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable$/'
38
38
  # For tags, create a pipeline.
39
39
  - if: '$CI_COMMIT_TAG'
40
40
  # When using Run pipeline button in the GitLab UI, from the project’s CI/CD > Pipelines section, create a pipeline.
@@ -47,6 +47,12 @@ variables:
47
47
  BUNDLE_SILENCE_ROOT_WARNING: "true"
48
48
  BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES: "true"
49
49
 
50
+ # Override rules to allow creating backport releases
51
+ .release-base:
52
+ rules:
53
+ - if: '$CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH || $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable$/)'
54
+ changes: ["lib/**/version.rb"]
55
+
50
56
  package-and-test-env:
51
57
  image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine:latest
52
58
  stage: .pre
@@ -135,7 +141,6 @@ package-and-test:
135
141
  variables:
136
142
  - RUBY_VERSION
137
143
  - DEBIAN_VERSION
138
- when: manual
139
144
  trigger:
140
145
  strategy: depend
141
146
  forward:
@@ -145,3 +150,8 @@ package-and-test:
145
150
  - project: gitlab-org/gitlab
146
151
  ref: master
147
152
  file: .gitlab/ci/package-and-test/main.gitlab-ci.yml
153
+ rules:
154
+ - if: '$CI_MERGE_REQUEST_IID'
155
+ when: manual
156
+ allow_failure: true
157
+ - when: always
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-qa (12.2.1)
4
+ gitlab-qa (12.4.0)
5
5
  activesupport (>= 6.1, < 7.1)
6
6
  gitlab (~> 4.19)
7
7
  http (~> 5.0)
@@ -24,6 +24,7 @@ GEM
24
24
  ast (2.4.2)
25
25
  backport (1.2.0)
26
26
  benchmark (0.2.0)
27
+ byebug (11.1.3)
27
28
  claide (1.1.0)
28
29
  claide-plugins (0.9.2)
29
30
  cork
@@ -149,6 +150,9 @@ GEM
149
150
  pry (0.14.1)
150
151
  coderay (~> 1.1)
151
152
  method_source (~> 1.0)
153
+ pry-byebug (3.10.1)
154
+ byebug (~> 11.0)
155
+ pry (>= 0.13, < 0.15)
152
156
  public_suffix (5.0.0)
153
157
  racc (1.6.0)
154
158
  rack (3.0.7)
@@ -263,6 +267,7 @@ DEPENDENCIES
263
267
  gitlab-styles (~> 10)
264
268
  lefthook (~> 1.2.6)
265
269
  pry (~> 0.11)
270
+ pry-byebug (~> 3.10.1)
266
271
  rake (~> 13.0)
267
272
  rspec (~> 3.7)
268
273
  simplecov (~> 0.22)
data/gitlab-qa.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'gitlab-styles', '~> 10'
28
28
  spec.add_development_dependency 'lefthook', '~> 1.2.6'
29
29
  spec.add_development_dependency 'pry', '~> 0.11'
30
+ spec.add_development_dependency 'pry-byebug', '~> 3.10.1'
30
31
  spec.add_development_dependency 'rake', '~> 13.0'
31
32
  spec.add_development_dependency 'rspec', '~> 3.7'
32
33
  spec.add_development_dependency 'simplecov', '~> 0.22'
@@ -10,7 +10,7 @@ module Gitlab
10
10
  # and has to be performed before main component containers are started
11
11
  #
12
12
  class Alpine < Base
13
- DOCKER_IMAGE = "alpine"
13
+ DOCKER_IMAGE = "alpine/curl"
14
14
  DOCKER_IMAGE_TAG = "latest"
15
15
 
16
16
  def name
@@ -21,6 +21,7 @@ module Gitlab
21
21
  docker.run(image: image, tag: tag, args: ["tail", "-f", "/dev/null"]) do |command|
22
22
  command << "-d"
23
23
  command << "--name #{name}"
24
+ command << "--network #{network}" if network
24
25
 
25
26
  volumes.each { |to, from| command.volume(to, from, 'Z') }
26
27
  environment.each { |key, value| command.env(key, value) }
@@ -8,7 +8,7 @@ module Gitlab
8
8
 
9
9
  CERTIFICATES_PATH = File.expand_path('../../../../tls_certificates', __dir__)
10
10
 
11
- attr_reader :docker
11
+ attr_reader :docker, :logger
12
12
  attr_writer :name, :exec_commands
13
13
  attr_accessor :volumes,
14
14
  :ports,
@@ -21,6 +21,7 @@ module Gitlab
21
21
 
22
22
  def initialize
23
23
  @docker = Docker::Engine.new
24
+ @logger = Runtime::Logger.logger
24
25
  @environment = {}
25
26
  @volumes = {}
26
27
  @ports = []
@@ -18,23 +18,24 @@ module Gitlab
18
18
  @tls_path = "/etc/smocker/tls"
19
19
  @ports = [80, 8081]
20
20
  @environment = { "SMOCKER_MOCK_SERVER_LISTEN_PORT" => 80 }
21
- @log_volume = {}
21
+ @tls_volume = { "smocker-ssl" => @tls_path }
22
22
  end
23
23
 
24
- attr_reader :name
24
+ attr_reader :name, :tls_volume
25
25
  attr_writer :tls
26
26
 
27
27
  def prepare
28
28
  super
29
29
 
30
+ alpine_service_container.start_instance
30
31
  setup_tls if tls
31
32
  end
32
33
 
33
- # Print smocker log output by using docker logs command because smocker only logs to stdout
34
- #
35
- # @return [void]
36
34
  def teardown!
35
+ # Print smocker log output by using docker logs command because smocker only logs to stdout
37
36
  Docker::Command.execute("logs #{name}")
37
+ # Remove alpine service container
38
+ alpine_service_container.teardown!
38
39
 
39
40
  super
40
41
  end
@@ -43,26 +44,64 @@ module Gitlab
43
44
 
44
45
  attr_reader :tls_path, :tls
45
46
 
47
+ # Run healthcheck validate startup of mock server
48
+ #
49
+ # @return [void]
50
+ def wait_until_ready
51
+ logger.info("Waiting for mock server to start!")
52
+ poll_mock_healthcheck(3)
53
+ logger.info("Mock server container is healthy!")
54
+ end
55
+
56
+ # Poll healthcheck endpoint
57
+ #
58
+ # @param [Integer] max_tries
59
+ # @return [void]
60
+ def poll_mock_healthcheck(max_tries)
61
+ url = "#{tls ? 'https' : 'http'}://#{hostname}:8081/version"
62
+ curl_cmd = "curl --cacert #{tls_path}/smocker.crt -s -f -o /dev/null -w '%{http_code}' #{url}"
63
+ tries = 0
64
+
65
+ loop do
66
+ # Poll healthcheck endpoint and remove service container if it passes
67
+ if docker.exec(alpine_service_container.name, curl_cmd, shell: "sh")
68
+ alpine_service_container.teardown!
69
+ break
70
+ end
71
+ rescue Support::ShellCommand::StatusError => e
72
+ # re-raise StatusError so that built in startup retry is used in case of failure
73
+ raise e if tries >= max_tries
74
+
75
+ tries += 1
76
+ sleep 1
77
+ end
78
+ end
79
+
46
80
  # Set up tls certs
47
81
  #
48
82
  # @return [void]
49
83
  def setup_tls
50
- @volumes = { "smocker-ssl" => tls_path }
84
+ @volumes = tls_volume
51
85
  @ports = [443, 8081]
52
86
  @environment = {
53
87
  "SMOCKER_MOCK_SERVER_LISTEN_PORT" => 443,
54
88
  "SMOCKER_TLS_ENABLE" => "true",
55
- "SMOCKER_TLS_CERT_FILE" => "#{@tls_path}/smocker.crt",
56
- "SMOCKER_TLS_PRIVATE_KEY_FILE" => "#{@tls_path}/smocker.key"
89
+ "SMOCKER_TLS_CERT_FILE" => "#{tls_path}/smocker.crt",
90
+ "SMOCKER_TLS_PRIVATE_KEY_FILE" => "#{tls_path}/smocker.key"
57
91
  }
58
92
 
59
- Alpine.perform do |alpine|
60
- alpine.volumes = volumes
93
+ docker.copy(alpine_service_container.name, "#{CERTIFICATES_PATH}/smocker/.", tls_path)
94
+ end
61
95
 
62
- alpine.start_instance
63
- docker.copy(alpine.name, "#{CERTIFICATES_PATH}/smocker/.", tls_path)
64
- ensure
65
- alpine.teardown! # always remove container, even when global `--no-tests` flag was provided
96
+ # Helper container to run tls cert copy and curl healthcheck command
97
+ # Separate container is required because tls certs have to be copied before smocker startup and smocker
98
+ # container itself doesn't ship with curl to perform healthcheck requests
99
+ #
100
+ # @return [Component::Alpine]
101
+ def alpine_service_container
102
+ @alpine_service_container ||= Alpine.new.tap do |alpine|
103
+ alpine.volumes = tls_volume
104
+ alpine.network = network
66
105
  end
67
106
  end
68
107
  end
@@ -81,10 +81,10 @@ module Gitlab
81
81
  ), mask_secrets: mask_secrets)
82
82
  end
83
83
 
84
- def exec(name, command, mask_secrets: nil)
84
+ def exec(name, command, mask_secrets: nil, shell: "bash")
85
85
  cmd = ['exec']
86
86
  cmd << '--privileged' if privileged_command?(command)
87
- Docker::Command.execute(%(#{cmd.join(' ')} #{name} bash -c "#{command.gsub('"', '\\"')}"),
87
+ Docker::Command.execute(%(#{cmd.join(' ')} #{name} #{shell} -c "#{command.gsub('"', '\\"')}"),
88
88
  mask_secrets: mask_secrets)
89
89
  end
90
90
 
@@ -85,6 +85,7 @@ module Gitlab
85
85
  'KNAPSACK_REPORT_PATH' => :knapsack_report_path,
86
86
  'KNAPSACK_TEST_FILE_PATTERN' => :knapsack_test_file_pattern,
87
87
  'KNAPSACK_TEST_DIR' => :knapsack_test_dir,
88
+ 'NO_KNAPSACK' => :no_knapsack,
88
89
  'QA_KNAPSACK_REPORT_GCS_CREDENTIALS' => :qa_knapsack_report_gcs_credentials,
89
90
  'QA_KNAPSACK_REPORT_PATH' => :qa_knapsack_report_path,
90
91
  'QA_RSPEC_REPORT_PATH' => :qa_rspec_report_path,
@@ -53,28 +53,134 @@ module Gitlab
53
53
  # NOT gitlab_rails['packages_enabled']=true
54
54
 
55
55
  v.nil? ? k.strip : "#{k.strip} = #{v.strip.tr('"', "'")}".strip
56
- end.uniq
56
+ end
57
57
 
58
- errors = []
58
+ sanitized = split_items(sanitized).uniq
59
+
60
+ sanitized = merge_arrays(sanitized)
59
61
 
60
62
  # check for duplicates
61
63
  duplicate_keys = []
62
64
  duplicates = sanitized.reject do |n|
63
65
  key = n.split('=').first
66
+
64
67
  duplicate_keys << key unless duplicate_keys.include?(key)
65
68
  end
66
69
 
70
+ errors = []
67
71
  duplicates.each { |duplicate| errors << "Duplicate entry found: `#{duplicate}`" }
68
72
 
69
73
  raise "Errors exist within the Omnibus Configuration!\n#{errors.join(',')}" if errors.any?
70
74
 
71
75
  @config = sanitized
72
76
  end
77
+
73
78
  # rubocop:enable Metrics/AbcSize
74
79
 
75
80
  def <<(config)
76
81
  @config << config.strip unless config.strip.empty?
77
82
  end
83
+
84
+ private
85
+
86
+ # Merge Omnibus configuration values if the value is an array
87
+ # @example
88
+ # array = ['a["setting"] = [1]', 'a["setting"] = [2]']
89
+ # merge_arrays(array) #=> ['a["setting"] = [1, 2]']
90
+ #
91
+ # @param [Array] arr
92
+ #
93
+ # @return [Array]
94
+ def merge_arrays(arr)
95
+ entries_with_array = {}
96
+
97
+ arr.reject! do |item|
98
+ key, value = item.split("=", 2)
99
+
100
+ array_content_match = value&.match(/^\s?\[([\s\S]+)\][\s;]?$/)
101
+
102
+ if array_content_match
103
+ if entries_with_array[key]
104
+ entries_with_array[key] << array_content_match[1]
105
+ else
106
+ entries_with_array[key] = [array_content_match[1]]
107
+ end
108
+ end
109
+ end
110
+
111
+ entries_with_array.each do |k, v|
112
+ arr << "#{k}= [#{v.map(&:chomp).join(', ')}]".strip
113
+ end
114
+
115
+ arr
116
+ end
117
+
118
+ # Split each Omnibus setting into an array item
119
+ # @example
120
+ # input = ["a['setting_1'] = true",
121
+ # "a['setting_2'] = [
122
+ # {
123
+ # name: 'setting_2a_name'
124
+ # }
125
+ # ]
126
+ # a['setting_3'] = false"]
127
+ #
128
+ # split_items(input) #=>
129
+ # ["a['setting_1'] = true",
130
+ # "a['setting_2'] = [
131
+ # {
132
+ # name: 'setting_2a_name'
133
+ # }
134
+ # ]",
135
+ # "a['setting_3'] = false"]
136
+ #
137
+ # @param [Array] input
138
+ #
139
+ # @return [Array]
140
+ #
141
+ # rubocop:disable Metrics/AbcSize
142
+ def split_items(input)
143
+ items = []
144
+
145
+ input.each do |item|
146
+ if count_occurrences(item, ' = ') > 1
147
+ multi_line_item = []
148
+ item.split("\n").each do |line|
149
+ if /( = |external_url)/.match?(line)
150
+
151
+ if multi_line_item.count > 1
152
+ items.pop
153
+ items << multi_line_item.join("\n")
154
+ end
155
+
156
+ items << line
157
+ multi_line_item = [line]
158
+ else
159
+ multi_line_item << line
160
+ end
161
+ end
162
+
163
+ if multi_line_item.count > 1
164
+ items.pop
165
+ items << multi_line_item.join("\n")
166
+ end
167
+ else
168
+ items << item
169
+ end
170
+ end
171
+
172
+ items
173
+ end
174
+ # rubocop:enable Metrics/AbcSize
175
+
176
+ # Count occurrences of a substring in a string
177
+ # @param [String] str
178
+ # @param [String] substr
179
+ #
180
+ # @return [Array]
181
+ def count_occurrences(str, substr)
182
+ str.scan(/(?=#{substr})/).count
183
+ end
78
184
  end
79
185
  end
80
186
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  module QA
5
- VERSION = '12.2.1'
5
+ VERSION = '12.4.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-qa
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.2.1
4
+ version: 12.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab Quality
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-26 00:00:00.000000000 Z
11
+ date: 2023-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.11'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 3.10.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 3.10.1
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rake
85
99
  requirement: !ruby/object:Gem::Requirement