gitlab-qa 7.25.0 → 7.27.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/.gitlab/ci/jobs/actioncable.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/base.gitlab-ci.yml +281 -0
- data/.gitlab/ci/jobs/cloud_activation.gitlab-ci.yml +30 -0
- data/.gitlab/ci/jobs/custom_parallel.gitlab-ci.yml +21 -0
- data/.gitlab/ci/jobs/ee_previous_to_ce_update.gitlab-ci.yml +18 -0
- data/.gitlab/ci/jobs/elasticsearch.gitlab-ci.yml +20 -0
- data/.gitlab/ci/jobs/geo.gitlab-ci.yml +18 -0
- data/.gitlab/ci/jobs/gitaly_cluster.gitlab-ci.yml +45 -0
- data/.gitlab/ci/jobs/group_saml.gitlab-ci.yml +20 -0
- data/.gitlab/ci/jobs/instance.gitlab-ci.yml +55 -0
- data/.gitlab/ci/jobs/instance_saml.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/integrations.gitlab-ci.yml +14 -0
- data/.gitlab/ci/jobs/jira.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/large_setup.gitlab-ci.yml +19 -0
- data/.gitlab/ci/jobs/ldap_no_server.gitlab-ci.yml +20 -0
- data/.gitlab/ci/jobs/ldap_no_tls.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/ldap_tls.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/mattermost.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/mtls.gitlab-ci.yml +17 -0
- data/.gitlab/ci/jobs/object_storage.gitlab-ci.yml +49 -0
- data/.gitlab/ci/jobs/object_storage_aws.gitlab-ci.yml +25 -0
- data/.gitlab/ci/jobs/object_storage_gcs.gitlab-ci.yml +23 -0
- data/.gitlab/ci/jobs/object_storage_registry_tls.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/omnibus_image.gitlab-ci.yml +15 -0
- data/.gitlab/ci/jobs/omnibus_upgrade.gitlab-ci.yml +28 -0
- data/.gitlab/ci/jobs/packages.gitlab-ci.yml +25 -0
- data/.gitlab/ci/jobs/praefect.gitlab-ci.yml +71 -0
- data/.gitlab/ci/jobs/registry.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/registry_with_cdn.gitlab-ci.yml +43 -0
- data/.gitlab/ci/jobs/relative_url.gitlab-ci.yml +65 -0
- data/.gitlab/ci/jobs/repository_storage.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/sanity_framework.gitlab-ci.yml +24 -0
- data/.gitlab/ci/jobs/service_ping_disabled.gitlab-ci.yml +19 -0
- data/.gitlab/ci/jobs/smtp.gitlab-ci.yml +19 -0
- data/.gitlab/ci/jobs/staging.gitlab-ci.yml +10 -0
- data/.gitlab/ci/jobs/update.gitlab-ci.yml +60 -0
- data/.gitlab/issue_templates/Default.md +2 -0
- data/.gitlab/merge_request_templates/Default.md +2 -0
- data/.gitlab-ci.yml +36 -38
- data/bin/notify_upstream +98 -0
- data/docs/what_tests_can_be_run.md +2 -0
- data/lib/gitlab/qa/component/base.rb +17 -6
- data/lib/gitlab/qa/component/gitlab.rb +17 -7
- data/lib/gitlab/qa/report/gitlab_issue_client.rb +12 -0
- data/lib/gitlab/qa/report/relate_failure_issue.rb +29 -5
- data/lib/gitlab/qa/report/test_result.rb +8 -0
- data/lib/gitlab/qa/report/update_screenshot_path.rb +28 -6
- data/lib/gitlab/qa/runner.rb +7 -0
- data/lib/gitlab/qa/runtime/env.rb +1 -1
- data/lib/gitlab/qa/runtime/omnibus_configuration.rb +1 -1
- data/lib/gitlab/qa/runtime/omnibus_configurations/ci_decomposition.rb +32 -0
- data/lib/gitlab/qa/scenario/test/instance/deployment_base.rb +5 -0
- data/lib/gitlab/qa/scenario/test/instance/image.rb +3 -1
- data/lib/gitlab/qa/scenario/test/integration/geo.rb +2 -1
- data/lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb +2 -0
- data/lib/gitlab/qa/scenario/test/integration/mattermost.rb +5 -1
- data/lib/gitlab/qa/scenario/test/integration/mtls.rb +1 -0
- data/lib/gitlab/qa/scenario/test/omnibus/update.rb +1 -0
- data/lib/gitlab/qa/scenario/test/omnibus/upgrade.rb +1 -0
- data/lib/gitlab/qa/version.rb +1 -1
- data/lib/gitlab/qa.rb +1 -0
- data/scripts/generate-qa-jobs.rb +41 -1710
- data/support/data/admin_access_token_seed.rb +24 -0
- metadata +41 -3
- data/bin/notify_upstream_commit +0 -61
@@ -0,0 +1,19 @@
|
|
1
|
+
ce:service_ping_disabled:
|
2
|
+
extends:
|
3
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
4
|
+
- .test
|
5
|
+
- .high-capacity
|
6
|
+
- .ce-variables
|
7
|
+
- .rspec-report-opts
|
8
|
+
variables:
|
9
|
+
QA_SCENARIO: "Test::Integration::ServicePingDisabled"
|
10
|
+
|
11
|
+
ee:service_ping_disabled:
|
12
|
+
extends:
|
13
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
14
|
+
- .test
|
15
|
+
- .high-capacity
|
16
|
+
- .ee-variables
|
17
|
+
- .rspec-report-opts
|
18
|
+
variables:
|
19
|
+
QA_SCENARIO: "Test::Integration::ServicePingDisabled"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
ce:smtp:
|
2
|
+
extends:
|
3
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
4
|
+
- .test
|
5
|
+
- .high-capacity
|
6
|
+
- .ce-variables
|
7
|
+
- .rspec-report-opts
|
8
|
+
variables:
|
9
|
+
QA_SCENARIO: "Test::Integration::SMTP"
|
10
|
+
|
11
|
+
ee:smtp:
|
12
|
+
extends:
|
13
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
14
|
+
- .test
|
15
|
+
- .high-capacity
|
16
|
+
- .ee-variables
|
17
|
+
- .rspec-report-opts
|
18
|
+
variables:
|
19
|
+
QA_SCENARIO: "Test::Integration::SMTP"
|
@@ -0,0 +1,10 @@
|
|
1
|
+
staging:
|
2
|
+
script:
|
3
|
+
- unset EE_LICENSE
|
4
|
+
- 'echo "Running: bundle exec exe/gitlab-qa Test::Instance::Staging ${RELEASE:=$DEFAULT_RELEASE} -- $QA_TESTS $QA_RSPEC_TAGS"'
|
5
|
+
- bundle exec exe/gitlab-qa Test::Instance::Staging ${RELEASE:=$DEFAULT_RELEASE} -- $QA_TESTS $QA_RSPEC_TAGS
|
6
|
+
extends:
|
7
|
+
- .rules:only-qa-never-when-triggered-by-feature-flag-definition-change
|
8
|
+
- .test
|
9
|
+
- .high-capacity
|
10
|
+
allow_failure: true
|
@@ -0,0 +1,60 @@
|
|
1
|
+
ce:update-parallel:
|
2
|
+
extends:
|
3
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
|
4
|
+
- .test
|
5
|
+
- .high-capacity
|
6
|
+
- .ce-variables
|
7
|
+
- .rspec-report-opts
|
8
|
+
- .update-scenario-script
|
9
|
+
parallel: 5
|
10
|
+
|
11
|
+
ce:update:
|
12
|
+
extends:
|
13
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
|
14
|
+
- .test
|
15
|
+
- .high-capacity
|
16
|
+
- .ce-variables
|
17
|
+
- .rspec-report-opts
|
18
|
+
- .update-scenario-script
|
19
|
+
|
20
|
+
ce:update-quarantine:
|
21
|
+
extends:
|
22
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
23
|
+
- .test
|
24
|
+
- .high-capacity
|
25
|
+
- .ce-variables
|
26
|
+
- .quarantine
|
27
|
+
- .rspec-report-opts
|
28
|
+
- .update-scenario-script
|
29
|
+
variables:
|
30
|
+
QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
|
31
|
+
|
32
|
+
ee:update-parallel:
|
33
|
+
extends:
|
34
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-specified
|
35
|
+
- .test
|
36
|
+
- .high-capacity
|
37
|
+
- .ee-variables
|
38
|
+
- .rspec-report-opts
|
39
|
+
- .update-scenario-script
|
40
|
+
parallel: 10
|
41
|
+
|
42
|
+
ee:update:
|
43
|
+
extends:
|
44
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change-and-never-when-qa-tests-not-specified
|
45
|
+
- .test
|
46
|
+
- .high-capacity
|
47
|
+
- .ee-variables
|
48
|
+
- .rspec-report-opts
|
49
|
+
- .update-scenario-script
|
50
|
+
|
51
|
+
ee:update-quarantine:
|
52
|
+
extends:
|
53
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
54
|
+
- .test
|
55
|
+
- .high-capacity
|
56
|
+
- .ee-variables
|
57
|
+
- .quarantine
|
58
|
+
- .rspec-report-opts
|
59
|
+
variables:
|
60
|
+
QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
|
@@ -11,3 +11,5 @@ If you feel that your issue can be categorized as a reproducible bug or a featur
|
|
11
11
|
|
12
12
|
Thank you for helping to make GitLab a better product.
|
13
13
|
-->
|
14
|
+
|
15
|
+
<!-- template sourced from https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/.gitlab/issue_templates/Default.md -->
|
@@ -44,3 +44,5 @@ This checklist encourages us to confirm any changes have been analyzed to reduce
|
|
44
44
|
* [ ] I have evaluated the [MR acceptance checklist](https://docs.gitlab.com/ee/development/code_review.html#acceptance-checklist) for this MR.
|
45
45
|
|
46
46
|
/label ~QA ~Quality
|
47
|
+
|
48
|
+
<!-- template sourced from https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/.gitlab/merge_request_templates/Default.md -->
|
data/.gitlab-ci.yml
CHANGED
@@ -49,7 +49,13 @@ prepare:
|
|
49
49
|
stage: generate
|
50
50
|
extends: .rules:never-on-version-change-or-tag
|
51
51
|
script:
|
52
|
-
-
|
52
|
+
- |
|
53
|
+
if [[ $TOP_UPSTREAM_SOURCE_PROJECT == "gitlab-org/gitlab" && -n $TOP_UPSTREAM_SOURCE_SHA ]]; then
|
54
|
+
export QA_IMAGE_TAG=${TOP_UPSTREAM_SOURCE_SHA}
|
55
|
+
else
|
56
|
+
export QA_IMAGE_TAG=master
|
57
|
+
fi
|
58
|
+
- 'echo "QA_IMAGE_TAG=$QA_IMAGE_TAG" >> prep_vars.env'
|
53
59
|
- 'echo $QA_IMAGE_TAG'
|
54
60
|
artifacts:
|
55
61
|
reports:
|
@@ -58,40 +64,6 @@ prepare:
|
|
58
64
|
- prep_vars.env
|
59
65
|
|
60
66
|
generate-jobs:
|
61
|
-
stage: generate
|
62
|
-
extends: .rules:never-on-version-change-or-tag
|
63
|
-
script:
|
64
|
-
# TOP_UPSTREAM_DEFAULT_BRANCH is the default branch name of the original project that triggered a pipeline in this project.
|
65
|
-
- 'export TOP_UPSTREAM_DEFAULT_BRANCH=${TOP_UPSTREAM_DEFAULT_BRANCH:=master} && echo "TOP_UPSTREAM_DEFAULT_BRANCH=$TOP_UPSTREAM_DEFAULT_BRANCH" >> variables.env'
|
66
|
-
- 'echo "RELEASE=$RELEASE" >> variables.env'
|
67
|
-
- 'echo "GITLAB_QA_OPTIONS=$GITLAB_QA_OPTIONS" >> variables.env'
|
68
|
-
- 'echo "QA_TESTS=$QA_TESTS" >> variables.env'
|
69
|
-
- 'echo "KNAPSACK_GENERATE_REPORT=$KNAPSACK_GENERATE_REPORT" >> variables.env'
|
70
|
-
- 'echo "TOP_UPSTREAM_SOURCE_JOB=$TOP_UPSTREAM_SOURCE_JOB" >> variables.env'
|
71
|
-
- 'echo "TOP_UPSTREAM_SOURCE_REF=$TOP_UPSTREAM_SOURCE_REF" >> variables.env'
|
72
|
-
- 'echo "DISABLE_RELATING_FAILURE_ISSUES=$DISABLE_RELATING_FAILURE_ISSUES" >> variables.env'
|
73
|
-
- 'echo "TOP_UPSTREAM_SOURCE_PROJECT=$TOP_UPSTREAM_SOURCE_PROJECT" >> variables.env'
|
74
|
-
- 'echo "TOP_UPSTREAM_SOURCE_SHA=$TOP_UPSTREAM_SOURCE_SHA" >> variables.env'
|
75
|
-
- 'echo "NOTIFY_CHANNEL=$NOTIFY_CHANNEL" >> variables.env'
|
76
|
-
- 'echo "QA_IMAGE=$QA_IMAGE" >> variables.env'
|
77
|
-
- 'echo "EE_LICENSE=$EE_LICENSE" >> variables.env'
|
78
|
-
- 'echo "TOP_UPSTREAM_MERGE_REQUEST_IID=$TOP_UPSTREAM_MERGE_REQUEST_IID" >> variables.env'
|
79
|
-
- 'echo "ALLURE_JOB_NAME=$ALLURE_JOB_NAME" >> variables.env'
|
80
|
-
|
81
|
-
- ./scripts/generate-qa-jobs.rb
|
82
|
-
- cat generated-qa-jobs.yml
|
83
|
-
artifacts:
|
84
|
-
reports:
|
85
|
-
dotenv: variables.env
|
86
|
-
paths:
|
87
|
-
- generated-qa-jobs.yml
|
88
|
-
- variables.env
|
89
|
-
expire_in: 2 days
|
90
|
-
needs:
|
91
|
-
- job: generate-count-example-files
|
92
|
-
artifacts: true
|
93
|
-
|
94
|
-
generate-count-example-files:
|
95
67
|
stage: generate
|
96
68
|
extends: .rules:never-on-version-change-or-tag
|
97
69
|
image:
|
@@ -104,8 +76,9 @@ generate-count-example-files:
|
|
104
76
|
before_script:
|
105
77
|
- cd /home/gitlab/qa
|
106
78
|
script:
|
79
|
+
# Generate count example files
|
107
80
|
- bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS
|
108
|
-
- bundle exec bin/qa Test::Integration::Mattermost http://dummy.test http://mattermost.test --count-examples-only -- $QA_TESTS
|
81
|
+
- bundle exec bin/qa Test::Integration::Mattermost http://dummy.test --mattermost-address http://mattermost.test --count-examples-only -- $QA_TESTS
|
109
82
|
- bundle exec bin/qa Test::Integration::ServicePingDisabled http://dummy.test --count-examples-only -- $QA_TESTS
|
110
83
|
- bundle exec bin/qa QA::EE::Scenario::Test::Geo --count-examples-only --primary-address http://dummy1.test --primary-name gitlab-primary --secondary-address http://dummy2.test --secondary-name gitlab-secondary --without-setup
|
111
84
|
- bundle exec bin/qa Test::Integration::LDAPNoTLS http://dummy.test --count-examples-only -- $QA_TESTS
|
@@ -127,12 +100,37 @@ generate-count-example-files:
|
|
127
100
|
- bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag can_use_large_setup
|
128
101
|
- bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag cloud_activation
|
129
102
|
- bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag object_storage
|
130
|
-
|
131
103
|
- cp -r no_of_examples $CI_PROJECT_DIR
|
104
|
+
|
105
|
+
# TOP_UPSTREAM_DEFAULT_BRANCH is the default branch name of the original project that triggered a pipeline in this project.
|
106
|
+
- 'export TOP_UPSTREAM_DEFAULT_BRANCH=${TOP_UPSTREAM_DEFAULT_BRANCH:=master} && echo "TOP_UPSTREAM_DEFAULT_BRANCH=$TOP_UPSTREAM_DEFAULT_BRANCH" >> variables.env'
|
107
|
+
- 'echo "RELEASE=$RELEASE" >> variables.env'
|
108
|
+
- 'echo "GITLAB_QA_OPTIONS=$GITLAB_QA_OPTIONS" >> variables.env'
|
109
|
+
- 'echo "QA_TESTS=$QA_TESTS" >> variables.env'
|
110
|
+
- 'echo "KNAPSACK_GENERATE_REPORT=$KNAPSACK_GENERATE_REPORT" >> variables.env'
|
111
|
+
- 'echo "TOP_UPSTREAM_SOURCE_JOB=$TOP_UPSTREAM_SOURCE_JOB" >> variables.env'
|
112
|
+
- 'echo "TOP_UPSTREAM_SOURCE_REF=$TOP_UPSTREAM_SOURCE_REF" >> variables.env'
|
113
|
+
- 'echo "DISABLE_RELATING_FAILURE_ISSUES=$DISABLE_RELATING_FAILURE_ISSUES" >> variables.env'
|
114
|
+
- 'echo "TOP_UPSTREAM_SOURCE_PROJECT=$TOP_UPSTREAM_SOURCE_PROJECT" >> variables.env'
|
115
|
+
- 'echo "TOP_UPSTREAM_SOURCE_SHA=$TOP_UPSTREAM_SOURCE_SHA" >> variables.env'
|
116
|
+
- 'echo "NOTIFY_CHANNEL=$NOTIFY_CHANNEL" >> variables.env'
|
117
|
+
- 'echo "QA_IMAGE=$QA_IMAGE" >> variables.env'
|
118
|
+
- 'echo "EE_LICENSE=$EE_LICENSE" >> variables.env'
|
119
|
+
- 'echo "TOP_UPSTREAM_MERGE_REQUEST_IID=$TOP_UPSTREAM_MERGE_REQUEST_IID" >> variables.env'
|
120
|
+
- 'echo "ALLURE_JOB_NAME=$ALLURE_JOB_NAME" >> variables.env'
|
121
|
+
- mv variables.env $CI_PROJECT_DIR
|
122
|
+
|
123
|
+
- cd $CI_PROJECT_DIR
|
124
|
+
- ./scripts/generate-qa-jobs.rb
|
125
|
+
- cat generated-qa-jobs.yml
|
132
126
|
artifacts:
|
127
|
+
reports:
|
128
|
+
dotenv: variables.env
|
133
129
|
paths:
|
130
|
+
- generated-qa-jobs.yml
|
131
|
+
- variables.env
|
134
132
|
- no_of_examples
|
135
|
-
|
133
|
+
expire_in: 2 days
|
136
134
|
|
137
135
|
trigger-generated-jobs:
|
138
136
|
stage: triggers
|
data/bin/notify_upstream
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'gitlab'
|
5
|
+
|
6
|
+
# Default to "Multi-pipeline (from 'gitlab-org/gitlab-qa' 'notify_upstream:*' jobs)" from current project
|
7
|
+
api_token = ENV.fetch('GITLAB_QA_PROJECT_ACCESS_TOKEN') do
|
8
|
+
puts "The $GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN variable is deprecated in favor of a dedicated project access token: $GITLAB_QA_PROJECT_ACCESS_TOKEN."
|
9
|
+
puts "See https://gitlab.com/groups/gitlab-org/quality/-/epics/17 for more details."
|
10
|
+
ENV['GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN']
|
11
|
+
end
|
12
|
+
|
13
|
+
# Configure credentials to be used with gitlab gem
|
14
|
+
Gitlab.configure do |config|
|
15
|
+
config.endpoint = 'https://gitlab.com/api/v4'
|
16
|
+
config.private_token = api_token
|
17
|
+
end
|
18
|
+
|
19
|
+
class CommitComment
|
20
|
+
UPSTREAM_COMMENT = <<~COMMENT
|
21
|
+
- The [`gitlab-qa-mirror` downstream pipeline](%<pipeline_url>s) for https://gitlab.com/%<project_path>s/-/merge_requests/%<mr_iid>s/diffs?commit_id=%<commit_sha>s %<status_with_icon>s
|
22
|
+
COMMENT
|
23
|
+
IDENTIFIABLE_NOTE_TAG = 'gitlab-qa:upstream-notification-note'
|
24
|
+
|
25
|
+
def self.mr?
|
26
|
+
ENV.key?('TOP_UPSTREAM_SOURCE_PROJECT') &&
|
27
|
+
ENV.key?('TOP_UPSTREAM_MERGE_REQUEST_IID') &&
|
28
|
+
ENV.key?('TOP_UPSTREAM_SOURCE_SHA') &&
|
29
|
+
!ENV['TOP_UPSTREAM_SOURCE_PROJECT'].to_s.empty? &&
|
30
|
+
!ENV['TOP_UPSTREAM_MERGE_REQUEST_IID'].to_s.empty? &&
|
31
|
+
!ENV['TOP_UPSTREAM_SOURCE_SHA'].to_s.empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.post!(status)
|
35
|
+
unless mr?
|
36
|
+
puts "All the 'TOP_UPSTREAM_SOURCE_PROJECT', 'TOP_UPSTREAM_MERGE_REQUEST_IID', and 'TOP_UPSTREAM_SOURCE_SHA' environment variables need to be present. We cannot post a comment on the upstream merge request."
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
# Look for an existing note
|
41
|
+
upstream_notification_note = Gitlab.merge_request_notes(project_path, mr_iid).auto_paginate.find do |note|
|
42
|
+
note.body.include?(IDENTIFIABLE_NOTE_TAG)
|
43
|
+
end
|
44
|
+
|
45
|
+
if upstream_notification_note
|
46
|
+
Gitlab.edit_merge_request_note(project_path, mr_iid, upstream_notification_note.id, [upstream_notification_note.body, build_comment(status)].join("\n"))
|
47
|
+
else
|
48
|
+
Gitlab.create_merge_request_comment(project_path, mr_iid, "<!-- #{IDENTIFIABLE_NOTE_TAG} -->\n#{build_comment(status)}")
|
49
|
+
end
|
50
|
+
rescue Gitlab::Error::Error => error
|
51
|
+
puts "Ignoring the following error: #{error}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.project_path
|
55
|
+
ENV['TOP_UPSTREAM_SOURCE_PROJECT']
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.mr_iid
|
59
|
+
ENV['TOP_UPSTREAM_MERGE_REQUEST_IID']
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.pipeline_url
|
63
|
+
ENV['CI_PIPELINE_URL']
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.commit_sha
|
67
|
+
ENV['TOP_UPSTREAM_SOURCE_SHA']
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.build_comment(status)
|
71
|
+
format(UPSTREAM_COMMENT,
|
72
|
+
project_path: project_path,
|
73
|
+
mr_iid: mr_iid,
|
74
|
+
pipeline_url: pipeline_url,
|
75
|
+
status_with_icon: status_with_icon(status),
|
76
|
+
commit_sha: commit_sha
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.status_with_icon(status)
|
81
|
+
case status
|
82
|
+
when :success
|
83
|
+
"passed. :white_check_mark:"
|
84
|
+
when :failure
|
85
|
+
"failed! :boom:"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.post_to_mr(project_id, mr_iid, comment)
|
90
|
+
Gitlab.create_merge_request_comment(project_id, mr_iid, comment)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
status = ARGV.shift.to_s.strip
|
95
|
+
|
96
|
+
abort "Please provide a status!" if status == ''
|
97
|
+
|
98
|
+
CommitComment.post!(status.to_sym)
|
@@ -637,6 +637,8 @@ container is spun up and tests are run from it by running the
|
|
637
637
|
- `JIRA_ADMIN_USERNAME`: Username for authenticating with Jira server as admin.
|
638
638
|
- `JIRA_ADMIN_PASSWORD`: Password for authenticating with Jira server as admin.
|
639
639
|
|
640
|
+
These values can be found in the shared GitLab QA 1Password vault.
|
641
|
+
|
640
642
|
Example:
|
641
643
|
|
642
644
|
```
|
@@ -124,7 +124,6 @@ module Gitlab
|
|
124
124
|
|
125
125
|
return unless docker.running?(name)
|
126
126
|
|
127
|
-
docker.stop(name)
|
128
127
|
docker.remove(name)
|
129
128
|
end
|
130
129
|
|
@@ -147,11 +146,23 @@ module Gitlab
|
|
147
146
|
end
|
148
147
|
|
149
148
|
def instance_no_teardown
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
149
|
+
begin
|
150
|
+
retries ||= 0
|
151
|
+
prepare
|
152
|
+
start
|
153
|
+
reconfigure
|
154
|
+
wait_until_ready
|
155
|
+
process_exec_commands
|
156
|
+
rescue Docker::Shellout::StatusError => e
|
157
|
+
# for scenarios where a service fails during startup, attempt to retry to avoid flaky failures
|
158
|
+
if (retries += 1) < 3
|
159
|
+
puts "Retry instance_no_teardown due to Docker::Shellout::StatusError -- attempt #{retries}"
|
160
|
+
teardown!
|
161
|
+
retry
|
162
|
+
end
|
163
|
+
|
164
|
+
raise e
|
165
|
+
end
|
155
166
|
|
156
167
|
yield self if block_given?
|
157
168
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# rubocop:disable Metrics/AbcSize
|
2
3
|
|
3
4
|
require 'securerandom'
|
4
5
|
require 'net/http'
|
@@ -14,7 +15,7 @@ module Gitlab
|
|
14
15
|
extend Forwardable
|
15
16
|
|
16
17
|
attr_reader :release, :omnibus_configuration, :omnibus_gitlab_rails_env
|
17
|
-
attr_accessor :tls, :skip_availability_check, :runner_network
|
18
|
+
attr_accessor :tls, :skip_availability_check, :runner_network, :seed_admin_token, :seed_db
|
18
19
|
attr_writer :name, :relative_path
|
19
20
|
|
20
21
|
def_delegators :release, :tag, :image, :edition
|
@@ -42,8 +43,10 @@ module Gitlab
|
|
42
43
|
@volumes[@gitlab_cert_path] = SSL_PATH
|
43
44
|
@volumes[@authority_cert_path] = TRUSTED_PATH
|
44
45
|
|
46
|
+
@seed_admin_token = Runtime::Scenario.seed_admin_token
|
47
|
+
@seed_db = Runtime::Scenario.seed_db
|
48
|
+
|
45
49
|
self.release = 'CE'
|
46
|
-
self.exec_commands += seed_test_data_command if Runtime::Scenario.seed_db
|
47
50
|
end
|
48
51
|
|
49
52
|
def set_formless_login_token
|
@@ -154,8 +157,7 @@ module Gitlab
|
|
154
157
|
@docker.attach(name) do |line, wait|
|
155
158
|
puts line
|
156
159
|
# TODO, workaround which allows to detach from the container
|
157
|
-
|
158
|
-
break if line =~ /gitlab Reconfigured!/
|
160
|
+
break if /gitlab Reconfigured!/.match?(line)
|
159
161
|
end
|
160
162
|
end
|
161
163
|
|
@@ -163,7 +165,6 @@ module Gitlab
|
|
163
165
|
return if skip_availability_check
|
164
166
|
|
165
167
|
if Availability.new(name, relative_path: relative_path, scheme: scheme, protocol_port: port.to_i).check(Runtime::Env.gitlab_availability_timeout)
|
166
|
-
sleep 12 # TODO, handle that better
|
167
168
|
puts ' -> GitLab is available.'
|
168
169
|
else
|
169
170
|
abort ' -> GitLab unavailable!'
|
@@ -171,9 +172,13 @@ module Gitlab
|
|
171
172
|
end
|
172
173
|
|
173
174
|
def process_exec_commands
|
174
|
-
@docker.copy(name, DATA_SEED_PATH, DATA_PATH) if
|
175
|
+
@docker.copy(name, DATA_SEED_PATH, DATA_PATH) if seed_admin_token || seed_db
|
176
|
+
|
177
|
+
self.exec_commands += seed_admin_token_command if seed_admin_token
|
178
|
+
self.exec_commands += seed_test_data_command if seed_db
|
175
179
|
|
176
|
-
|
180
|
+
Runtime::Logger.info("Running exec_commands...")
|
181
|
+
exec_commands.flatten.uniq.each { |command| @docker.exec(name, command) }
|
177
182
|
end
|
178
183
|
|
179
184
|
def sha_version
|
@@ -231,6 +236,10 @@ module Gitlab
|
|
231
236
|
cmd.uniq
|
232
237
|
end
|
233
238
|
|
239
|
+
def seed_admin_token_command
|
240
|
+
["gitlab-rails runner #{DATA_PATH}/admin_access_token_seed.rb"]
|
241
|
+
end
|
242
|
+
|
234
243
|
class Availability
|
235
244
|
def initialize(name, relative_path: '', scheme: 'http', protocol_port: 80)
|
236
245
|
@docker = Docker::Engine.new
|
@@ -276,3 +285,4 @@ module Gitlab
|
|
276
285
|
end
|
277
286
|
end
|
278
287
|
end
|
288
|
+
# rubocop:enable Metrics/AbcSize
|
@@ -101,6 +101,18 @@ module Gitlab
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
+
def upload_file(file_fullpath:)
|
105
|
+
ignore_gitlab_client_exceptions do
|
106
|
+
Gitlab.upload_file(project, file_fullpath)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def ignore_gitlab_client_exceptions
|
111
|
+
yield
|
112
|
+
rescue StandardError, SystemCallError, OpenSSL::SSL::SSLError, Net::OpenTimeout, Net::ReadTimeout, Gitlab::Error::Error => e
|
113
|
+
puts "Ignoring the following error: #{e}"
|
114
|
+
end
|
115
|
+
|
104
116
|
def handle_gitlab_client_exceptions
|
105
117
|
yield
|
106
118
|
rescue Gitlab::Error::NotFound
|
@@ -47,7 +47,7 @@ module Gitlab
|
|
47
47
|
puts " => Searching issues for test '#{test.name}'..."
|
48
48
|
|
49
49
|
begin
|
50
|
-
issue = find_and_link_issue(test) || create_issue(test)
|
50
|
+
issue = test.quarantine? ? find_and_link_issue(test) : find_and_link_issue(test) || create_issue(test)
|
51
51
|
return unless issue
|
52
52
|
|
53
53
|
update_labels(issue, test)
|
@@ -72,6 +72,8 @@ module Gitlab
|
|
72
72
|
issue = super
|
73
73
|
puts "for test '#{test.name}'."
|
74
74
|
|
75
|
+
post_or_update_failed_job_note(issue, test)
|
76
|
+
|
75
77
|
issue
|
76
78
|
end
|
77
79
|
|
@@ -82,10 +84,17 @@ module Gitlab
|
|
82
84
|
end
|
83
85
|
end
|
84
86
|
|
87
|
+
def full_stacktrace(test)
|
88
|
+
if test.failures.first['message_lines'].empty?
|
89
|
+
test.failures.first['message']
|
90
|
+
else
|
91
|
+
test.failures.first['message_lines'].join("\n")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
85
95
|
def find_relevant_failure_issues(test) # rubocop:disable Metrics/AbcSize
|
86
96
|
ld = Class.new.extend(Gem::Text).method(:levenshtein_distance)
|
87
|
-
|
88
|
-
first_test_failure_stacktrace = sanitize_stacktrace(full_stacktrace, FAILURE_STACKTRACE_REGEX) || full_stacktrace
|
97
|
+
first_test_failure_stacktrace = sanitize_stacktrace(full_stacktrace(test), FAILURE_STACKTRACE_REGEX) || full_stacktrace(test)
|
89
98
|
clean_first_test_failure_stacktrace = remove_unique_resource_names(first_test_failure_stacktrace)
|
90
99
|
|
91
100
|
# Search with the `search` param returns 500 errors, so we filter by ~QA and then filter further in Ruby
|
@@ -156,9 +165,10 @@ module Gitlab
|
|
156
165
|
def new_issue_description(test)
|
157
166
|
super + [
|
158
167
|
"\n\n### Stack trace",
|
159
|
-
"```\n#{test
|
168
|
+
"```\n#{full_stacktrace(test)}\n```",
|
160
169
|
"First happened in #{test.ci_job_url}.",
|
161
|
-
"Related test case: #{test.testcase}."
|
170
|
+
"Related test case: #{test.testcase}.",
|
171
|
+
screenshot_section(test)
|
162
172
|
].join("\n\n")
|
163
173
|
end
|
164
174
|
|
@@ -194,6 +204,20 @@ module Gitlab
|
|
194
204
|
|
195
205
|
false
|
196
206
|
end
|
207
|
+
|
208
|
+
def screenshot_section(test)
|
209
|
+
section = ''
|
210
|
+
|
211
|
+
failure = full_stacktrace(test)
|
212
|
+
|
213
|
+
if test.screenshot? && !failure.include?('500 Internal Server Error') && !failure.include?('fabricate_via_api!')
|
214
|
+
relative_url = gitlab.upload_file(file_fullpath: test.failure_screenshot)
|
215
|
+
|
216
|
+
section = "### Screenshot: #{relative_url.markdown}"
|
217
|
+
end
|
218
|
+
|
219
|
+
section
|
220
|
+
end
|
197
221
|
end
|
198
222
|
end
|
199
223
|
end
|
@@ -95,6 +95,14 @@ module Gitlab
|
|
95
95
|
report['quarantine']['issue'] if quarantine?
|
96
96
|
end
|
97
97
|
|
98
|
+
def screenshot?
|
99
|
+
report['screenshot'].present?
|
100
|
+
end
|
101
|
+
|
102
|
+
def failure_screenshot
|
103
|
+
report['screenshot']['image'] if screenshot?
|
104
|
+
end
|
105
|
+
|
98
106
|
private
|
99
107
|
|
100
108
|
# rubocop:disable Metrics/AbcSize
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'nokogiri'
|
2
|
+
require 'json'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
2
4
|
|
3
5
|
module Gitlab
|
4
6
|
module QA
|
@@ -9,30 +11,50 @@ module Gitlab
|
|
9
11
|
end
|
10
12
|
|
11
13
|
REGEX = %r{(?<gitlab_qa_run>gitlab-qa-run-.*?(?=\/))\/(?<gitlab_ce_ee_qa>gitlab-(ee|ce)-qa-.*?(?=\/))}
|
14
|
+
CONTAINER_PATH = File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'tmp').freeze
|
12
15
|
|
13
16
|
def invoke!
|
14
17
|
Dir.glob(@files).each do |rspec_report_file|
|
15
|
-
|
18
|
+
match_data = rspec_report_file.match(REGEX)
|
19
|
+
artifact_path = "#{match_data[:gitlab_qa_run]}/#{match_data[:gitlab_ce_ee_qa]}"
|
16
20
|
|
17
|
-
|
21
|
+
xml_report = rewrite_each_xml_screenshot_path(rspec_report_file, artifact_path)
|
22
|
+
|
23
|
+
File.write(rspec_report_file, xml_report)
|
18
24
|
|
19
25
|
puts "Saved #{rspec_report_file}"
|
26
|
+
|
27
|
+
json_rspec_report_file = rspec_report_file.gsub('.xml', '.json')
|
28
|
+
json_report = rewrite_each_json_screenshot_path(json_rspec_report_file, artifact_path)
|
29
|
+
|
30
|
+
File.write(json_rspec_report_file, json_report)
|
31
|
+
|
32
|
+
puts "Saved #{json_rspec_report_file}"
|
20
33
|
end
|
21
34
|
end
|
22
35
|
|
23
36
|
private
|
24
37
|
|
25
|
-
def
|
38
|
+
def rewrite_each_xml_screenshot_path(rspec_report_file, artifact_path)
|
26
39
|
report = Nokogiri::XML(File.open(rspec_report_file))
|
27
40
|
|
28
|
-
match_data = rspec_report_file.match(REGEX)
|
29
|
-
|
30
41
|
report.xpath('//system-out').each do |system_out|
|
31
|
-
system_out.content = system_out.content.gsub(
|
42
|
+
system_out.content = system_out.content.gsub(CONTAINER_PATH, artifact_path)
|
32
43
|
end
|
33
44
|
|
34
45
|
report.to_s
|
35
46
|
end
|
47
|
+
|
48
|
+
def rewrite_each_json_screenshot_path(json_rspec_report_file, artifact_path)
|
49
|
+
report = JSON.parse(File.read(json_rspec_report_file))
|
50
|
+
examples = report['examples']
|
51
|
+
|
52
|
+
examples.each do |example|
|
53
|
+
example['screenshot']['image'] = example['screenshot']['image'].gsub(CONTAINER_PATH, artifact_path) if example['screenshot'].present?
|
54
|
+
end
|
55
|
+
|
56
|
+
JSON.pretty_generate(report)
|
57
|
+
end
|
36
58
|
end
|
37
59
|
end
|
38
60
|
end
|
data/lib/gitlab/qa/runner.rb
CHANGED
@@ -13,6 +13,8 @@ module Gitlab
|
|
13
13
|
Runtime::Scenario.define(:qa_image, Runtime::Env.qa_image) if Runtime::Env.qa_image
|
14
14
|
Runtime::Scenario.define(:omnibus_configuration, Runtime::OmnibusConfiguration.new)
|
15
15
|
Runtime::Scenario.define(:seed_db, false)
|
16
|
+
Runtime::Scenario.define(:seed_admin_token, true) # Create an admin access token for root user by default
|
17
|
+
Runtime::Scenario.define(:omnibus_exec_commands, [])
|
16
18
|
|
17
19
|
# Omnibus Configurators specified by flags
|
18
20
|
@active_configurators = []
|
@@ -31,6 +33,10 @@ module Gitlab
|
|
31
33
|
Runtime::Scenario.define(:teardown, false)
|
32
34
|
end
|
33
35
|
|
36
|
+
opts.on('--no-admin-token', 'Skip admin token creation for root user') do
|
37
|
+
Runtime::Scenario.define(:seed_admin_token, false)
|
38
|
+
end
|
39
|
+
|
34
40
|
opts.on('--qa-image QA_IMAGE', String, 'Specifies a QA image to be used instead of inferring it from the GitLab image. See Gitlab::QA::Release#qa_image') do |value|
|
35
41
|
Runtime::Scenario.define(:qa_image, value)
|
36
42
|
end
|
@@ -135,6 +141,7 @@ module Gitlab
|
|
135
141
|
# # Runtime::OmnibusConfiguration::Packages
|
136
142
|
# gitlab_rails['packages_enabled'] = true
|
137
143
|
Runtime::Scenario.omnibus_configuration << "# #{configurator.class.name}"
|
144
|
+
Runtime::Scenario.omnibus_exec_commands << configurator.exec_commands
|
138
145
|
|
139
146
|
# Load the configuration
|
140
147
|
configurator.configuration.split("\n").each { |c| Runtime::Scenario.omnibus_configuration << c }
|