Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-09-15 06:12:51 +00:00
parent 6eb95ccbe8
commit 9a0e0265e4
21 changed files with 368 additions and 226 deletions

View File

@ -4,7 +4,6 @@ variables:
RELEASE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/build/omnibus-gitlab-mirror/gitlab-ee:${CI_COMMIT_SHA}"
SKIP_REPORT_IN_ISSUES: "true"
OMNIBUS_GITLAB_CACHE_UPDATE: "false"
COLORIZED_LOGS: "true"
QA_LOG_LEVEL: "info"
QA_TESTS: ""
QA_FEATURE_FLAGS: ""

View File

@ -11,6 +11,7 @@ stages:
include:
- local: .gitlab/ci/global.gitlab-ci.yml
- local: .gitlab/ci/rules.gitlab-ci.yml
- local: .gitlab/ci/review-apps/rules.gitlab-ci.yml
- local: .gitlab/ci/review-apps/qa.gitlab-ci.yml
- local: .gitlab/ci/review-apps/dast.gitlab-ci.yml
@ -97,6 +98,7 @@ review-deploy:
- export GITALY_VERSION=$(<GITALY_SERVER_VERSION)
- export GITLAB_WORKHORSE_VERSION=$(<GITLAB_WORKHORSE_VERSION)
- echo "${CI_ENVIRONMENT_URL}" > environment_url.txt
- echo "QA_GITLAB_URL=${CI_ENVIRONMENT_URL}" > environment.env
- *base-before_script
script:
- check_kube_domain
@ -112,6 +114,8 @@ review-deploy:
artifacts:
paths:
- environment_url.txt
reports:
dotenv: environment.env
expire_in: 7 days
when: always

View File

@ -1,6 +1,6 @@
include:
- project: gitlab-org/quality/pipeline-common
ref: 0.13.0
ref: 1.2.2
file:
- /ci/allure-report.yml
- /ci/knapsack-report.yml
@ -8,7 +8,7 @@ include:
.test-variables:
variables:
QA_GENERATE_ALLURE_REPORT: "true"
COLORIZED_LOGS: "true"
QA_CAN_TEST_PRAEFECT: "false"
GITLAB_USERNAME: "root"
GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
GITLAB_ADMIN_USERNAME: "root"
@ -21,49 +21,31 @@ include:
- .qa-cache
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.3
before_script:
- export QA_GITLAB_URL="$(cat environment_url.txt)"
- cd qa && bundle install
.review-qa-base:
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.3-git-2.33-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-gcloud-383-kubectl-1.23
extends:
- .use-docker-in-docker
- .bundle-base
- .test-variables
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.3-git-2.33-lfs-2.9-chrome-${CHROME_VERSION}-docker-${DOCKER_VERSION}-gcloud-383-kubectl-1.23
stage: qa
needs:
- review-deploy
- download-knapsack-report
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: /certs
DOCKER_CERT_PATH: /certs/client
DOCKER_TLS_VERIFY: 1
GIT_LFS_SKIP_SMUDGE: 1
WD_INSTALL_DIR: /usr/local/bin
before_script:
- !reference [.bundle-base, before_script]
RSPEC_REPORT_OPTS: --force-color --order random --format documentation --format RspecJunitFormatter --out tmp/rspec.xml
script:
- export EE_LICENSE="$(cat $REVIEW_APPS_EE_LICENSE_FILE)"
- qa_run_status=0
- QA_COMMAND="bundle exec bin/qa ${QA_SCENARIO} ${QA_GITLAB_URL} -- ${QA_TESTS} ${RSPEC_REPORT_OPTS}"
- echo "Running - '${QA_COMMAND}'"
- eval "$QA_COMMAND"
after_script:
- |
bundle exec rake "knapsack:rspec[\
${RSPEC_TAGS} \
--tag ~orchestrated \
--tag ~transient \
--tag ~skip_signup_disabled \
--tag ~requires_git_protocol_v2 \
--tag ~requires_praefect \
--force-color \
--order random \
--format documentation \
--format RspecJunitFormatter --out tmp/rspec.xml \
]" || qa_run_status=$?
- if [ ${qa_run_status} -ne 0 ]; then
release_sha=$(echo "${CI_COMMIT_SHA}" | cut -c1-11);
echo "Errors can be found at https://sentry.gitlab.net/gitlab/gitlab-review-apps/releases/${release_sha}/all-events/.";
fi
- exit ${qa_run_status}
echo "Sentry errors for the current review-app test run can be found via following url:"
echo "https://sentry.gitlab.net/gitlab/gitlab-review-apps/releases/$(echo "${CI_COMMIT_SHA}" | cut -c1-11)/all-events/."
artifacts:
paths:
- qa/tmp
@ -72,20 +54,11 @@ include:
expire_in: 7 days
when: always
.allure-report-base:
extends: .generate-allure-report-base
stage: post-qa
variables:
GITLAB_AUTH_TOKEN: $GITLAB_QA_MR_ALLURE_REPORT_TOKEN
ALLURE_PROJECT_PATH: $CI_PROJECT_PATH
ALLURE_MERGE_REQUEST_IID: $CI_MERGE_REQUEST_IID
ALLURE_RESULTS_GLOB: qa/tmp/allure-results/*
# Store knapsack report as artifact so the same report is reused across all jobs
download-knapsack-report:
extends:
- .bundle-base
- .review:rules:review-qa-reliable
- .rules:qa-framework-changes-or-review-scenarios
stage: prepare
script:
- bundle exec rake "knapsack:download[qa]"
@ -98,30 +71,39 @@ download-knapsack-report:
review-qa-smoke:
extends:
- .review-qa-base
- .review:rules:review-qa-smoke
retry: 1
- .rules:qa-smoke
variables:
QA_SCENARIO: Test::Instance::Smoke
QA_RUN_TYPE: review-qa-smoke
RSPEC_TAGS: --tag smoke
review-qa-reliable:
extends:
- .review-qa-base
- .review:rules:review-qa-reliable
retry: 1
parallel: 10
variables:
QA_RUN_TYPE: review-qa-reliable
RSPEC_TAGS: --tag reliable --tag sanity_feature_flags
review-qa-all:
review-qa-blocking:
extends:
- .review-qa-base
- .review:rules:review-qa-all
parallel: 5
- .rules:qa-blocking
variables:
QA_RUN_TYPE: review-qa-all
RSPEC_TAGS: --tag ~reliable --tag ~smoke --tag ~sanity_feature_flags
QA_SCENARIO: Test::Instance::ReviewBlocking
QA_RUN_TYPE: review-qa-blocking
retry: 1
review-qa-blocking-parallel:
extends:
- review-qa-blocking
- .rules:qa-blocking-parallel
parallel: 10
review-qa-non-blocking:
extends:
- .review-qa-base
- .rules:qa-non-blocking
variables:
QA_SCENARIO: Test::Instance::ReviewNonBlocking
QA_RUN_TYPE: review-qa-non-blocking
allow_failure: true
review-qa-non-blocking-parallel:
extends:
- review-qa-non-blocking
- .rules:qa-non-blocking-parallel
parallel: 5
review-performance:
extends:
@ -149,27 +131,20 @@ review-performance:
performance: performance.json
expire_in: 31d
# Generate single report for both smoke and reliable test jobs
# Both job types are essentially the same:
# * always executed
# * always blocking
allure-report-qa-blocking:
e2e-test-report:
extends:
- .allure-report-base
- .review:rules:review-qa-blocking-report
needs:
- review-qa-smoke
- review-qa-reliable
- .generate-allure-report-base
- .rules:qa-framework-changes-or-review-scenarios
stage: post-qa
variables:
ALLURE_JOB_NAME: e2e-review-qa-blocking
allure-report-qa-all:
extends:
- .allure-report-base
- .review:rules:review-qa-all-report
needs: ["review-qa-all"]
variables:
ALLURE_JOB_NAME: e2e-review-qa-all
ALLURE_JOB_NAME: e2e-review-qa
ALLURE_PROJECT_PATH: $CI_PROJECT_PATH
ALLURE_RESULTS_GLOB: qa/tmp/allure-results/*
ALLURE_MERGE_REQUEST_IID: $CI_MERGE_REQUEST_IID
GITLAB_AUTH_TOKEN: $GITLAB_QA_MR_ALLURE_REPORT_TOKEN
GIT_STRATEGY: none
allow_failure: true
when: always
upload-knapsack-report:
extends:
@ -182,13 +157,13 @@ upload-knapsack-report:
delete-test-resources:
extends:
- .bundle-base
- .review:rules:review-qa-cleanup
- .rules:qa-framework-changes-or-review-scenarios
stage: post-qa
variables:
QA_TEST_RESOURCES_FILE_PATTERN: $CI_PROJECT_DIR/qa/tmp/test-resources-*.json
GITLAB_QA_ACCESS_TOKEN: $REVIEW_APPS_ROOT_TOKEN
COLORIZED_LOGS: "true"
script:
- export GITLAB_ADDRESS="$QA_GITLAB_URL"
- bundle exec rake "test_resources:delete[$QA_TEST_RESOURCES_FILE_PATTERN]"
allow_failure: true
when: always

View File

@ -0,0 +1,80 @@
# Specific specs passed
.specific-specs: &specific-specs
if: $QA_TESTS != ""
# No specific specs passed
.all-specs: &all-specs
if: $QA_TESTS == ""
# No specific specs in mr pipeline
.all-specs-mr: &all-specs-mr
if: $CI_MERGE_REQUEST_IID && $QA_TESTS == ""
when: manual
# Triggered by change pattern
.app-changes: &app-changes
if: $APP_CHANGE_TRIGGER == "true"
# QA framework changes present
.qa-framework-changes: &qa-framework-changes
if: $QA_FRAMEWORK_CHANGES == "true"
.never-when-qa-framework-changes-or-no-specific-specs:
- <<: *qa-framework-changes
when: never
- <<: *all-specs
when: never
.never-when-specific-specs-always-when-qa-framework-changes:
- <<: *specific-specs
when: never
- *qa-framework-changes
# ------------------------------------------
# Test
# ------------------------------------------
.rules:qa-smoke:
rules:
# always trigger smoke suite if review pipeline got triggered by specific changes in application code
- <<: *app-changes
variables:
QA_TESTS: "" # unset QA_TESTS even if specific tests were inferred from stage label
- *qa-framework-changes
- if: $QA_SUITES =~ /Test::Instance::Smoke/
.rules:qa-blocking:
rules:
- <<: *app-changes
when: never
- !reference [.never-when-qa-framework-changes-or-no-specific-specs]
- if: $QA_SUITES =~ /Test::Instance::ReviewBlocking/
.rules:qa-blocking-parallel:
rules:
# always trigger blocking suite if review pipeline got triggered by specific changes in application code
- <<: *app-changes
variables:
QA_TESTS: "" # unset QA_TESTS even if specific tests were inferred from stage label
- !reference [.never-when-specific-specs-always-when-qa-framework-changes]
- if: $QA_SUITES =~ /Test::Instance::ReviewBlocking/
.rules:qa-non-blocking:
rules:
- !reference [.never-when-qa-framework-changes-or-no-specific-specs]
- if: $QA_SUITES =~ /Test::Instance::ReviewNonBlocking/
.rules:qa-non-blocking-parallel:
rules:
- !reference [.never-when-specific-specs-always-when-qa-framework-changes]
- *all-specs-mr # set full suite to manual when no specific specs passed in mr
- if: $QA_SUITES =~ /Test::Instance::ReviewNonBlocking/
# ------------------------------------------
# Prepare/Report
# ------------------------------------------
# if no framework changes or QA_SUITES do not contain review scenarios, pipeline will not have e2e test jobs
# so we need to skip knapsack, allure and test resource deletion jobs as well
.rules:qa-framework-changes-or-review-scenarios:
rules:
- *qa-framework-changes
- if: $QA_SUITES =~ /Test::Instance::Smoke/
- if: $QA_SUITES =~ /Test::Instance::ReviewBlocking/
- if: $QA_SUITES =~ /Test::Instance::ReviewNonBlocking/

View File

@ -1667,6 +1667,9 @@
################
# Review rules #
################
.review-change-pattern: &review-change-pattern
APP_CHANGE_TRIGGER: "true"
.review:rules:start-review-app-pipeline:
rules:
- <<: *if-not-ee
@ -1678,12 +1681,16 @@
changes: *ci-review-patterns
- <<: *if-dot-com-gitlab-org-merge-request
changes: *frontend-build-patterns
variables: *review-change-pattern
- <<: *if-dot-com-gitlab-org-merge-request
changes: *controllers-patterns
variables: *review-change-pattern
- <<: *if-dot-com-gitlab-org-merge-request
changes: *models-patterns
variables: *review-change-pattern
- <<: *if-dot-com-gitlab-org-merge-request
changes: *lib-gitlab-patterns
variables: *review-change-pattern
- <<: *if-dot-com-gitlab-org-merge-request
changes: *qa-patterns
- <<: *if-dot-com-gitlab-org-merge-request
@ -1717,49 +1724,6 @@
rules:
- when: on_success
.review:rules:review-qa-smoke:
rules:
- when: on_success
# If the needed job isn't allowed to fail, we need to use `when: always` in
# order to keep the job always running after it.
#
# If the needed job is allowed to fail, we need to use both
# `when: on_success` and `when: on_failure` in order to keep
# the job always running after it.
# Not that if the needed job has `when: on_success` we can use `when: always`
# for the depending job.
#
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76756
.review:rules:review-qa-reliable:
rules:
- when: on_success
# Since `review-qa-reliable` isn't allowed to fail, we need to use `when: always`for `review-qa-reliable-report`.
.review:rules:review-qa-blocking-report:
rules:
- when: always
.review:rules:review-qa-all:
rules:
- <<: *if-dot-com-gitlab-org-merge-request
changes: *code-patterns
when: manual
allow_failure: true # manual jobs needs to be allowed to fail, otherwise they block the pipeline
- when: on_success
allow_failure: true
# Since `review-qa-all` is allowed to fail (and potentially manual), we need to use `when: on_success` and `when: on_failure` for `review-qa-all-report`.
.review:rules:review-qa-all-report:
rules:
- when: on_success
- when: on_failure
.review:rules:review-qa-cleanup:
rules:
- when: always
.review:rules:review-cleanup:
rules:
- <<: *if-not-ee

View File

@ -46,6 +46,7 @@ const populateUserInfo = (user) => {
pronouns: userData.pronouns,
localTime: userData.local_time,
isFollowed: userData.is_followed,
state: userData.state,
loaded: true,
});
}

View File

@ -1 +1,14 @@
import { __ } from '~/locale';
export const USER_POPOVER_DELAY = 200;
export const I18N_ERROR_FOLLOW = __(
'An error occurred while trying to follow this user, please try again.',
);
export const I18N_ERROR_UNFOLLOW = __(
'An error occurred while trying to unfollow this user, please try again.',
);
export const I18N_USER_BLOCKED = __('User is blocked');
export const I18N_USER_BUSY = __('Busy');
export const I18N_USER_LEARN = __('Learn more about %{name}');
export const I18N_USER_FOLLOW = __('Follow');
export const I18N_USER_UNFOLLOW = __('Unfollow');

View File

@ -9,23 +9,31 @@ import {
GlButton,
GlAvatarLabeled,
} from '@gitlab/ui';
import { __ } from '~/locale';
import { glEmojiTag } from '~/emoji';
import createFlash from '~/flash';
import { followUser, unfollowUser } from '~/rest_api';
import { isUserBusy } from '~/set_status_modal/utils';
import Tracking from '~/tracking';
import { USER_POPOVER_DELAY } from './constants';
import {
I18N_ERROR_FOLLOW,
I18N_ERROR_UNFOLLOW,
I18N_USER_BLOCKED,
I18N_USER_BUSY,
I18N_USER_LEARN,
I18N_USER_FOLLOW,
I18N_USER_UNFOLLOW,
USER_POPOVER_DELAY,
} from './constants';
const MAX_SKELETON_LINES = 4;
export default {
name: 'UserPopover',
maxSkeletonLines: MAX_SKELETON_LINES,
I18N_USER_BLOCKED,
I18N_USER_BUSY,
I18N_USER_LEARN,
USER_POPOVER_DELAY,
i18n: {
busy: __('Busy'),
},
components: {
GlIcon,
GlLink,
@ -94,7 +102,7 @@ export default {
toggleFollowButtonText() {
if (this.toggleFollowLoading) return null;
return this.user?.isFollowed ? __('Unfollow') : __('Follow');
return this.user?.isFollowed ? I18N_USER_UNFOLLOW : I18N_USER_FOLLOW;
},
toggleFollowButtonVariant() {
return this.user?.isFollowed ? 'default' : 'confirm';
@ -102,6 +110,9 @@ export default {
hasPronouns() {
return Boolean(this.user?.pronouns?.trim());
},
isBlocked() {
return this.user?.state === 'blocked';
},
isBusy() {
return isUserBusy(this.availabilityStatus);
},
@ -129,7 +140,7 @@ export default {
this.$emit('follow');
} catch (error) {
createFlash({
message: __('An error occurred while trying to follow this user, please try again.'),
message: I18N_ERROR_FOLLOW,
error,
captureError: true,
});
@ -149,7 +160,7 @@ export default {
this.$emit('unfollow');
} catch (error) {
createFlash({
message: __('An error occurred while trying to unfollow this user, please try again.'),
message: I18N_ERROR_UNFOLLOW,
error,
captureError: true,
});
@ -189,16 +200,21 @@ export default {
:label="user.name"
:sub-label="username"
>
<gl-button
v-if="shouldRenderToggleFollowButton"
class="gl-mt-3 gl-align-self-start"
:variant="toggleFollowButtonVariant"
:loading="toggleFollowLoading"
size="small"
data-testid="toggle-follow-button"
@click="toggleFollow"
>{{ toggleFollowButtonText }}</gl-button
>
<template v-if="isBlocked">
<span class="gl-mt-4 gl-font-style-italic">{{ $options.I18N_USER_BLOCKED }}</span>
</template>
<template v-else>
<gl-button
v-if="shouldRenderToggleFollowButton"
class="gl-mt-3 gl-align-self-start"
:variant="toggleFollowButtonVariant"
:loading="toggleFollowLoading"
size="small"
data-testid="toggle-follow-button"
@click="toggleFollow"
>{{ toggleFollowButtonText }}</gl-button
>
</template>
<template #meta>
<span
@ -208,7 +224,7 @@ export default {
>({{ user.pronouns }})</span
>
<span v-if="isBusy" class="gl-text-gray-500 gl-font-sm gl-font-weight-normal gl-p-1"
>({{ $options.i18n.busy }})</span
>({{ $options.I18N_USER_BUSY }})</span
>
</template>
</gl-avatar-labeled>
@ -223,39 +239,41 @@ export default {
/>
</template>
<template v-else>
<div class="gl-text-gray-500">
<div v-if="user.bio" class="gl-display-flex gl-mb-2">
<gl-icon name="profile" class="gl-flex-shrink-0" />
<span ref="bio" class="gl-ml-2">{{ user.bio }}</span>
<template v-if="!isBlocked">
<div class="gl-text-gray-500">
<div v-if="user.bio" class="gl-display-flex gl-mb-2">
<gl-icon name="profile" class="gl-flex-shrink-0" />
<span ref="bio" class="gl-ml-2">{{ user.bio }}</span>
</div>
<div v-if="user.workInformation" class="gl-display-flex gl-mb-2">
<gl-icon name="work" class="gl-flex-shrink-0" />
<span ref="workInformation" class="gl-ml-2">{{ user.workInformation }}</span>
</div>
<div v-if="user.location" class="gl-display-flex gl-mb-2">
<gl-icon name="location" class="gl-flex-shrink-0" />
<span class="gl-ml-2">{{ user.location }}</span>
</div>
<div
v-if="user.localTime && !user.bot"
class="gl-display-flex gl-mb-2"
data-testid="user-popover-local-time"
>
<gl-icon name="clock" class="gl-flex-shrink-0" />
<span class="gl-ml-2">{{ user.localTime }}</span>
</div>
</div>
<div v-if="user.workInformation" class="gl-display-flex gl-mb-2">
<gl-icon name="work" class="gl-flex-shrink-0" />
<span ref="workInformation" class="gl-ml-2">{{ user.workInformation }}</span>
<div v-if="statusHtml" class="gl-mb-2" data-testid="user-popover-status">
<span v-safe-html:[$options.safeHtmlConfig]="statusHtml"></span>
</div>
<div v-if="user.location" class="gl-display-flex gl-mb-2">
<gl-icon name="location" class="gl-flex-shrink-0" />
<span class="gl-ml-2">{{ user.location }}</span>
<div v-if="user.bot && user.websiteUrl" class="gl-text-blue-500">
<gl-icon name="question" />
<gl-link data-testid="user-popover-bot-docs-link" :href="user.websiteUrl">
<gl-sprintf :message="$options.I18N_USER_LEARN">
<template #name>{{ user.name }}</template>
</gl-sprintf>
</gl-link>
</div>
<div
v-if="user.localTime && !user.bot"
class="gl-display-flex gl-mb-2"
data-testid="user-popover-local-time"
>
<gl-icon name="clock" class="gl-flex-shrink-0" />
<span class="gl-ml-2">{{ user.localTime }}</span>
</div>
</div>
<div v-if="statusHtml" class="gl-mb-2" data-testid="user-popover-status">
<span v-safe-html:[$options.safeHtmlConfig]="statusHtml"></span>
</div>
<div v-if="user.bot && user.websiteUrl" class="gl-text-blue-500">
<gl-icon name="question" />
<gl-link data-testid="user-popover-bot-docs-link" :href="user.websiteUrl">
<gl-sprintf :message="__('Learn more about %{username}')">
<template #username>{{ user.name }}</template>
</gl-sprintf>
</gl-link>
</div>
</template>
</template>
</div>
</gl-popover>

View File

@ -2,29 +2,30 @@
= stylesheet_link_tag 'mailers/highlighted_diff_email'
%h3
#{@message.author_name} #{@message.action_name} #{@message.ref_type} #{@message.ref_name}
at #{link_to(@message.project_name_with_namespace, project_url(@message.project))}
= s_('Notify|%{author_name} %{action_name} %{ref_type} %{ref_name} at %{project_link}').html_safe % {author_name: @message.author_name, action_name: @message.action_name, ref_type: @message.ref_type, ref_name: @message.ref_name, project_link: link_to(@message.project_name_with_namespace, strip_tags(project_url(@message.project)))}
- if @message.compare
- if @message.reverse_compare?
%p
%strong WARNING:
The push did not contain any new commits, but force pushed to delete the commits and changes below.
%strong
= _('WARNING:')
= s_('Notify|The push did not contain any new commits, but force pushed to delete the commits and changes below.')
%h4
= @message.reverse_compare? ? "Deleted commits:" : "Commits:"
= @message.reverse_compare? ? _("Deleted commits:") : _("Commits:")
%ul
- @message.commits.each do |commit|
%li
%strong= link_to(commit.short_id, project_commit_url(@message.project, commit))
%div
%span by #{commit.author_name}
%i at #{commit.committed_date.to_s(:iso8601)}
= html_escape(s_('Notify|%{committed_by_start} by %{author_name} %{committed_by_end} %{committed_at_start} at %{committed_date} %{committed_at_end}')) % {committed_by_start: '<span>'.html_safe, author_name: commit.author_name, committed_by_end: '</span>'.html_safe, committed_at_start: '<i>'.html_safe, committed_date: commit.committed_date.to_s(:iso8601), committed_at_end: '</i>'.html_safe}
%pre.commit-message
= commit.safe_message
%h4 #{pluralize @message.diffs_count, "changed file"}:
%h4
- changed_files = n_('%d changed file', '%d changed files', @message.diffs_count) % @message.diffs_count
= s_('Notify|%{changed_files}:') % {changed_files: changed_files}
%ul
- @message.diffs.each do |diff_file|
@ -47,9 +48,11 @@
- unless @message.disable_diffs?
- if @message.compare_timeout
%h5 The diff was not included because it is too large.
%h5
= s_('Notify|The diff was not included because it is too large.')
- else
%h4 Changes:
%h4
= _('Changes:')
- @message.diffs.each do |diff_file|
- file_hash = hexdigest(diff_file.file_path)
%li{ id: file_hash }
@ -57,7 +60,7 @@
- if diff_file.deleted_file?
%strong<
= diff_file.old_path
deleted
= s_('deleted')
- elsif diff_file.renamed_file?
%strong<
= diff_file.old_path
@ -68,7 +71,7 @@
%strong<
= diff_file.new_path
- if diff_file.too_large?
The diff for this file was not included because it is too large.
= s_('Notify|The diff for this file was not included because it is too large.')
- else
%hr
- blob = diff_file.blob
@ -76,5 +79,5 @@
%table.code.white
= render partial: "projects/diffs/email_line", collection: diff_file.highlighted_diff_lines, as: :line, locals: { diff_file: diff_file }
- else
No preview for this file type
= s_('Notify|No preview for this file type')
%br

View File

@ -79,11 +79,11 @@ module Gitlab
@action_name ||=
case @action
when :create
'pushed new'
s_('Notify|pushed new')
when :delete
'deleted'
s_('Notify|deleted')
else
'pushed to'
s_('Notify|pushed to')
end
end

View File

@ -7723,6 +7723,9 @@ msgstr ""
msgid "Changes to the title have not been saved"
msgstr ""
msgid "Changes:"
msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
@ -9620,6 +9623,9 @@ msgstr ""
msgid "Commits you select appear here. Go to the first tab and select commits to add to this merge request."
msgstr ""
msgid "Commits:"
msgstr ""
msgid "Commits|An error occurred while fetching merge requests data."
msgstr ""
@ -12717,6 +12723,9 @@ msgstr ""
msgid "Deleted chat nickname: %{chat_name}!"
msgstr ""
msgid "Deleted commits:"
msgstr ""
msgid "Deleted projects cannot be restored!"
msgstr ""
@ -23423,7 +23432,7 @@ msgstr ""
msgid "Learn more"
msgstr ""
msgid "Learn more about %{username}"
msgid "Learn more about %{name}"
msgstr ""
msgid "Learn more about Auto DevOps"
@ -27039,12 +27048,21 @@ msgstr ""
msgid "Notify|%{author_link}'s issue %{issue_reference_link} is due soon."
msgstr ""
msgid "Notify|%{author_name} %{action_name} %{ref_type} %{ref_name} at %{project_link}"
msgstr ""
msgid "Notify|%{changed_files}:"
msgstr ""
msgid "Notify|%{commit_link} in %{mr_link}"
msgstr ""
msgid "Notify|%{commits_text} from branch `%{target_branch}`"
msgstr ""
msgid "Notify|%{committed_by_start} by %{author_name} %{committed_by_end} %{committed_at_start} at %{committed_date} %{committed_at_end}"
msgstr ""
msgid "Notify|%{invite_email}, now known as %{user_name}, has accepted your invitation to join the %{target_name} %{target_model_name}."
msgstr ""
@ -27171,6 +27189,9 @@ msgstr ""
msgid "Notify|New issue: %{project_issue_url}"
msgstr ""
msgid "Notify|No preview for this file type"
msgstr ""
msgid "Notify|Pipeline %{pipeline_link} triggered by"
msgstr ""
@ -27180,6 +27201,15 @@ msgstr ""
msgid "Notify|The Auto DevOps pipeline failed for pipeline %{pipeline_link} and has been disabled for %{project_link}. In order to use the Auto DevOps pipeline with your project, please review the %{supported_langs_link}, adjust your project accordingly, and turn on the Auto DevOps pipeline within your %{settings_link}."
msgstr ""
msgid "Notify|The diff for this file was not included because it is too large."
msgstr ""
msgid "Notify|The diff was not included because it is too large."
msgstr ""
msgid "Notify|The push did not contain any new commits, but force pushed to delete the commits and changes below."
msgstr ""
msgid "Notify|This issue is due on: %{issue_due_date}"
msgstr ""
@ -27204,6 +27234,15 @@ msgstr ""
msgid "Notify|currently supported languages"
msgstr ""
msgid "Notify|deleted"
msgstr ""
msgid "Notify|pushed new"
msgstr ""
msgid "Notify|pushed to"
msgstr ""
msgid "Notify|successfully completed %{jobs} in %{stages}."
msgstr ""
@ -43051,6 +43090,9 @@ msgstr ""
msgid "User identity was successfully updated."
msgstr ""
msgid "User is blocked"
msgstr ""
msgid "User is not allowed to resolve thread"
msgstr ""
@ -44194,6 +44236,9 @@ msgstr ""
msgid "Vulnerability|View training"
msgstr ""
msgid "WARNING:"
msgstr ""
msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
msgstr ""

View File

@ -1,16 +0,0 @@
# frozen_string_literal: true
module QA
module Scenario
module Test
module Instance
class Blocking < Template
include Bootable
include SharedAttributes
tags :reliable, :smoke
end
end
end
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
module QA
module Scenario
module Test
module Instance
class ReviewBlocking < All
tags :reliable,
:sanity_feature_flags,
:"~orchestrated",
:"~skip_signup_disabled"
end
end
end
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
module QA
module Scenario
module Test
module Instance
class ReviewNonBlocking < All
tags :"~reliable",
:"~smoke",
:"~skip_signup_disabled",
*Specs::Runner::DEFAULT_SKIPPED_TAGS.map { |tag| :"~#{tag}" }
end
end
end
end
end

View File

@ -64,7 +64,7 @@ module QA
it(
'comments on an issue with an attachment',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347946',
except: { job: 'review-qa-smoke' }
except: { job: 'review-qa-*' }
) do
Page::Project::Issue::Show.perform do |show|
show.comment('See attached image for scale', attachment: file_to_attach)

View File

@ -15,7 +15,8 @@ module QA
{ klass: "Test::Instance::All" },
{ klass: "Test::Instance::Smoke" },
{ klass: "Test::Instance::Reliable" },
{ klass: "Test::Instance::Blocking" },
{ klass: "Test::Instance::ReviewBlocking" },
{ klass: "Test::Instance::ReviewNonBlocking" },
{ klass: "Test::Instance::CloudActivation" },
{ klass: "Test::Instance::Integrations" },
{ klass: "Test::Instance::Jira" },

View File

@ -21,6 +21,7 @@ fi
variables=$(cat <<YML
variables:
GITLAB_VERSION: "$(cat VERSION)"
COLORIZED_LOGS: "true"
QA_TESTS: "$QA_TESTS"
QA_FEATURE_FLAGS: "${QA_FEATURE_FLAGS}"
QA_FRAMEWORK_CHANGES: "${QA_FRAMEWORK_CHANGES:-false}"
@ -29,13 +30,10 @@ YML
)
echo "Using .gitlab/ci/review-apps/main.gitlab-ci.yml and .gitlab/ci/package-and-test/main.gitlab-ci.yml"
cp .gitlab/ci/review-apps/main.gitlab-ci.yml "$REVIEW_PIPELINE_YML"
echo "$variables" >>"$REVIEW_PIPELINE_YML"
echo "Successfully generated review-app pipeline with following variables section:"
echo "$variables"
cp .gitlab/ci/package-and-test/main.gitlab-ci.yml "$OMNIBUS_PIPELINE_YML"
echo "$variables" >>"$OMNIBUS_PIPELINE_YML"
echo "Successfully generated package-and-test pipeline with following variables section:"
echo "Successfully generated review-app and package-and-test pipeline with following variables section:"
echo "$variables"

View File

@ -32,13 +32,6 @@ end
ActiveSupport::XmlMini.backend = 'Nokogiri'
RSpec.configure do |config|
unless ENV['CI']
# Allow running `:focus` examples locally,
# falling back to all tests when there is no `:focus` example.
config.filter_run focus: true
config.run_all_when_everything_filtered = true
end
# Makes diffs show entire non-truncated values.
config.before(:each, unlimited_max_formatted_output_length: true) do |_example|
config.expect_with :rspec do |c|

View File

@ -1,8 +1,15 @@
import { GlSkeletonLoader, GlIcon } from '@gitlab/ui';
import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import { sprintf } from '~/locale';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { AVAILABILITY_STATUS } from '~/set_status_modal/constants';
import UserPopover from '~/vue_shared/components/user_popover/user_popover.vue';
import {
I18N_USER_BLOCKED,
I18N_USER_LEARN,
I18N_USER_FOLLOW,
I18N_USER_UNFOLLOW,
} from '~/vue_shared/components/user_popover/constants';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
import { followUser, unfollowUser } from '~/api/user_api';
@ -310,7 +317,9 @@ describe('User Popover Component', () => {
const securityBotDocsLink = findSecurityBotDocsLink();
expect(securityBotDocsLink.exists()).toBe(true);
expect(securityBotDocsLink.attributes('href')).toBe(SECURITY_BOT_USER.websiteUrl);
expect(securityBotDocsLink.text()).toBe('Learn more about GitLab Security Bot');
expect(securityBotDocsLink.text()).toBe(
sprintf(I18N_USER_LEARN, { name: SECURITY_BOT_USER.name }),
);
});
it("does not show a link to the bot's documentation if there is no website_url", () => {
@ -320,9 +329,10 @@ describe('User Popover Component', () => {
});
it("doesn't escape user's name", () => {
createWrapper({ user: { ...SECURITY_BOT_USER, name: '%<>\';"' } });
const name = '%<>\';"';
createWrapper({ user: { ...SECURITY_BOT_USER, name } });
const securityBotDocsLink = findSecurityBotDocsLink();
expect(securityBotDocsLink.text()).toBe('Learn more about %<>\';"');
expect(securityBotDocsLink.text()).toBe(sprintf(I18N_USER_LEARN, { name }, false));
});
it('does not display local time', () => {
@ -336,7 +346,7 @@ describe('User Popover Component', () => {
beforeEach(() => createWrapper());
it('renders the Follow button with the correct variant', () => {
expect(findToggleFollowButton().text()).toBe('Follow');
expect(findToggleFollowButton().text()).toBe(I18N_USER_FOLLOW);
expect(findToggleFollowButton().props('variant')).toBe('confirm');
});
@ -387,7 +397,7 @@ describe('User Popover Component', () => {
beforeEach(() => createWrapper({ user: { ...DEFAULT_PROPS.user, isFollowed: true } }));
it('renders the Unfollow button with the correct variant', () => {
expect(findToggleFollowButton().text()).toBe('Unfollow');
expect(findToggleFollowButton().text()).toBe(I18N_USER_UNFOLLOW);
expect(findToggleFollowButton().props('variant')).toBe('default');
});
@ -441,6 +451,25 @@ describe('User Popover Component', () => {
});
});
describe('when the user is blocked', () => {
const bio = 'My super interesting bio';
const status = 'My status';
beforeEach(() =>
createWrapper({
user: { ...DEFAULT_PROPS.user, state: 'blocked', bio, status: { message_html: status } },
}),
);
it('renders warning', () => {
expect(wrapper.text()).toContain(I18N_USER_BLOCKED);
});
it("doesn't show other information", () => {
expect(wrapper.text()).not.toContain(bio);
expect(wrapper.text()).not.toContain(status);
});
});
describe('when API does not support `isFollowed`', () => {
beforeEach(() => {
const user = {

View File

@ -36,6 +36,7 @@ require 'rspec-parameterized'
require 'shoulda/matchers'
require 'test_prof/recipes/rspec/let_it_be'
require 'test_prof/factory_default'
require 'test_prof/factory_prof/nate_heckler'
require 'parslet/rig/rspec'
rspec_profiling_is_configured =
@ -109,11 +110,6 @@ RSpec.configure do |config|
warn `curl -s -o log/goroutines.log http://localhost:9236/debug/pprof/goroutine?debug=2`
end
end
else
# Allow running `:focus` examples locally,
# falling back to all tests when there is no `:focus` example.
config.filter_run focus: true
config.run_all_when_everything_filtered = true
end
# Attempt to troubleshoot https://gitlab.com/gitlab-org/gitlab/-/issues/351531

View File

@ -14,6 +14,13 @@ RSpec.configure do |config|
# Re-run failures locally with `--only-failures`
config.example_status_persistence_file_path = ENV.fetch('RSPEC_LAST_RUN_RESULTS_FILE', './spec/examples.txt')
unless ENV['CI']
# Allow running `:focus` examples locally,
# falling back to all tests when there is no `:focus` example.
config.filter_run focus: true
config.run_all_when_everything_filtered = true
end
config.mock_with :rspec do |mocks|
mocks.verify_doubled_constant_names = true
end