Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
6eb95ccbe8
commit
9a0e0265e4
|
@ -4,7 +4,6 @@ variables:
|
||||||
RELEASE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/build/omnibus-gitlab-mirror/gitlab-ee:${CI_COMMIT_SHA}"
|
RELEASE: "${REGISTRY_HOST}/${REGISTRY_GROUP}/build/omnibus-gitlab-mirror/gitlab-ee:${CI_COMMIT_SHA}"
|
||||||
SKIP_REPORT_IN_ISSUES: "true"
|
SKIP_REPORT_IN_ISSUES: "true"
|
||||||
OMNIBUS_GITLAB_CACHE_UPDATE: "false"
|
OMNIBUS_GITLAB_CACHE_UPDATE: "false"
|
||||||
COLORIZED_LOGS: "true"
|
|
||||||
QA_LOG_LEVEL: "info"
|
QA_LOG_LEVEL: "info"
|
||||||
QA_TESTS: ""
|
QA_TESTS: ""
|
||||||
QA_FEATURE_FLAGS: ""
|
QA_FEATURE_FLAGS: ""
|
||||||
|
|
|
@ -11,6 +11,7 @@ stages:
|
||||||
include:
|
include:
|
||||||
- local: .gitlab/ci/global.gitlab-ci.yml
|
- local: .gitlab/ci/global.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/rules.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/qa.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/review-apps/dast.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 GITALY_VERSION=$(<GITALY_SERVER_VERSION)
|
||||||
- export GITLAB_WORKHORSE_VERSION=$(<GITLAB_WORKHORSE_VERSION)
|
- export GITLAB_WORKHORSE_VERSION=$(<GITLAB_WORKHORSE_VERSION)
|
||||||
- echo "${CI_ENVIRONMENT_URL}" > environment_url.txt
|
- echo "${CI_ENVIRONMENT_URL}" > environment_url.txt
|
||||||
|
- echo "QA_GITLAB_URL=${CI_ENVIRONMENT_URL}" > environment.env
|
||||||
- *base-before_script
|
- *base-before_script
|
||||||
script:
|
script:
|
||||||
- check_kube_domain
|
- check_kube_domain
|
||||||
|
@ -112,6 +114,8 @@ review-deploy:
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- environment_url.txt
|
- environment_url.txt
|
||||||
|
reports:
|
||||||
|
dotenv: environment.env
|
||||||
expire_in: 7 days
|
expire_in: 7 days
|
||||||
when: always
|
when: always
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
include:
|
include:
|
||||||
- project: gitlab-org/quality/pipeline-common
|
- project: gitlab-org/quality/pipeline-common
|
||||||
ref: 0.13.0
|
ref: 1.2.2
|
||||||
file:
|
file:
|
||||||
- /ci/allure-report.yml
|
- /ci/allure-report.yml
|
||||||
- /ci/knapsack-report.yml
|
- /ci/knapsack-report.yml
|
||||||
|
@ -8,7 +8,7 @@ include:
|
||||||
.test-variables:
|
.test-variables:
|
||||||
variables:
|
variables:
|
||||||
QA_GENERATE_ALLURE_REPORT: "true"
|
QA_GENERATE_ALLURE_REPORT: "true"
|
||||||
COLORIZED_LOGS: "true"
|
QA_CAN_TEST_PRAEFECT: "false"
|
||||||
GITLAB_USERNAME: "root"
|
GITLAB_USERNAME: "root"
|
||||||
GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
|
GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
|
||||||
GITLAB_ADMIN_USERNAME: "root"
|
GITLAB_ADMIN_USERNAME: "root"
|
||||||
|
@ -21,49 +21,31 @@ include:
|
||||||
- .qa-cache
|
- .qa-cache
|
||||||
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.3
|
image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.3
|
||||||
before_script:
|
before_script:
|
||||||
- export QA_GITLAB_URL="$(cat environment_url.txt)"
|
|
||||||
- cd qa && bundle install
|
- cd qa && bundle install
|
||||||
|
|
||||||
.review-qa-base:
|
.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:
|
extends:
|
||||||
- .use-docker-in-docker
|
- .use-docker-in-docker
|
||||||
- .bundle-base
|
- .bundle-base
|
||||||
- .test-variables
|
- .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
|
stage: qa
|
||||||
needs:
|
needs:
|
||||||
- review-deploy
|
- review-deploy
|
||||||
- download-knapsack-report
|
- download-knapsack-report
|
||||||
variables:
|
variables:
|
||||||
DOCKER_HOST: tcp://docker:2376
|
|
||||||
DOCKER_TLS_CERTDIR: /certs
|
|
||||||
DOCKER_CERT_PATH: /certs/client
|
|
||||||
DOCKER_TLS_VERIFY: 1
|
|
||||||
GIT_LFS_SKIP_SMUDGE: 1
|
GIT_LFS_SKIP_SMUDGE: 1
|
||||||
WD_INSTALL_DIR: /usr/local/bin
|
WD_INSTALL_DIR: /usr/local/bin
|
||||||
before_script:
|
RSPEC_REPORT_OPTS: --force-color --order random --format documentation --format RspecJunitFormatter --out tmp/rspec.xml
|
||||||
- !reference [.bundle-base, before_script]
|
|
||||||
script:
|
script:
|
||||||
- export EE_LICENSE="$(cat $REVIEW_APPS_EE_LICENSE_FILE)"
|
- 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[\
|
echo "Sentry errors for the current review-app test run can be found via following url:"
|
||||||
${RSPEC_TAGS} \
|
echo "https://sentry.gitlab.net/gitlab/gitlab-review-apps/releases/$(echo "${CI_COMMIT_SHA}" | cut -c1-11)/all-events/."
|
||||||
--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}
|
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- qa/tmp
|
- qa/tmp
|
||||||
|
@ -72,20 +54,11 @@ include:
|
||||||
expire_in: 7 days
|
expire_in: 7 days
|
||||||
when: always
|
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
|
# Store knapsack report as artifact so the same report is reused across all jobs
|
||||||
download-knapsack-report:
|
download-knapsack-report:
|
||||||
extends:
|
extends:
|
||||||
- .bundle-base
|
- .bundle-base
|
||||||
- .review:rules:review-qa-reliable
|
- .rules:qa-framework-changes-or-review-scenarios
|
||||||
stage: prepare
|
stage: prepare
|
||||||
script:
|
script:
|
||||||
- bundle exec rake "knapsack:download[qa]"
|
- bundle exec rake "knapsack:download[qa]"
|
||||||
|
@ -98,30 +71,39 @@ download-knapsack-report:
|
||||||
review-qa-smoke:
|
review-qa-smoke:
|
||||||
extends:
|
extends:
|
||||||
- .review-qa-base
|
- .review-qa-base
|
||||||
- .review:rules:review-qa-smoke
|
- .rules:qa-smoke
|
||||||
retry: 1
|
|
||||||
variables:
|
variables:
|
||||||
|
QA_SCENARIO: Test::Instance::Smoke
|
||||||
QA_RUN_TYPE: review-qa-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
|
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:
|
extends:
|
||||||
- .review-qa-base
|
- .review-qa-base
|
||||||
- .review:rules:review-qa-all
|
- .rules:qa-blocking
|
||||||
parallel: 5
|
|
||||||
variables:
|
variables:
|
||||||
QA_RUN_TYPE: review-qa-all
|
QA_SCENARIO: Test::Instance::ReviewBlocking
|
||||||
RSPEC_TAGS: --tag ~reliable --tag ~smoke --tag ~sanity_feature_flags
|
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:
|
review-performance:
|
||||||
extends:
|
extends:
|
||||||
|
@ -149,27 +131,20 @@ review-performance:
|
||||||
performance: performance.json
|
performance: performance.json
|
||||||
expire_in: 31d
|
expire_in: 31d
|
||||||
|
|
||||||
# Generate single report for both smoke and reliable test jobs
|
e2e-test-report:
|
||||||
# Both job types are essentially the same:
|
|
||||||
# * always executed
|
|
||||||
# * always blocking
|
|
||||||
allure-report-qa-blocking:
|
|
||||||
extends:
|
extends:
|
||||||
- .allure-report-base
|
- .generate-allure-report-base
|
||||||
- .review:rules:review-qa-blocking-report
|
- .rules:qa-framework-changes-or-review-scenarios
|
||||||
needs:
|
stage: post-qa
|
||||||
- review-qa-smoke
|
|
||||||
- review-qa-reliable
|
|
||||||
variables:
|
variables:
|
||||||
ALLURE_JOB_NAME: e2e-review-qa-blocking
|
ALLURE_JOB_NAME: e2e-review-qa
|
||||||
|
ALLURE_PROJECT_PATH: $CI_PROJECT_PATH
|
||||||
allure-report-qa-all:
|
ALLURE_RESULTS_GLOB: qa/tmp/allure-results/*
|
||||||
extends:
|
ALLURE_MERGE_REQUEST_IID: $CI_MERGE_REQUEST_IID
|
||||||
- .allure-report-base
|
GITLAB_AUTH_TOKEN: $GITLAB_QA_MR_ALLURE_REPORT_TOKEN
|
||||||
- .review:rules:review-qa-all-report
|
GIT_STRATEGY: none
|
||||||
needs: ["review-qa-all"]
|
allow_failure: true
|
||||||
variables:
|
when: always
|
||||||
ALLURE_JOB_NAME: e2e-review-qa-all
|
|
||||||
|
|
||||||
upload-knapsack-report:
|
upload-knapsack-report:
|
||||||
extends:
|
extends:
|
||||||
|
@ -182,13 +157,13 @@ upload-knapsack-report:
|
||||||
delete-test-resources:
|
delete-test-resources:
|
||||||
extends:
|
extends:
|
||||||
- .bundle-base
|
- .bundle-base
|
||||||
- .review:rules:review-qa-cleanup
|
- .rules:qa-framework-changes-or-review-scenarios
|
||||||
stage: post-qa
|
stage: post-qa
|
||||||
variables:
|
variables:
|
||||||
QA_TEST_RESOURCES_FILE_PATTERN: $CI_PROJECT_DIR/qa/tmp/test-resources-*.json
|
QA_TEST_RESOURCES_FILE_PATTERN: $CI_PROJECT_DIR/qa/tmp/test-resources-*.json
|
||||||
GITLAB_QA_ACCESS_TOKEN: $REVIEW_APPS_ROOT_TOKEN
|
GITLAB_QA_ACCESS_TOKEN: $REVIEW_APPS_ROOT_TOKEN
|
||||||
COLORIZED_LOGS: "true"
|
|
||||||
script:
|
script:
|
||||||
- export GITLAB_ADDRESS="$QA_GITLAB_URL"
|
- export GITLAB_ADDRESS="$QA_GITLAB_URL"
|
||||||
- bundle exec rake "test_resources:delete[$QA_TEST_RESOURCES_FILE_PATTERN]"
|
- bundle exec rake "test_resources:delete[$QA_TEST_RESOURCES_FILE_PATTERN]"
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
when: always
|
||||||
|
|
|
@ -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/
|
|
@ -1667,6 +1667,9 @@
|
||||||
################
|
################
|
||||||
# Review rules #
|
# Review rules #
|
||||||
################
|
################
|
||||||
|
.review-change-pattern: &review-change-pattern
|
||||||
|
APP_CHANGE_TRIGGER: "true"
|
||||||
|
|
||||||
.review:rules:start-review-app-pipeline:
|
.review:rules:start-review-app-pipeline:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
|
@ -1678,12 +1681,16 @@
|
||||||
changes: *ci-review-patterns
|
changes: *ci-review-patterns
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *frontend-build-patterns
|
changes: *frontend-build-patterns
|
||||||
|
variables: *review-change-pattern
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *controllers-patterns
|
changes: *controllers-patterns
|
||||||
|
variables: *review-change-pattern
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *models-patterns
|
changes: *models-patterns
|
||||||
|
variables: *review-change-pattern
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *lib-gitlab-patterns
|
changes: *lib-gitlab-patterns
|
||||||
|
variables: *review-change-pattern
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
changes: *qa-patterns
|
changes: *qa-patterns
|
||||||
- <<: *if-dot-com-gitlab-org-merge-request
|
- <<: *if-dot-com-gitlab-org-merge-request
|
||||||
|
@ -1717,49 +1724,6 @@
|
||||||
rules:
|
rules:
|
||||||
- when: on_success
|
- 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:
|
.review:rules:review-cleanup:
|
||||||
rules:
|
rules:
|
||||||
- <<: *if-not-ee
|
- <<: *if-not-ee
|
||||||
|
|
|
@ -46,6 +46,7 @@ const populateUserInfo = (user) => {
|
||||||
pronouns: userData.pronouns,
|
pronouns: userData.pronouns,
|
||||||
localTime: userData.local_time,
|
localTime: userData.local_time,
|
||||||
isFollowed: userData.is_followed,
|
isFollowed: userData.is_followed,
|
||||||
|
state: userData.state,
|
||||||
loaded: true,
|
loaded: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,14 @@
|
||||||
|
import { __ } from '~/locale';
|
||||||
|
|
||||||
export const USER_POPOVER_DELAY = 200;
|
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');
|
||||||
|
|
|
@ -9,23 +9,31 @@ import {
|
||||||
GlButton,
|
GlButton,
|
||||||
GlAvatarLabeled,
|
GlAvatarLabeled,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
import { __ } from '~/locale';
|
|
||||||
import { glEmojiTag } from '~/emoji';
|
import { glEmojiTag } from '~/emoji';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import { followUser, unfollowUser } from '~/rest_api';
|
import { followUser, unfollowUser } from '~/rest_api';
|
||||||
import { isUserBusy } from '~/set_status_modal/utils';
|
import { isUserBusy } from '~/set_status_modal/utils';
|
||||||
import Tracking from '~/tracking';
|
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;
|
const MAX_SKELETON_LINES = 4;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'UserPopover',
|
name: 'UserPopover',
|
||||||
maxSkeletonLines: MAX_SKELETON_LINES,
|
maxSkeletonLines: MAX_SKELETON_LINES,
|
||||||
|
I18N_USER_BLOCKED,
|
||||||
|
I18N_USER_BUSY,
|
||||||
|
I18N_USER_LEARN,
|
||||||
USER_POPOVER_DELAY,
|
USER_POPOVER_DELAY,
|
||||||
i18n: {
|
|
||||||
busy: __('Busy'),
|
|
||||||
},
|
|
||||||
components: {
|
components: {
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlLink,
|
GlLink,
|
||||||
|
@ -94,7 +102,7 @@ export default {
|
||||||
toggleFollowButtonText() {
|
toggleFollowButtonText() {
|
||||||
if (this.toggleFollowLoading) return null;
|
if (this.toggleFollowLoading) return null;
|
||||||
|
|
||||||
return this.user?.isFollowed ? __('Unfollow') : __('Follow');
|
return this.user?.isFollowed ? I18N_USER_UNFOLLOW : I18N_USER_FOLLOW;
|
||||||
},
|
},
|
||||||
toggleFollowButtonVariant() {
|
toggleFollowButtonVariant() {
|
||||||
return this.user?.isFollowed ? 'default' : 'confirm';
|
return this.user?.isFollowed ? 'default' : 'confirm';
|
||||||
|
@ -102,6 +110,9 @@ export default {
|
||||||
hasPronouns() {
|
hasPronouns() {
|
||||||
return Boolean(this.user?.pronouns?.trim());
|
return Boolean(this.user?.pronouns?.trim());
|
||||||
},
|
},
|
||||||
|
isBlocked() {
|
||||||
|
return this.user?.state === 'blocked';
|
||||||
|
},
|
||||||
isBusy() {
|
isBusy() {
|
||||||
return isUserBusy(this.availabilityStatus);
|
return isUserBusy(this.availabilityStatus);
|
||||||
},
|
},
|
||||||
|
@ -129,7 +140,7 @@ export default {
|
||||||
this.$emit('follow');
|
this.$emit('follow');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
createFlash({
|
createFlash({
|
||||||
message: __('An error occurred while trying to follow this user, please try again.'),
|
message: I18N_ERROR_FOLLOW,
|
||||||
error,
|
error,
|
||||||
captureError: true,
|
captureError: true,
|
||||||
});
|
});
|
||||||
|
@ -149,7 +160,7 @@ export default {
|
||||||
this.$emit('unfollow');
|
this.$emit('unfollow');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
createFlash({
|
createFlash({
|
||||||
message: __('An error occurred while trying to unfollow this user, please try again.'),
|
message: I18N_ERROR_UNFOLLOW,
|
||||||
error,
|
error,
|
||||||
captureError: true,
|
captureError: true,
|
||||||
});
|
});
|
||||||
|
@ -189,16 +200,21 @@ export default {
|
||||||
:label="user.name"
|
:label="user.name"
|
||||||
:sub-label="username"
|
:sub-label="username"
|
||||||
>
|
>
|
||||||
<gl-button
|
<template v-if="isBlocked">
|
||||||
v-if="shouldRenderToggleFollowButton"
|
<span class="gl-mt-4 gl-font-style-italic">{{ $options.I18N_USER_BLOCKED }}</span>
|
||||||
class="gl-mt-3 gl-align-self-start"
|
</template>
|
||||||
:variant="toggleFollowButtonVariant"
|
<template v-else>
|
||||||
:loading="toggleFollowLoading"
|
<gl-button
|
||||||
size="small"
|
v-if="shouldRenderToggleFollowButton"
|
||||||
data-testid="toggle-follow-button"
|
class="gl-mt-3 gl-align-self-start"
|
||||||
@click="toggleFollow"
|
:variant="toggleFollowButtonVariant"
|
||||||
>{{ toggleFollowButtonText }}</gl-button
|
:loading="toggleFollowLoading"
|
||||||
>
|
size="small"
|
||||||
|
data-testid="toggle-follow-button"
|
||||||
|
@click="toggleFollow"
|
||||||
|
>{{ toggleFollowButtonText }}</gl-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #meta>
|
<template #meta>
|
||||||
<span
|
<span
|
||||||
|
@ -208,7 +224,7 @@ export default {
|
||||||
>({{ user.pronouns }})</span
|
>({{ user.pronouns }})</span
|
||||||
>
|
>
|
||||||
<span v-if="isBusy" class="gl-text-gray-500 gl-font-sm gl-font-weight-normal gl-p-1"
|
<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>
|
</template>
|
||||||
</gl-avatar-labeled>
|
</gl-avatar-labeled>
|
||||||
|
@ -223,39 +239,41 @@ export default {
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="gl-text-gray-500">
|
<template v-if="!isBlocked">
|
||||||
<div v-if="user.bio" class="gl-display-flex gl-mb-2">
|
<div class="gl-text-gray-500">
|
||||||
<gl-icon name="profile" class="gl-flex-shrink-0" />
|
<div v-if="user.bio" class="gl-display-flex gl-mb-2">
|
||||||
<span ref="bio" class="gl-ml-2">{{ user.bio }}</span>
|
<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>
|
||||||
<div v-if="user.workInformation" class="gl-display-flex gl-mb-2">
|
<div v-if="statusHtml" class="gl-mb-2" data-testid="user-popover-status">
|
||||||
<gl-icon name="work" class="gl-flex-shrink-0" />
|
<span v-safe-html:[$options.safeHtmlConfig]="statusHtml"></span>
|
||||||
<span ref="workInformation" class="gl-ml-2">{{ user.workInformation }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-if="user.location" class="gl-display-flex gl-mb-2">
|
<div v-if="user.bot && user.websiteUrl" class="gl-text-blue-500">
|
||||||
<gl-icon name="location" class="gl-flex-shrink-0" />
|
<gl-icon name="question" />
|
||||||
<span class="gl-ml-2">{{ user.location }}</span>
|
<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>
|
||||||
<div
|
</template>
|
||||||
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>
|
</div>
|
||||||
</gl-popover>
|
</gl-popover>
|
||||||
|
|
|
@ -2,29 +2,30 @@
|
||||||
= stylesheet_link_tag 'mailers/highlighted_diff_email'
|
= stylesheet_link_tag 'mailers/highlighted_diff_email'
|
||||||
|
|
||||||
%h3
|
%h3
|
||||||
#{@message.author_name} #{@message.action_name} #{@message.ref_type} #{@message.ref_name}
|
= 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)))}
|
||||||
at #{link_to(@message.project_name_with_namespace, project_url(@message.project))}
|
|
||||||
|
|
||||||
- if @message.compare
|
- if @message.compare
|
||||||
- if @message.reverse_compare?
|
- if @message.reverse_compare?
|
||||||
%p
|
%p
|
||||||
%strong WARNING:
|
%strong
|
||||||
The push did not contain any new commits, but force pushed to delete the commits and changes below.
|
= _('WARNING:')
|
||||||
|
= s_('Notify|The push did not contain any new commits, but force pushed to delete the commits and changes below.')
|
||||||
|
|
||||||
%h4
|
%h4
|
||||||
= @message.reverse_compare? ? "Deleted commits:" : "Commits:"
|
= @message.reverse_compare? ? _("Deleted commits:") : _("Commits:")
|
||||||
|
|
||||||
%ul
|
%ul
|
||||||
- @message.commits.each do |commit|
|
- @message.commits.each do |commit|
|
||||||
%li
|
%li
|
||||||
%strong= link_to(commit.short_id, project_commit_url(@message.project, commit))
|
%strong= link_to(commit.short_id, project_commit_url(@message.project, commit))
|
||||||
%div
|
%div
|
||||||
%span by #{commit.author_name}
|
= 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}
|
||||||
%i at #{commit.committed_date.to_s(:iso8601)}
|
|
||||||
%pre.commit-message
|
%pre.commit-message
|
||||||
= commit.safe_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
|
%ul
|
||||||
- @message.diffs.each do |diff_file|
|
- @message.diffs.each do |diff_file|
|
||||||
|
@ -47,9 +48,11 @@
|
||||||
|
|
||||||
- unless @message.disable_diffs?
|
- unless @message.disable_diffs?
|
||||||
- if @message.compare_timeout
|
- 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
|
- else
|
||||||
%h4 Changes:
|
%h4
|
||||||
|
= _('Changes:')
|
||||||
- @message.diffs.each do |diff_file|
|
- @message.diffs.each do |diff_file|
|
||||||
- file_hash = hexdigest(diff_file.file_path)
|
- file_hash = hexdigest(diff_file.file_path)
|
||||||
%li{ id: file_hash }
|
%li{ id: file_hash }
|
||||||
|
@ -57,7 +60,7 @@
|
||||||
- if diff_file.deleted_file?
|
- if diff_file.deleted_file?
|
||||||
%strong<
|
%strong<
|
||||||
= diff_file.old_path
|
= diff_file.old_path
|
||||||
deleted
|
= s_('deleted')
|
||||||
- elsif diff_file.renamed_file?
|
- elsif diff_file.renamed_file?
|
||||||
%strong<
|
%strong<
|
||||||
= diff_file.old_path
|
= diff_file.old_path
|
||||||
|
@ -68,7 +71,7 @@
|
||||||
%strong<
|
%strong<
|
||||||
= diff_file.new_path
|
= diff_file.new_path
|
||||||
- if diff_file.too_large?
|
- 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
|
- else
|
||||||
%hr
|
%hr
|
||||||
- blob = diff_file.blob
|
- blob = diff_file.blob
|
||||||
|
@ -76,5 +79,5 @@
|
||||||
%table.code.white
|
%table.code.white
|
||||||
= render partial: "projects/diffs/email_line", collection: diff_file.highlighted_diff_lines, as: :line, locals: { diff_file: diff_file }
|
= render partial: "projects/diffs/email_line", collection: diff_file.highlighted_diff_lines, as: :line, locals: { diff_file: diff_file }
|
||||||
- else
|
- else
|
||||||
No preview for this file type
|
= s_('Notify|No preview for this file type')
|
||||||
%br
|
%br
|
||||||
|
|
|
@ -79,11 +79,11 @@ module Gitlab
|
||||||
@action_name ||=
|
@action_name ||=
|
||||||
case @action
|
case @action
|
||||||
when :create
|
when :create
|
||||||
'pushed new'
|
s_('Notify|pushed new')
|
||||||
when :delete
|
when :delete
|
||||||
'deleted'
|
s_('Notify|deleted')
|
||||||
else
|
else
|
||||||
'pushed to'
|
s_('Notify|pushed to')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7723,6 +7723,9 @@ msgstr ""
|
||||||
msgid "Changes to the title have not been saved"
|
msgid "Changes to the title have not been saved"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Changes:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Changing any setting here requires an application restart"
|
msgid "Changing any setting here requires an application restart"
|
||||||
msgstr ""
|
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."
|
msgid "Commits you select appear here. Go to the first tab and select commits to add to this merge request."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Commits:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Commits|An error occurred while fetching merge requests data."
|
msgid "Commits|An error occurred while fetching merge requests data."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -12717,6 +12723,9 @@ msgstr ""
|
||||||
msgid "Deleted chat nickname: %{chat_name}!"
|
msgid "Deleted chat nickname: %{chat_name}!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Deleted commits:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Deleted projects cannot be restored!"
|
msgid "Deleted projects cannot be restored!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -23423,7 +23432,7 @@ msgstr ""
|
||||||
msgid "Learn more"
|
msgid "Learn more"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Learn more about %{username}"
|
msgid "Learn more about %{name}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Learn more about Auto DevOps"
|
msgid "Learn more about Auto DevOps"
|
||||||
|
@ -27039,12 +27048,21 @@ msgstr ""
|
||||||
msgid "Notify|%{author_link}'s issue %{issue_reference_link} is due soon."
|
msgid "Notify|%{author_link}'s issue %{issue_reference_link} is due soon."
|
||||||
msgstr ""
|
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}"
|
msgid "Notify|%{commit_link} in %{mr_link}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Notify|%{commits_text} from branch `%{target_branch}`"
|
msgid "Notify|%{commits_text} from branch `%{target_branch}`"
|
||||||
msgstr ""
|
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}."
|
msgid "Notify|%{invite_email}, now known as %{user_name}, has accepted your invitation to join the %{target_name} %{target_model_name}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -27171,6 +27189,9 @@ msgstr ""
|
||||||
msgid "Notify|New issue: %{project_issue_url}"
|
msgid "Notify|New issue: %{project_issue_url}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Notify|No preview for this file type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Notify|Pipeline %{pipeline_link} triggered by"
|
msgid "Notify|Pipeline %{pipeline_link} triggered by"
|
||||||
msgstr ""
|
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}."
|
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 ""
|
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}"
|
msgid "Notify|This issue is due on: %{issue_due_date}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -27204,6 +27234,15 @@ msgstr ""
|
||||||
msgid "Notify|currently supported languages"
|
msgid "Notify|currently supported languages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Notify|deleted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Notify|pushed new"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Notify|pushed to"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Notify|successfully completed %{jobs} in %{stages}."
|
msgid "Notify|successfully completed %{jobs} in %{stages}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -43051,6 +43090,9 @@ msgstr ""
|
||||||
msgid "User identity was successfully updated."
|
msgid "User identity was successfully updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "User is blocked"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "User is not allowed to resolve thread"
|
msgid "User is not allowed to resolve thread"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -44194,6 +44236,9 @@ msgstr ""
|
||||||
msgid "Vulnerability|View training"
|
msgid "Vulnerability|View training"
|
||||||
msgstr ""
|
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."
|
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 ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
@ -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
|
|
@ -64,7 +64,7 @@ module QA
|
||||||
it(
|
it(
|
||||||
'comments on an issue with an attachment',
|
'comments on an issue with an attachment',
|
||||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347946',
|
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347946',
|
||||||
except: { job: 'review-qa-smoke' }
|
except: { job: 'review-qa-*' }
|
||||||
) do
|
) do
|
||||||
Page::Project::Issue::Show.perform do |show|
|
Page::Project::Issue::Show.perform do |show|
|
||||||
show.comment('See attached image for scale', attachment: file_to_attach)
|
show.comment('See attached image for scale', attachment: file_to_attach)
|
||||||
|
|
|
@ -15,7 +15,8 @@ module QA
|
||||||
{ klass: "Test::Instance::All" },
|
{ klass: "Test::Instance::All" },
|
||||||
{ klass: "Test::Instance::Smoke" },
|
{ klass: "Test::Instance::Smoke" },
|
||||||
{ klass: "Test::Instance::Reliable" },
|
{ klass: "Test::Instance::Reliable" },
|
||||||
{ klass: "Test::Instance::Blocking" },
|
{ klass: "Test::Instance::ReviewBlocking" },
|
||||||
|
{ klass: "Test::Instance::ReviewNonBlocking" },
|
||||||
{ klass: "Test::Instance::CloudActivation" },
|
{ klass: "Test::Instance::CloudActivation" },
|
||||||
{ klass: "Test::Instance::Integrations" },
|
{ klass: "Test::Instance::Integrations" },
|
||||||
{ klass: "Test::Instance::Jira" },
|
{ klass: "Test::Instance::Jira" },
|
||||||
|
|
|
@ -21,6 +21,7 @@ fi
|
||||||
variables=$(cat <<YML
|
variables=$(cat <<YML
|
||||||
variables:
|
variables:
|
||||||
GITLAB_VERSION: "$(cat VERSION)"
|
GITLAB_VERSION: "$(cat VERSION)"
|
||||||
|
COLORIZED_LOGS: "true"
|
||||||
QA_TESTS: "$QA_TESTS"
|
QA_TESTS: "$QA_TESTS"
|
||||||
QA_FEATURE_FLAGS: "${QA_FEATURE_FLAGS}"
|
QA_FEATURE_FLAGS: "${QA_FEATURE_FLAGS}"
|
||||||
QA_FRAMEWORK_CHANGES: "${QA_FRAMEWORK_CHANGES:-false}"
|
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"
|
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"
|
cp .gitlab/ci/review-apps/main.gitlab-ci.yml "$REVIEW_PIPELINE_YML"
|
||||||
echo "$variables" >>"$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"
|
cp .gitlab/ci/package-and-test/main.gitlab-ci.yml "$OMNIBUS_PIPELINE_YML"
|
||||||
echo "$variables" >>"$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"
|
echo "$variables"
|
||||||
|
|
|
@ -32,13 +32,6 @@ end
|
||||||
ActiveSupport::XmlMini.backend = 'Nokogiri'
|
ActiveSupport::XmlMini.backend = 'Nokogiri'
|
||||||
|
|
||||||
RSpec.configure do |config|
|
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.
|
# Makes diffs show entire non-truncated values.
|
||||||
config.before(:each, unlimited_max_formatted_output_length: true) do |_example|
|
config.before(:each, unlimited_max_formatted_output_length: true) do |_example|
|
||||||
config.expect_with :rspec do |c|
|
config.expect_with :rspec do |c|
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
import { GlSkeletonLoader, GlIcon } from '@gitlab/ui';
|
import { GlSkeletonLoader, GlIcon } from '@gitlab/ui';
|
||||||
import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
|
import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
|
||||||
|
import { sprintf } from '~/locale';
|
||||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||||
import { AVAILABILITY_STATUS } from '~/set_status_modal/constants';
|
import { AVAILABILITY_STATUS } from '~/set_status_modal/constants';
|
||||||
import UserPopover from '~/vue_shared/components/user_popover/user_popover.vue';
|
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 axios from '~/lib/utils/axios_utils';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import { followUser, unfollowUser } from '~/api/user_api';
|
import { followUser, unfollowUser } from '~/api/user_api';
|
||||||
|
@ -310,7 +317,9 @@ describe('User Popover Component', () => {
|
||||||
const securityBotDocsLink = findSecurityBotDocsLink();
|
const securityBotDocsLink = findSecurityBotDocsLink();
|
||||||
expect(securityBotDocsLink.exists()).toBe(true);
|
expect(securityBotDocsLink.exists()).toBe(true);
|
||||||
expect(securityBotDocsLink.attributes('href')).toBe(SECURITY_BOT_USER.websiteUrl);
|
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", () => {
|
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", () => {
|
it("doesn't escape user's name", () => {
|
||||||
createWrapper({ user: { ...SECURITY_BOT_USER, name: '%<>\';"' } });
|
const name = '%<>\';"';
|
||||||
|
createWrapper({ user: { ...SECURITY_BOT_USER, name } });
|
||||||
const securityBotDocsLink = findSecurityBotDocsLink();
|
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', () => {
|
it('does not display local time', () => {
|
||||||
|
@ -336,7 +346,7 @@ describe('User Popover Component', () => {
|
||||||
beforeEach(() => createWrapper());
|
beforeEach(() => createWrapper());
|
||||||
|
|
||||||
it('renders the Follow button with the correct variant', () => {
|
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');
|
expect(findToggleFollowButton().props('variant')).toBe('confirm');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -387,7 +397,7 @@ describe('User Popover Component', () => {
|
||||||
beforeEach(() => createWrapper({ user: { ...DEFAULT_PROPS.user, isFollowed: true } }));
|
beforeEach(() => createWrapper({ user: { ...DEFAULT_PROPS.user, isFollowed: true } }));
|
||||||
|
|
||||||
it('renders the Unfollow button with the correct variant', () => {
|
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');
|
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`', () => {
|
describe('when API does not support `isFollowed`', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const user = {
|
const user = {
|
||||||
|
|
|
@ -36,6 +36,7 @@ require 'rspec-parameterized'
|
||||||
require 'shoulda/matchers'
|
require 'shoulda/matchers'
|
||||||
require 'test_prof/recipes/rspec/let_it_be'
|
require 'test_prof/recipes/rspec/let_it_be'
|
||||||
require 'test_prof/factory_default'
|
require 'test_prof/factory_default'
|
||||||
|
require 'test_prof/factory_prof/nate_heckler'
|
||||||
require 'parslet/rig/rspec'
|
require 'parslet/rig/rspec'
|
||||||
|
|
||||||
rspec_profiling_is_configured =
|
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`
|
warn `curl -s -o log/goroutines.log http://localhost:9236/debug/pprof/goroutine?debug=2`
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
# Attempt to troubleshoot https://gitlab.com/gitlab-org/gitlab/-/issues/351531
|
# Attempt to troubleshoot https://gitlab.com/gitlab-org/gitlab/-/issues/351531
|
||||||
|
|
|
@ -14,6 +14,13 @@ RSpec.configure do |config|
|
||||||
# Re-run failures locally with `--only-failures`
|
# Re-run failures locally with `--only-failures`
|
||||||
config.example_status_persistence_file_path = ENV.fetch('RSPEC_LAST_RUN_RESULTS_FILE', './spec/examples.txt')
|
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|
|
config.mock_with :rspec do |mocks|
|
||||||
mocks.verify_doubled_constant_names = true
|
mocks.verify_doubled_constant_names = true
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue