gitlab-qa 15.2.0 → 15.3.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/Gemfile.lock +1 -1
- data/docs/what_tests_can_be_run.md +59 -3
- data/lib/gitlab/qa/component/license_ops.rb +51 -0
- data/lib/gitlab/qa/component/pipeline_ops.rb +57 -0
- data/lib/gitlab/qa/component/project_importer.rb +63 -0
- data/lib/gitlab/qa/component/runner_ops.rb +113 -0
- data/lib/gitlab/qa/docker/engine.rb +12 -0
- data/lib/gitlab/qa/scenario/test/instance/secure_version.rb +57 -0
- data/lib/gitlab/qa/scenario/test/omnibus/update_to_next.rb +76 -0
- data/lib/gitlab/qa/support/gitlab_upgrade_path.rb +56 -9
- data/lib/gitlab/qa/support/gitlab_version_info.rb +33 -0
- data/lib/gitlab/qa/version.rb +1 -1
- data/support/pipeline/create_for_projectname.rb +28 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bc0f25e1bbf4c9d82910a6b8a2da29df78bbe683d620d82cb0d36e28a906dcb
|
4
|
+
data.tar.gz: '0283a7bc128cc2e86f1e4aa1a7c0c0020be2a6c62c543019c1879e73bf5b9e2f'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a14c2e7949b7cbe2b031e13ad5c12488160025c256d831e6bda9158890fc311277f31d10279b1a1b184fbef463b95bac2767b80103fa41a6d011d42ffc2be71
|
7
|
+
data.tar.gz: e4180225aa649c4796a85c4c016651adc8200cf6b8e2c69e451b8f64e26a32caf7f71bfd28159d026bcd1d6355b541631f6c8ae6f8c28fef38e94929b4216d87
|
data/Gemfile.lock
CHANGED
@@ -299,11 +299,11 @@ $ gitlab-qa Test::Omnibus::Upgrade CE
|
|
299
299
|
$ gitlab-qa Test::Omnibus::Upgrade gitlab/gitlab-ce:my-custom-tag
|
300
300
|
```
|
301
301
|
|
302
|
-
### `Test::Omnibus::UpdateFromPrevious <full image address> <current_version> <major|minor> <from_edition>`
|
302
|
+
### `Test::Omnibus::UpdateFromPrevious <full image address> <current_version> <major|minor|patch> <from_edition>`
|
303
303
|
|
304
|
-
Scenario verifies upgrade from previous (major|minor) version to current release.
|
304
|
+
Scenario verifies upgrade from previous (major|minor|patch) version to current release.
|
305
305
|
|
306
|
-
- Deploys previous (major|minor) version and runs Smoke test suite
|
306
|
+
- Deploys previous (major|minor|patch) version and runs Health Check test suite (Smoke test suite if below 17.1.0)
|
307
307
|
to populate data in database before upgrade
|
308
308
|
- Generates upgrade path following current GitLab recommendations
|
309
309
|
from ['gitlab.com/gitlab-org/gitlab'](https://gitlab.com/gitlab-org/gitlab/-/raw/master/config/upgrade_path.yml) project
|
@@ -318,6 +318,27 @@ $ gitlab-qa Test::Omnibus::UpdateFromPrevious gitlab-ee:dev-tag 15.6.0-pre minor
|
|
318
318
|
|
319
319
|
# Major upgrade - will perform upgrades 14.10.x -> 15.0.x -> 15.4.x -> gitlab-ee:dev-tag (15.6.0-pre)
|
320
320
|
$ gitlab-qa Test::Omnibus::UpdateFromPrevious gitlab-ee:dev-tag 15.6.0-pre major
|
321
|
+
|
322
|
+
# Patch upgrade - will perform upgrade from 17.8.1 -> gitlab-ee:dev-tag (17.8.2-pre)
|
323
|
+
$ gitlab-qa Test::Omnibus::UpdateFromPrevious gitlab-ee:dev-tag 17.8.2-pre patch
|
324
|
+
```
|
325
|
+
|
326
|
+
### `Test::Omnibus::UpdateToNext <full image address> <current_version> <from_edition>`
|
327
|
+
|
328
|
+
Scenario verifies upgrade from current development version to next available stable release.
|
329
|
+
|
330
|
+
- Deploys development version and runs Health Check test suite to populate data in database (Smoke test suite if below 17.1.0)
|
331
|
+
- Finds next available stable version
|
332
|
+
- Upgrades GitLab instance from development version to next stable and runs tests against it
|
333
|
+
- Skips if either current version or next version is not yet released
|
334
|
+
|
335
|
+
Note: `from_edition` setting is optional, can be set to `ee` or `ce`.
|
336
|
+
|
337
|
+
Example:
|
338
|
+
|
339
|
+
```shell
|
340
|
+
# Will perform upgrade from gitlab-ee:dev-tag (17.8.2-pre) -> 17.9.2
|
341
|
+
$ gitlab-qa Test::Omnibus::UpdateToNext gitlab-ee:dev-tag 17.8.2-pre
|
321
342
|
```
|
322
343
|
|
323
344
|
### `Test::Integration::Geo EE|<full image address>`
|
@@ -1049,6 +1070,29 @@ This orchestrated scenario runs tests from the test suite against a GitLab insta
|
|
1049
1070
|
|
1050
1071
|
These variables are available at 1Password QA Vault.
|
1051
1072
|
|
1073
|
+
----
|
1074
|
+
|
1075
|
+
#### `Test::Instance::SecureVersion EE|<full image address>`
|
1076
|
+
|
1077
|
+
Used for testing that a project with Secure scanner functionality functions correctly against the specified version.
|
1078
|
+
As this is Secure functionality, an EE license is required.
|
1079
|
+
Can be used for running older instances of GitLab, this skips the Security version modal on login.
|
1080
|
+
|
1081
|
+
The script applies the license, imports the project, kicks off a pipeline, and checks that the pipeline was successful.
|
1082
|
+
|
1083
|
+
**Required environment variables:**
|
1084
|
+
|
1085
|
+
- `EE_LICENSE`: A valid EE license for testing.
|
1086
|
+
- `PROJECT_URL`: The URL of the project to test.
|
1087
|
+
- `PROJECT_NAME`: The name of the project to test, when imported to the instance.
|
1088
|
+
|
1089
|
+
Example:
|
1090
|
+
|
1091
|
+
```shell
|
1092
|
+
$ export EE_LICENSE=$(cat /path/to/gitlab_license)
|
1093
|
+
$ PROJECT_URL='https://gitlab.com/gitlab-org/quality/ci/secure-testing/secure-matrix-test.git' PROJECT_NAME='secure-matrix-test' gitlab-qa Test::Instance::SecureVersion gitlab/gitlab-ee:16.5.0-ee.0
|
1094
|
+
```
|
1095
|
+
|
1052
1096
|
### `Test::Integration::RegistryTLS EE`
|
1053
1097
|
|
1054
1098
|
It uses GitLab's TLS certificate found in the [`tls_certificates`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/tls_certificates/gitlab/gitlab.test.crt) folder.
|
@@ -1236,4 +1280,16 @@ $ gitlab-qa Test::Integration::AiGatewayNoLicense EE
|
|
1236
1280
|
|
1237
1281
|
----
|
1238
1282
|
|
1283
|
+
#### Troubleshooting `AiGateway` Tests
|
1284
|
+
|
1285
|
+
The following logs are available for troubleshooting `AiGateway` tests in the `e2e-test-on-omnibus` pipelines.
|
1286
|
+
|
1287
|
+
| Component | Log Location | Additional Info |
|
1288
|
+
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
|
1289
|
+
| CustomersDot Staging | [Kibana](https://nonprod-log.gitlab.net/) (`pubsub-rails-inf-stgsub*`), [Sentry](https://new-sentry.gitlab.net/organizations/gitlab/issues/?environment=stg&project=8) | See [CustomersDot Logging](https://gitlab.com/gitlab-org/customers-gitlab-com/blob/main/doc/architecture/logging.md#customersdot-logging) for details |
|
1290
|
+
| GitLab Omnibus | Job artifacts: `gitlab/logs` | See the GitLab [Log system](https://docs.gitlab.com/ee/administration/logs/) docs for more details |
|
1291
|
+
| AI Gateway | Job artifacts: `ai-gateway/logs/modelgateway_debug.log` | See the AI Gateway's [README](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist#gitlab-ai-gateway) for more details |
|
1292
|
+
|
1293
|
+
----
|
1294
|
+
|
1239
1295
|
[Back to README.md](../README.md)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Component
|
6
|
+
class LicenseOps < Base
|
7
|
+
LicenseError = Class.new(StandardError)
|
8
|
+
require 'shellwords'
|
9
|
+
|
10
|
+
def add_license(gitlab)
|
11
|
+
license_key = fetch_license_key
|
12
|
+
command = build_license_command(license_key)
|
13
|
+
apply_license(gitlab, command, license_key)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def fetch_license_key
|
19
|
+
license_key = ENV.fetch('EE_LICENSE', '')
|
20
|
+
raise LicenseError, "EE_LICENSE environment variable is not set or is empty" if license_key.empty?
|
21
|
+
|
22
|
+
Shellwords.shellwords(license_key).join
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_license_command(license_key)
|
26
|
+
script = <<~RUBY
|
27
|
+
key = ENV['EE_LICENSE']
|
28
|
+
license = License.new(data: key)
|
29
|
+
if license.save
|
30
|
+
puts "License applied successfully"
|
31
|
+
else
|
32
|
+
STDERR.puts "Failed to apply license"
|
33
|
+
end
|
34
|
+
RUBY
|
35
|
+
"EE_LICENSE='#{license_key}' gitlab-rails runner $'#{script.gsub("'", "\\\\'").gsub("\n", '\\n')}'"
|
36
|
+
end
|
37
|
+
|
38
|
+
def apply_license(gitlab, command, license_key)
|
39
|
+
result = gitlab.docker.exec(gitlab.name, command, mask_secrets: license_key)
|
40
|
+
verify_license_application(result)
|
41
|
+
end
|
42
|
+
|
43
|
+
def verify_license_application(result)
|
44
|
+
return if result.include?("License applied successfully")
|
45
|
+
|
46
|
+
raise LicenseError, "Failed to apply license."
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Component
|
6
|
+
class PipelineOps < Base
|
7
|
+
def start(gitlab, project_name)
|
8
|
+
create_and_execute_pipeline_script(gitlab, project_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def check_status(gitlab)
|
12
|
+
pipeline_status = gitlab.docker.exec(
|
13
|
+
gitlab.name, wait_for_pipeline)
|
14
|
+
|
15
|
+
case pipeline_status
|
16
|
+
when 'success'
|
17
|
+
puts "Pipeline succeeded!"
|
18
|
+
nil
|
19
|
+
when 'failed'
|
20
|
+
raise StandardError, "Pipeline failed."
|
21
|
+
else
|
22
|
+
puts "Pipeline is currently #{pipeline_status}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def create_and_execute_pipeline_script(gitlab, project_name)
|
29
|
+
setup_src_path = File.expand_path('../../../../support/pipeline', __dir__)
|
30
|
+
setup_dest_path = '/tmp/setup-scripts'
|
31
|
+
|
32
|
+
gitlab.docker.copy(gitlab.name, setup_src_path, setup_dest_path)
|
33
|
+
|
34
|
+
gitlab.docker.exec(
|
35
|
+
gitlab.name,
|
36
|
+
"PROJECT_NAME='#{project_name}' gitlab-rails runner #{setup_dest_path}/create_for_projectname.rb"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def wait_for_pipeline
|
41
|
+
<<~SHELL
|
42
|
+
gitlab-rails runner "
|
43
|
+
latest_pipeline = Ci::Pipeline.last
|
44
|
+
# wait for the pipeline to complete
|
45
|
+
loop do
|
46
|
+
latest_pipeline.reload
|
47
|
+
break if latest_pipeline.complete?
|
48
|
+
sleep 1
|
49
|
+
end
|
50
|
+
puts latest_pipeline.status
|
51
|
+
"
|
52
|
+
SHELL
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Component
|
6
|
+
class ProjectImporter < Base
|
7
|
+
IMPORT_TIMEOUT = 300 # 5 minutes
|
8
|
+
|
9
|
+
def initialize(project_url, project_name, project_path: project_name)
|
10
|
+
@project_name = project_name
|
11
|
+
@project_url = project_url
|
12
|
+
@project_path = project_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def import_project(gitlab)
|
16
|
+
import_command = build_import_command(create_import_script, @project_url, @project_name, @project_path)
|
17
|
+
puts gitlab.docker.exec(gitlab.name, import_command)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def create_import_script
|
23
|
+
<<~'RUBY'
|
24
|
+
require 'timeout'
|
25
|
+
|
26
|
+
project_url = ENV.fetch('PROJECT_URL')
|
27
|
+
project_name = ENV.fetch('PROJECT_NAME')
|
28
|
+
project_path = ENV.fetch('PROJECT_PATH')
|
29
|
+
|
30
|
+
root_user = User.find_by_username('root')
|
31
|
+
|
32
|
+
project = Projects::CreateService.new(root_user,
|
33
|
+
{ name: project_name, path: project_path, import_url: project_url }).execute
|
34
|
+
|
35
|
+
if project.persisted?
|
36
|
+
# Wait for import to complete
|
37
|
+
begin
|
38
|
+
Timeout.timeout(300) do # 5 minutes timeout
|
39
|
+
until ['finished', 'failed'].include?(project.import_status)
|
40
|
+
sleep 5
|
41
|
+
project.reload
|
42
|
+
end
|
43
|
+
end
|
44
|
+
rescue Timeout::Error
|
45
|
+
puts "Import process timed out after 5 minutes"
|
46
|
+
end
|
47
|
+
else
|
48
|
+
puts "Failed to create project: #{project.errors.full_messages.join(', ')}"
|
49
|
+
end
|
50
|
+
|
51
|
+
# Always print import state for debugging
|
52
|
+
puts "Import state: #{project.import_state.attributes}" if project.respond_to?(:import_state)
|
53
|
+
RUBY
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_import_command(script, project_url, project_name, project_path)
|
57
|
+
escaped_script = script.gsub("'", "\\\\'").gsub("\n", "\\n")
|
58
|
+
"PROJECT_URL='#{project_url}' PROJECT_NAME='#{project_name}' PROJECT_PATH='#{project_path}' gitlab-rails runner $'#{escaped_script}'"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Component
|
6
|
+
class RunnerOps < Base
|
7
|
+
include Support::Shellout
|
8
|
+
|
9
|
+
RUNNER_DESCRIPTION = "QA Runner"
|
10
|
+
DOCKER_IMAGE = "registry.gitlab.com/gitlab-org/gitlab-runner:alpine"
|
11
|
+
BUILD_IMAGE = "registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.7"
|
12
|
+
|
13
|
+
def setup_runner(gitlab)
|
14
|
+
token = SecureRandom.hex(15)
|
15
|
+
add_runner_to_gitlab(gitlab, token)
|
16
|
+
register_docker_runner(gitlab, token)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def add_runner_to_gitlab(gitlab, token)
|
22
|
+
gitlab.docker.exec(
|
23
|
+
gitlab.name,
|
24
|
+
create_runner_command(token),
|
25
|
+
mask_secrets: token
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_runner_command(token)
|
30
|
+
<<~RUBY.strip.gsub(/\s+/, ' ')
|
31
|
+
gitlab-rails runner '
|
32
|
+
Ci::Runner.create!(
|
33
|
+
description: "#{RUNNER_DESCRIPTION}",
|
34
|
+
run_untagged: true,
|
35
|
+
active: true,
|
36
|
+
token: "#{token}",
|
37
|
+
runner_type: :instance_type
|
38
|
+
);
|
39
|
+
puts "Runner created"
|
40
|
+
'
|
41
|
+
RUBY
|
42
|
+
end
|
43
|
+
|
44
|
+
def register_docker_runner(gitlab, token)
|
45
|
+
runner_name = generate_runner_name
|
46
|
+
docker_command = build_docker_command(
|
47
|
+
runner_name: runner_name,
|
48
|
+
network: gitlab.network,
|
49
|
+
address: gitlab.address,
|
50
|
+
token: token
|
51
|
+
)
|
52
|
+
|
53
|
+
shell(docker_command, mask_secrets: [token])
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_runner_name
|
57
|
+
"test-runner-#{SecureRandom.hex(4)}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_docker_command(runner_name:, network:, address:, token:)
|
61
|
+
<<~CMD.tr("\n", ' ')
|
62
|
+
docker run -d --rm --network #{network} --name #{runner_name}
|
63
|
+
-v /var/run/docker.sock:/var/run/docker.sock
|
64
|
+
--privileged
|
65
|
+
#{DOCKER_IMAGE}
|
66
|
+
&& docker exec --detach #{runner_name} sh -c "#{register_command(runner_name, address, token, network)}"
|
67
|
+
CMD
|
68
|
+
end
|
69
|
+
|
70
|
+
def runner_config
|
71
|
+
<<~CONFIG
|
72
|
+
concurrent = 1
|
73
|
+
check_interval = 0
|
74
|
+
|
75
|
+
[session_server]
|
76
|
+
session_timeout = 1800
|
77
|
+
CONFIG
|
78
|
+
end
|
79
|
+
|
80
|
+
def register_command(name, address, token, network)
|
81
|
+
registration_args = build_registration_args(
|
82
|
+
name: name,
|
83
|
+
address: address,
|
84
|
+
token: token,
|
85
|
+
network: network
|
86
|
+
)
|
87
|
+
|
88
|
+
<<~CMD.strip
|
89
|
+
echo "#{runner_config}" > /etc/gitlab-runner/config.toml &&
|
90
|
+
gitlab-runner register #{registration_args} &&
|
91
|
+
gitlab-runner run
|
92
|
+
CMD
|
93
|
+
end
|
94
|
+
|
95
|
+
def build_registration_args(name:, address:, token:, network:)
|
96
|
+
[
|
97
|
+
'--non-interactive',
|
98
|
+
"--name #{name}",
|
99
|
+
"--url #{address}",
|
100
|
+
"--token #{token}",
|
101
|
+
'--run-untagged=true',
|
102
|
+
'--executor docker',
|
103
|
+
"--docker-image #{BUILD_IMAGE}",
|
104
|
+
'--docker-tlsverify=false',
|
105
|
+
'--docker-privileged=true',
|
106
|
+
"--docker-network-mode=#{network}",
|
107
|
+
'--docker-volumes=/certs/client'
|
108
|
+
].join(' ')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -81,6 +81,18 @@ module Gitlab
|
|
81
81
|
), mask_secrets: mask_secrets)
|
82
82
|
end
|
83
83
|
|
84
|
+
# Executes a command inside a running Docker container.
|
85
|
+
#
|
86
|
+
# @param name [String] The name or ID of the container to execute the command in.
|
87
|
+
# @param command [String] The command to be executed inside the container.
|
88
|
+
# @param mask_secrets [Boolean, nil] Whether to mask sensitive information in logs. Defaults to nil.
|
89
|
+
# @param shell [String] The shell to use for executing the command. Defaults to "bash".
|
90
|
+
#
|
91
|
+
# @return [String] The output of the executed command.
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# exec("my-container", "echo 'hello world'")
|
95
|
+
# # => "hello world\n"
|
84
96
|
def exec(name, command, mask_secrets: nil, shell: "bash")
|
85
97
|
cmd = ['exec']
|
86
98
|
cmd << '--privileged' if privileged_command?(command)
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Scenario
|
6
|
+
module Test
|
7
|
+
module Instance
|
8
|
+
class SecureVersion < Scenario::Template
|
9
|
+
include Support::Shellout
|
10
|
+
|
11
|
+
attr_writer :volumes, :seed_admin_token
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@volumes = {}
|
15
|
+
@seed_admin_token = true
|
16
|
+
@pipeline_ops = Component::PipelineOps.new
|
17
|
+
@runner_ops = Component::RunnerOps.new
|
18
|
+
@importer = Component::ProjectImporter.new(
|
19
|
+
ENV.fetch('PROJECT_URL', nil),
|
20
|
+
ENV.fetch('PROJECT_NAME', nil))
|
21
|
+
@license_ops = Component::LicenseOps.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def perform(release, *_rspec_args)
|
25
|
+
Component::Gitlab.perform do |gitlab|
|
26
|
+
setup_gitlab(gitlab, release)
|
27
|
+
execute_gitlab_operations(gitlab)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def setup_gitlab(gitlab, release)
|
34
|
+
gitlab.release = release
|
35
|
+
gitlab.volumes = @volumes
|
36
|
+
gitlab.network = Runtime::Env.docker_network
|
37
|
+
gitlab.name = Runtime::Env.qa_gitlab_hostname
|
38
|
+
gitlab.seed_admin_token = @seed_admin_token
|
39
|
+
gitlab.tls = Runtime::Env.qa_gitlab_use_tls?
|
40
|
+
# gitlab.exec_commands = foo
|
41
|
+
end
|
42
|
+
|
43
|
+
def execute_gitlab_operations(gitlab)
|
44
|
+
gitlab.instance do
|
45
|
+
@license_ops.add_license(gitlab)
|
46
|
+
@runner_ops.setup_runner(gitlab)
|
47
|
+
@importer.import_project(gitlab)
|
48
|
+
@pipeline_ops.start(gitlab, 'secure-matrix-test')
|
49
|
+
@pipeline_ops.check_status(gitlab)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Scenario
|
6
|
+
module Test
|
7
|
+
module Omnibus
|
8
|
+
class UpdateToNext < UpdateFromPrevious
|
9
|
+
using Rainbow
|
10
|
+
# Test upgrade from development version to next stable release
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# perform(gitlab-ee:dev-tag, 17.8.2-pre)
|
14
|
+
# => will perform upgrade gitlab-ee:dev-tag -> 17.9.2
|
15
|
+
#
|
16
|
+
# @param [String] release current release docker image with development changes
|
17
|
+
# @param [String] current_version current gitlab version associated with docker image
|
18
|
+
# @param [String] from_edition gitlab edition to update from
|
19
|
+
# @param [Array] *rspec_args rspec arguments
|
20
|
+
# @return [void]
|
21
|
+
def perform(release, current_version, from_edition = nil, *rspec_args)
|
22
|
+
# When from_edition isn't actually passed but RSpec args arg passed with `-- rspec_args...`,
|
23
|
+
# from_edition is wrongly set to `--`, so we fix that here.
|
24
|
+
if from_edition == "--"
|
25
|
+
rspec_args.prepend('--')
|
26
|
+
from_edition = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
@current_release = QA::Release.new(release)
|
30
|
+
@upgrade_path = Support::GitlabUpgradePath.new(
|
31
|
+
current_version,
|
32
|
+
'from_patch',
|
33
|
+
from_edition || @current_release.edition
|
34
|
+
).fetch
|
35
|
+
@rspec_args = rspec_args
|
36
|
+
|
37
|
+
# Key difference to UpdateFromPrevious: current_release comes first in the upgrade path
|
38
|
+
upgrade_info = "(#{current_version}) #{[current_release, *upgrade_path].join(' => ')}".bright
|
39
|
+
Runtime::Logger.info("Performing gitlab update: #{upgrade_info}")
|
40
|
+
|
41
|
+
update(rspec_args)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Override to run specs in reverse order - first on development version, then on target version
|
47
|
+
#
|
48
|
+
# @param [Array] rspec_args
|
49
|
+
# @return [void]
|
50
|
+
def update(rspec_args)
|
51
|
+
Docker::Volumes.new.with_temporary_volumes do |volumes|
|
52
|
+
# deploy development release and run specs to populate db
|
53
|
+
Runtime::Logger.info("Running the development release: #{current_release}")
|
54
|
+
run_gitlab(current_release, volumes, seeding_suite_args, seeding_run: true)
|
55
|
+
|
56
|
+
# deploy target release and run tests
|
57
|
+
upgrade_path.each do |release|
|
58
|
+
Runtime::Logger.info("Upgrading GitLab to target release: #{release}")
|
59
|
+
run_gitlab(release, volumes, rspec_args, skip_setup: true)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Override to run specs on development release and final target
|
65
|
+
#
|
66
|
+
# @param [Gitlab::QA::Release] release
|
67
|
+
# @return [Boolean]
|
68
|
+
def run_specs?(release)
|
69
|
+
[current_release, upgrade_path.last].any?(release)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -13,11 +13,17 @@ module Gitlab
|
|
13
13
|
# @param [String] semver_component version number component for previous version detection - major|minor|patch
|
14
14
|
# @param [String] edition GitLab edition - ee or ce
|
15
15
|
def initialize(current_version, semver_component, edition)
|
16
|
+
@logger = Runtime::Logger.logger
|
17
|
+
|
18
|
+
unless current_version.match?(GitlabVersionInfo::VERSION_PATTERN)
|
19
|
+
logger.error("Invalid 'current_version' format: #{current_version}. Expected format: MAJOR.MINOR.PATCH (e.g., 17.8.2)")
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
|
16
23
|
@version_info = GitlabVersionInfo.new(current_version, edition)
|
17
|
-
@current_version = Gem::Version.new(current_version)
|
24
|
+
@current_version = Gem::Version.new(current_version.match(GitlabVersionInfo::VERSION_PATTERN)[:version]) # Extract version without postfixes like pre or ee
|
18
25
|
@semver_component = semver_component
|
19
26
|
@edition = edition
|
20
|
-
@logger = Runtime::Logger.logger
|
21
27
|
end
|
22
28
|
|
23
29
|
# Get upgrade path between releases
|
@@ -26,9 +32,18 @@ module Gitlab
|
|
26
32
|
#
|
27
33
|
# @return [Array<QA::Release>]
|
28
34
|
def fetch
|
29
|
-
|
30
|
-
|
31
|
-
|
35
|
+
case semver_component
|
36
|
+
when "patch"
|
37
|
+
patch_upgrade_path
|
38
|
+
when "minor"
|
39
|
+
minor_upgrade_path
|
40
|
+
when "major"
|
41
|
+
major_upgrade_path
|
42
|
+
when "from_patch"
|
43
|
+
from_patch_upgrade_path
|
44
|
+
else
|
45
|
+
raise ArgumentError, "Unknown semver component: #{semver_component}"
|
46
|
+
end
|
32
47
|
rescue GitlabVersionInfo::VersionNotFoundError
|
33
48
|
logger.error("Failed to construct gitlab upgrade path")
|
34
49
|
raise
|
@@ -40,6 +55,17 @@ module Gitlab
|
|
40
55
|
|
41
56
|
attr_reader :version_info, :current_version, :semver_component, :edition, :logger
|
42
57
|
|
58
|
+
# Upgrade path for patch version update
|
59
|
+
# Returns array with current version as we're testing upgrade from
|
60
|
+
# latest stable patch to development version
|
61
|
+
#
|
62
|
+
# @return [Array]
|
63
|
+
def patch_upgrade_path
|
64
|
+
verify_current_version_exists
|
65
|
+
|
66
|
+
[release(latest_patch(current_version))]
|
67
|
+
end
|
68
|
+
|
43
69
|
# Upgrade path from previous minor version
|
44
70
|
#
|
45
71
|
# @return [Array]
|
@@ -63,11 +89,21 @@ module Gitlab
|
|
63
89
|
end
|
64
90
|
end
|
65
91
|
|
66
|
-
# Upgrade from
|
92
|
+
# Upgrade path from current version to next stable version
|
93
|
+
# Checks if current version exists in releases
|
94
|
+
# Gets next available major.minor version and its latest patch
|
67
95
|
#
|
68
|
-
# @return [
|
69
|
-
def
|
70
|
-
|
96
|
+
# @return [Array] Array with next version's latest patch release or exits with message
|
97
|
+
def from_patch_upgrade_path
|
98
|
+
verify_current_version_exists
|
99
|
+
next_version = version_info.next_version(current_version.to_s)
|
100
|
+
|
101
|
+
unless next_version
|
102
|
+
logger.info("Skipping upgrade test as next version after #{current_version} is not yet available")
|
103
|
+
exit 0
|
104
|
+
end
|
105
|
+
|
106
|
+
[release(latest_patch(next_version))]
|
71
107
|
end
|
72
108
|
|
73
109
|
# Docker release image
|
@@ -85,6 +121,17 @@ module Gitlab
|
|
85
121
|
@previous_version ||= version_info.previous_version(semver_component)
|
86
122
|
end
|
87
123
|
|
124
|
+
# Verify if current version exists in GitLab releases
|
125
|
+
# Exit with message if version is not yet released
|
126
|
+
#
|
127
|
+
# @return [void]
|
128
|
+
def verify_current_version_exists
|
129
|
+
return if version_info.version_exists?(current_version.to_s)
|
130
|
+
|
131
|
+
logger.info("Skipping upgrade test as version #{current_version} is not yet released")
|
132
|
+
exit 0
|
133
|
+
end
|
134
|
+
|
88
135
|
# Gitlab upgrade path
|
89
136
|
#
|
90
137
|
# @return [Array<Gem::Version>]
|
@@ -36,6 +36,18 @@ module Gitlab
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
# Check if specific version exists in GitLab releases
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# version_exists?("17.10.5") => true
|
43
|
+
# version_exists?("17.10.28") => false
|
44
|
+
#
|
45
|
+
# @param [String] version Version to check
|
46
|
+
# @return [Boolean] true if version exists in GitLab releases, false otherwise
|
47
|
+
def version_exists?(version)
|
48
|
+
!!versions.find { |ver| ver.to_s == version }
|
49
|
+
end
|
50
|
+
|
39
51
|
# Get latest patch for specific version number
|
40
52
|
#
|
41
53
|
# @example
|
@@ -53,6 +65,27 @@ module Gitlab
|
|
53
65
|
end
|
54
66
|
end
|
55
67
|
|
68
|
+
# Get next version major.minor from available releases
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# next_version("17.7.4") => "17.8"
|
72
|
+
# next_version("17.12.5") => "18.0"
|
73
|
+
# next_version("18.0.3") => nil # when no next version exists
|
74
|
+
#
|
75
|
+
# @param [String] version Current version
|
76
|
+
# @return [String, nil] Next version in major.minor format or nil if no next version exists
|
77
|
+
def next_version(version)
|
78
|
+
current_ver = Gem::Version.new(version)
|
79
|
+
|
80
|
+
# Since versions are already sorted in descending order (newest first),
|
81
|
+
# we need to reverse them to find the next version after current
|
82
|
+
next_ver = versions.reverse.find { |ver| ver > current_ver }
|
83
|
+
|
84
|
+
return nil unless next_ver
|
85
|
+
|
86
|
+
[next_ver.segments[0], next_ver.segments[1]].join('.') # major.minor
|
87
|
+
end
|
88
|
+
|
56
89
|
private
|
57
90
|
|
58
91
|
MAX_TAGS_HTTP_REQUESTS = 50
|
data/lib/gitlab/qa/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateForProjectname
|
4
|
+
class << self
|
5
|
+
def create_pipeline
|
6
|
+
project_name = ENV.fetch('PROJECT_NAME', nil)
|
7
|
+
root_user = User.find_by_username('root')
|
8
|
+
project = Project.find_by_path(project_name)
|
9
|
+
|
10
|
+
if project
|
11
|
+
pipeline_service = Ci::CreatePipelineService.new(project, root_user, ref: project.default_branch_or_main)
|
12
|
+
pipeline = pipeline_service.execute(:api)
|
13
|
+
|
14
|
+
if pipeline
|
15
|
+
puts "Pipeline created successfully. Pipeline ID: \#{pipeline.payload.id}"
|
16
|
+
else
|
17
|
+
puts "Failed to create pipeline"
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
else
|
21
|
+
puts "Project not found: \#{project_name}"
|
22
|
+
exit 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
CreateForProjectname.create_pipeline
|
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: 15.
|
4
|
+
version: 15.3.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: 2025-
|
11
|
+
date: 2025-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|
@@ -407,15 +407,19 @@ files:
|
|
407
407
|
- lib/gitlab/qa/component/gitlab.rb
|
408
408
|
- lib/gitlab/qa/component/jira.rb
|
409
409
|
- lib/gitlab/qa/component/ldap.rb
|
410
|
+
- lib/gitlab/qa/component/license_ops.rb
|
410
411
|
- lib/gitlab/qa/component/mail_hog.rb
|
411
412
|
- lib/gitlab/qa/component/minio.rb
|
412
413
|
- lib/gitlab/qa/component/mock_server.rb
|
413
414
|
- lib/gitlab/qa/component/opensearch.rb
|
415
|
+
- lib/gitlab/qa/component/pipeline_ops.rb
|
414
416
|
- lib/gitlab/qa/component/postgresql.rb
|
415
417
|
- lib/gitlab/qa/component/praefect.rb
|
416
418
|
- lib/gitlab/qa/component/preprod.rb
|
417
419
|
- lib/gitlab/qa/component/production.rb
|
420
|
+
- lib/gitlab/qa/component/project_importer.rb
|
418
421
|
- lib/gitlab/qa/component/release.rb
|
422
|
+
- lib/gitlab/qa/component/runner_ops.rb
|
419
423
|
- lib/gitlab/qa/component/saml.rb
|
420
424
|
- lib/gitlab/qa/component/selenoid.rb
|
421
425
|
- lib/gitlab/qa/component/specs.rb
|
@@ -452,6 +456,7 @@ files:
|
|
452
456
|
- lib/gitlab/qa/scenario/test/instance/relative_url.rb
|
453
457
|
- lib/gitlab/qa/scenario/test/instance/release.rb
|
454
458
|
- lib/gitlab/qa/scenario/test/instance/repository_storage.rb
|
459
|
+
- lib/gitlab/qa/scenario/test/instance/secure_version.rb
|
455
460
|
- lib/gitlab/qa/scenario/test/instance/smoke.rb
|
456
461
|
- lib/gitlab/qa/scenario/test/instance/staging.rb
|
457
462
|
- lib/gitlab/qa/scenario/test/instance/staging_ref.rb
|
@@ -493,6 +498,7 @@ files:
|
|
493
498
|
- lib/gitlab/qa/scenario/test/omnibus/image.rb
|
494
499
|
- lib/gitlab/qa/scenario/test/omnibus/update_from_previous.rb
|
495
500
|
- lib/gitlab/qa/scenario/test/omnibus/update_from_previous_ai.rb
|
501
|
+
- lib/gitlab/qa/scenario/test/omnibus/update_to_next.rb
|
496
502
|
- lib/gitlab/qa/scenario/test/omnibus/upgrade.rb
|
497
503
|
- lib/gitlab/qa/service/cluster_provider/base.rb
|
498
504
|
- lib/gitlab/qa/service/cluster_provider/k3d.rb
|
@@ -516,6 +522,7 @@ files:
|
|
516
522
|
- support/manifests/suggested_reviewer/pubsub.yaml
|
517
523
|
- support/manifests/suggested_reviewer/recommender-bot.yaml
|
518
524
|
- support/manifests/suggested_reviewer/recommender.yaml
|
525
|
+
- support/pipeline/create_for_projectname.rb
|
519
526
|
- support/setup/gitlab_duo_setup.rb
|
520
527
|
- tls_certificates/authority/ca.crt
|
521
528
|
- tls_certificates/authority/ca.key
|