Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-09-29 21:12:32 +00:00
parent fef5449973
commit 42a29f3879
38 changed files with 411 additions and 200 deletions

View file

@ -128,11 +128,13 @@ update-storybook-yarn-cache:
- tmp/tests/frontend/
- knapsack/
rspec frontend_fixture:
# In gitlab-foss, generates FOSS fixtures. In gitlab, generates FOSS & EE fixtures.
# That way, we don't need to have two separate jobs.
rspec-all frontend_fixture:
extends:
- .frontend-fixtures-base
- .frontend:rules:default-frontend-jobs
parallel: 2
parallel: 5
rspec frontend_fixture as-if-foss:
extends:
@ -140,12 +142,6 @@ rspec frontend_fixture as-if-foss:
- .frontend:rules:default-frontend-jobs-as-if-foss
- .as-if-foss
rspec-ee frontend_fixture:
extends:
- .frontend-fixtures-base
- .frontend:rules:default-frontend-jobs-ee
parallel: 3
graphql-schema-dump:
variables:
SETUP_DB: "false"
@ -196,9 +192,7 @@ jest:
- .frontend:rules:jest
needs:
- job: "detect-tests"
- job: "rspec frontend_fixture"
- job: "rspec-ee frontend_fixture"
optional: true
- job: "rspec-all frontend_fixture"
artifacts:
name: coverage-frontend
expire_in: 31d
@ -225,9 +219,7 @@ jest-integration:
script:
- run_timed_command "yarn jest:integration --ci"
needs:
- job: "rspec frontend_fixture"
- job: "rspec-ee frontend_fixture"
optional: true
- job: "rspec-all frontend_fixture"
- job: "graphql-schema-dump"
jest-as-if-foss:
@ -341,9 +333,7 @@ startup-css-check:
- .frontend:rules:default-frontend-jobs
needs:
- job: "compile-test-assets"
- job: "rspec frontend_fixture"
- job: "rspec-ee frontend_fixture"
optional: true
- job: "rspec-all frontend_fixture"
startup-css-check as-if-foss:
extends:

View file

@ -495,13 +495,6 @@
- <<: *if-default-refs
changes: *code-backstage-patterns
.frontend:rules:default-frontend-jobs-ee:
rules:
- <<: *if-not-ee
when: never
- <<: *if-default-refs
changes: *code-backstage-patterns
.frontend:rules:default-frontend-jobs-as-if-foss:
rules:
- <<: *if-not-ee

View file

@ -29,8 +29,7 @@ update-tests-metadata:
- retrieve-tests-metadata
- setup-test-env
- rspec migration pg12
- rspec frontend_fixture
- rspec-ee frontend_fixture
- rspec-all frontend_fixture
- rspec unit pg12
- rspec integration pg12
- rspec system pg12

View file

@ -316,7 +316,7 @@ export default {
</p>
</gl-tooltip>
<span ref="countBadge" class="issue-count-badge board-card-info gl-mr-0 gl-pr-0">
<span ref="countBadge" class="board-card-info gl-mr-0 gl-pr-0 gl-pl-3">
<span v-if="allowSubEpics" class="gl-mr-3">
<gl-icon name="epic" />
{{ totalEpicsCount }}
@ -334,7 +334,7 @@ export default {
<span
v-if="shouldRenderEpicProgress"
ref="progressBadge"
class="issue-count-badge board-card-info gl-pl-0"
class="board-card-info gl-pl-0"
>
<span class="gl-mr-3" data-testid="epic-progress">
<gl-icon name="progress" />

View file

@ -365,7 +365,7 @@ export default {
>
<span class="gl-display-inline-flex">
<gl-tooltip :target="() => $refs.itemCount" :title="itemsTooltipLabel" />
<span ref="itemCount" class="issue-count-badge-count">
<span ref="itemCount" class="gl-display-inline-flex gl-align-items-center">
<gl-icon class="gl-mr-2" :name="countIcon" />
<item-count :items-size="itemsCount" :max-issue-count="list.maxIssueCount" />
</span>
@ -388,7 +388,7 @@ export default {
v-gl-tooltip.hover
:aria-label="$options.i18n.newIssue"
:title="$options.i18n.newIssue"
class="issue-count-badge-add-button no-drag"
class="no-drag"
icon="plus"
@click="showNewIssueForm"
/>

View file

@ -162,7 +162,6 @@ export default {
icon="plus"
:aria-label="__('Add a related issue')"
:class="qaClass"
class="js-issue-count-badge-add-button"
@click="$emit('toggleAddRelatedIssuesForm', $event)"
/>
</div>

View file

@ -81,13 +81,13 @@ export default {
{{ __('Related merge requests') }}
</span>
<div v-if="totalCount" class="d-inline-flex lh-100 align-middle">
<div class="mr-count-badge gl-display-inline-flex">
<div class="mr-count-badge-count">
<svg class="s16 mr-1 text-secondary">
<gl-icon name="merge-request" class="mr-1 text-secondary" />
</svg>
<span class="js-items-count">{{ totalCount }}</span>
</div>
<div
class="mr-count-badge gl-display-inline-flex gl-align-items-center gl-py-2 gl-px-3"
>
<svg class="s16 mr-1 text-secondary">
<gl-icon name="merge-request" class="mr-1 text-secondary" />
</svg>
<span class="js-items-count">{{ totalCount }}</span>
</div>
</div>
</div>

View file

@ -6,7 +6,7 @@ import TokenAccess from './components/token_access.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
defaultClient: createDefaultClient({}, { assumeImmutableResults: true }),
});
export const initTokenAccess = (containerId = 'js-ci-token-access-app') => {

View file

@ -10,7 +10,6 @@
@import './pages/groups';
@import './pages/help';
@import './pages/issuable';
@import './pages/issues/issue_count_badge';
@import './pages/issues';
@import './pages/labels';
@import './pages/login';

View file

@ -1,10 +0,0 @@
.issue-count-badge,
.mr-count-badge {
padding: 5px $gl-padding-8;
}
.issue-count-badge-count,
.mr-count-badge-count {
display: inline-flex;
align-items: center;
}

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
module Ci
module StuckBuilds
class DropRunningService
include DropHelpers
BUILD_RUNNING_OUTDATED_TIMEOUT = 1.hour
def execute
Gitlab::AppLogger.info "#{self.class}: Cleaning running, timed-out builds"
drop(running_timed_out_builds, failure_reason: :stuck_or_timeout_failure)
end
private
def running_timed_out_builds
Ci::Build.running.updated_at_before(BUILD_RUNNING_OUTDATED_TIMEOUT.ago)
end
end
end
end

View file

@ -5,7 +5,6 @@ module Ci
class DropService
include DropHelpers
BUILD_RUNNING_OUTDATED_TIMEOUT = 1.hour
BUILD_PENDING_OUTDATED_TIMEOUT = 1.day
BUILD_SCHEDULED_OUTDATED_TIMEOUT = 1.hour
BUILD_PENDING_STUCK_TIMEOUT = 1.hour
@ -14,8 +13,6 @@ module Ci
def execute
Gitlab::AppLogger.info "#{self.class}: Cleaning stuck builds"
drop(running_timed_out_builds, failure_reason: :stuck_or_timeout_failure)
drop(
pending_builds(BUILD_PENDING_OUTDATED_TIMEOUT.ago),
failure_reason: :stuck_or_timeout_failure
@ -50,13 +47,6 @@ module Ci
BUILD_SCHEDULED_OUTDATED_TIMEOUT.ago
)
end
def running_timed_out_builds
Ci::Build.running.where( # rubocop: disable CodeReuse/ActiveRecord
'ci_builds.updated_at < ?',
BUILD_RUNNING_OUTDATED_TIMEOUT.ago
)
end
end
end
end

View file

@ -228,6 +228,15 @@
:weight: 1
:idempotent: true
:tags: []
- :name: cronjob:ci_stuck_builds_drop_running
:worker_name: Ci::StuckBuilds::DropRunningWorker
:feature_category: :continuous_integration
:has_external_dependencies:
:urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent: true
:tags: []
- :name: cronjob:container_expiration_policy
:worker_name: ContainerExpirationPolicyWorker
:feature_category: :container_registry

View file

@ -0,0 +1,43 @@
# frozen_string_literal: true
module Ci
module StuckBuilds
class DropRunningWorker
include ApplicationWorker
idempotent!
# rubocop:disable Scalability/CronWorkerContext
# This is an instance-wide cleanup query, so there's no meaningful
# scope to consider this in the context of.
include CronjobQueue
# rubocop:enable Scalability/CronWorkerContext
data_consistency :always
feature_category :continuous_integration
EXCLUSIVE_LEASE_KEY = 'ci_stuck_builds_drop_running_worker_lease'
def perform
return unless try_obtain_lease
begin
Ci::StuckBuilds::DropRunningService.new.execute
ensure
remove_lease
end
end
private
def try_obtain_lease
@uuid = Gitlab::ExclusiveLease.new(EXCLUSIVE_LEASE_KEY, timeout: 30.minutes).try_obtain
end
def remove_lease
Gitlab::ExclusiveLease.cancel(EXCLUSIVE_LEASE_KEY, @uuid)
end
end
end
end

View file

@ -17,6 +17,8 @@ class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker
EXCLUSIVE_LEASE_KEY = 'stuck_ci_builds_worker_lease'
def perform
Ci::StuckBuilds::DropRunningWorker.perform_in(20.minutes)
return unless try_obtain_lease
Ci::StuckBuilds::DropService.new.execute

View file

@ -1,15 +1,5 @@
# frozen_string_literal: true
def log_pool_size(db, previous_pool_size, current_pool_size)
log_message = ["#{db} connection pool size: #{current_pool_size}"]
if previous_pool_size && current_pool_size > previous_pool_size
log_message << "(increased from #{previous_pool_size} to match thread count)"
end
Gitlab::AppLogger.debug(log_message.join(' '))
end
Gitlab.ee do
# We need to initialize the Geo database before
# setting the Geo DB connection pool size.

View file

@ -252,7 +252,7 @@ graph RL;
2_1-1 & 2_1-2 & 2_1-3 & 2_1-4 --> 1-6;
end
2_2-2["rspec frontend_fixture/rspec-ee frontend_fixture (7 minutes)"];
2_2-2["rspec-all frontend_fixture (7 minutes)"];
class 2_2-2 criticalPath;
click 2_2-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910143&udv=0"
2_2-4["memory-on-boot (3.5 minutes)"];
@ -284,7 +284,7 @@ graph RL;
3_1-1["jest (14.5 minutes)"];
class 3_1-1 criticalPath;
click 3_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914204&udv=0"
subgraph "Needs `rspec frontend_fixture/rspec-ee frontend_fixture`";
subgraph "Needs `rspec-all frontend_fixture`";
3_1-1 --> 2_2-2;
end
@ -355,7 +355,7 @@ graph RL;
2_1-1 & 2_1-2 & 2_1-3 & 2_1-4 --> 1-6;
end
2_2-2["rspec frontend_fixture/rspec-ee frontend_fixture (7 minutes)"];
2_2-2["rspec-all frontend_fixture (7 minutes)"];
class 2_2-2 criticalPath;
click 2_2-2 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=7910143&udv=0"
2_2-4["memory-on-boot (3.5 minutes)"];
@ -395,7 +395,7 @@ graph RL;
3_1-1["jest (14.5 minutes)"];
class 3_1-1 criticalPath;
click 3_1-1 "https://app.periscopedata.com/app/gitlab/652085/Engineering-Productivity---Pipeline-Build-Durations?widget=6914204&udv=0"
subgraph "Needs `rspec frontend_fixture/rspec-ee frontend_fixture`";
subgraph "Needs `rspec-all frontend_fixture`";
3_1-1 --> 2_2-2;
end

View file

@ -53,6 +53,8 @@ immediately identify which alerts you should prioritize investigating:
Alerts contain one of the following icons:
<!-- vale gitlab.SubstitutionWarning = NO -->
| Severity | Icon | Color (hexadecimal) |
|----------|-------------------------|---------------------|
| Critical | **{severity-critical}** | `#8b2615` |
@ -62,6 +64,8 @@ Alerts contain one of the following icons:
| Info | **{severity-info}** | `#418cd8` |
| Unknown | **{severity-unknown}** | `#bababa` |
<!-- vale gitlab.SubstitutionWarning = YES -->
## Alert details page
Navigate to the Alert details view by visiting the [Alert list](alerts.md)

View file

@ -10,7 +10,7 @@ type: reference, howto
Coverage-guided fuzzing sends random inputs to an instrumented version of your application in an
effort to cause unexpected behavior. Such behavior indicates a bug that you should address.
GitLab allows you to add coverage-guided fuzz testing to your pipelines. This helps you discover
bugs and potential security issues that other QA processes may miss.
bugs and potential security issues that other QA processes may miss.
We recommend that you use fuzz testing in addition to the other security scanners in [GitLab Secure](../index.md)
and your own test processes. If you're using [GitLab CI/CD](../../../ci/index.md),
@ -248,6 +248,8 @@ which shows an overview of all the security vulnerabilities in your groups, proj
Clicking the vulnerability opens a modal that provides additional information about the
vulnerability:
<!-- vale gitlab.Acronyms = NO -->
- Status: The vulnerability's status. As with any type of vulnerability, a coverage fuzzing
vulnerability can be Detected, Confirmed, Dismissed, or Resolved.
- Project: The project in which the vulnerability exists.
@ -261,3 +263,5 @@ vulnerability:
- Scanner: The scanner that detected the vulnerability (for example, Coverage Fuzzing).
- Scanner Provider: The engine that did the scan. For Coverage Fuzzing, this can be any of the
engines listed in [Supported fuzzing engines and languages](#supported-fuzzing-engines-and-languages).
<!-- vale gitlab.Acronyms = YES -->

View file

@ -27,6 +27,8 @@ analysis are available in the [security dashboards](../security_dashboard/index.
The results are sorted by the priority of the vulnerability:
<!-- vale gitlab.SubstitutionWarning = NO -->
1. Critical
1. High
1. Medium
@ -34,6 +36,8 @@ The results are sorted by the priority of the vulnerability:
1. Info
1. Unknown
<!-- vale gitlab.SubstitutionWarning = YES -->
A pipeline consists of multiple jobs, including SAST and DAST scanning. If any job fails to finish
for any reason, the security dashboard does not show SAST scanner output. For example, if the SAST
job finishes but the DAST job fails, the security dashboard does not show SAST results. On failure,

View file

@ -45,6 +45,8 @@ From the Vulnerability Report you can:
You can filter the vulnerabilities table by:
<!-- vale gitlab.SubstitutionWarning = NO -->
| Filter | Available options |
|:---------|:------------------|
| Status | Detected, Confirmed, Dismissed, Resolved. |
@ -53,6 +55,8 @@ You can filter the vulnerabilities table by:
| Project | For more details, see [Project filter](#project-filter). |
| Activity | For more details, see [Activity filter](#activity-filter). |
<!-- vale gitlab.SubstitutionWarning = YES -->
### Filter the list of vulnerabilities
To filter the list of vulnerabilities:

View file

@ -1,5 +1,4 @@
---
type: reference, howto
stage: Manage
group: Import
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
@ -10,30 +9,30 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Import your projects from Gitea to GitLab with minimal effort.
NOTE:
This requires Gitea `v1.0.0` or newer.
This requires Gitea `v1.0.0` or later.
The Gitea importer can import:
- Repository description (GitLab 8.15+)
- Git repository data (GitLab 8.15+)
- Issues (GitLab 8.15+)
- Pull requests (GitLab 8.15+)
- Milestones (GitLab 8.15+)
- Labels (GitLab 8.15+)
- Repository description
- Git repository data
- Issues
- Pull requests
- Milestones
- Labels
When importing, repository public access is retained. If a repository is private in Gitea, it's
created as private in GitLab as well.
## How it works
Since Gitea is currently not an OAuth provider, author/assignee cannot be mapped
to users in your GitLab instance. This means that the project creator (most of
the times the current user that started the import process) is set as the author,
but a reference on the issue about the original Gitea author is kept.
Because Gitea isn't an OAuth provider, author/assignee can't be mapped to users
in your GitLab instance. This means the project creator (usually the user that
started the import process) is set as the author. A reference, however, is kept
on the issue about the original Gitea author.
The importer creates any new namespaces (groups) if they don't exist or in
the case the namespace is taken, the repository is imported under the user's
namespace that started the import process.
The importer creates any new namespaces (groups) if they don't exist. If the
namespace is taken, the repository is imported under the user's namespace
that started the import process.
## Import your Gitea repositories
@ -41,7 +40,7 @@ The importer page is visible when you create a new project.
![New project page on GitLab](img/import_projects_from_new_project_page.png)
Click the **Gitea** link and the import authorization process starts.
Select the **Gitea** link to start the import authorization process.
![New Gitea project import](img/import_projects_from_gitea_new_import.png)
@ -52,13 +51,13 @@ GitLab access your repositories:
1. Go to `https://your-gitea-instance/user/settings/applications` (replace
`your-gitea-instance` with the host of your Gitea instance).
1. Click **Generate New Token**.
1. Select **Generate New Token**.
1. Enter a token description.
1. Click **Generate Token**.
1. Select **Generate Token**.
1. Copy the token hash.
1. Go back to GitLab and provide the token to the Gitea importer.
1. Hit the **List Your Gitea Repositories** button and wait while GitLab reads
your repositories' information. Once done, you are taken to the importer
1. Select **List Your Gitea Repositories** and wait while GitLab reads
your repositories' information. After it's done, GitLab displays the importer
page to select the repositories to import.
### Select which repositories to import
@ -66,19 +65,19 @@ GitLab access your repositories:
After you've authorized access to your Gitea repositories, you are
redirected to the Gitea importer page.
From there, you can see the import statuses of your Gitea repositories.
From there, you can view the import statuses of your Gitea repositories:
- Those that are being imported show a _started_ status,
- those already successfully imported are green with a _done_ status,
- whereas those that are not yet imported have an **Import** button on the
- Those that are being imported show a _started_ status.
- Those already successfully imported are green with a _done_ status.
- Those that aren't yet imported have an **Import** button on the
right side of the table.
You also can:
- Import all your Gitea projects in one go by hitting **Import all projects** in
the upper left corner.
- Filter projects by name. If filter is applied, hitting **Import all projects**
only imports matched projects.
- Import all of your Gitea projects in one go by selecting **Import all projects**
in the upper left corner.
- Filter projects by name. If filter is applied, selecting **Import all projects**
imports only matched projects.
![Gitea importer page](img/import_projects_from_gitea_importer_v12_3.png)

View file

@ -55,9 +55,9 @@
"@babel/preset-env": "^7.10.1",
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "1.212.0",
"@gitlab/svgs": "1.213.0",
"@gitlab/tributejs": "1.0.0",
"@gitlab/ui": "32.11.4",
"@gitlab/ui": "32.12.0",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "6.1.3-2",
"@rails/ujs": "6.1.3-2",

View file

@ -58,8 +58,8 @@ module QA
testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1806',
issue_1: 'https://gitlab.com/gitlab-org/gitlab/-/issues/331252',
issue_2: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333678',
# mostly impacts testing as it makes small groups import slower
issue_3: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332351'
issue_3: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332351',
except: { job: 'instance-image-slow-network' }
) do
Page::Group::BulkImport.perform do |import_page|
import_page.import_group(imported_group.path, imported_group.sandbox.path)

View file

@ -109,14 +109,18 @@ function rspec_paralellized_job() {
local test_level="${job_name[1]}"
local report_name=$(echo "${CI_JOB_NAME}" | sed -E 's|[/ ]|_|g') # e.g. 'rspec unit pg12 1/24' would become 'rspec_unit_pg12_1_24'
local rspec_opts="${1}"
local spec_folder_prefix=""
local spec_folder_prefixes=""
if [[ "${test_tool}" =~ "-ee" ]]; then
spec_folder_prefix="ee/"
spec_folder_prefixes="'ee/'"
fi
if [[ "${test_tool}" =~ "-jh" ]]; then
spec_folder_prefix="jh/"
spec_folder_prefixes="'jh/'"
fi
if [[ "${test_tool}" =~ "-all" ]]; then
spec_folder_prefixes="['', 'ee/']"
fi
export KNAPSACK_LOG_LEVEL="debug"
@ -131,7 +135,7 @@ function rspec_paralellized_job() {
cp "${KNAPSACK_RSPEC_SUITE_REPORT_PATH}" "${KNAPSACK_REPORT_PATH}"
if [[ -z "${KNAPSACK_TEST_FILE_PATTERN}" ]]; then
pattern=$(ruby -r./tooling/quality/test_level.rb -e "puts Quality::TestLevel.new(%(${spec_folder_prefix})).pattern(:${test_level})")
pattern=$(ruby -r./tooling/quality/test_level.rb -e "puts Quality::TestLevel.new(${spec_folder_prefixes}).pattern(:${test_level})")
export KNAPSACK_TEST_FILE_PATTERN="${pattern}"
fi

View file

@ -68,7 +68,7 @@ RSpec.describe 'Issue Boards new issue', :js do
wait_for_requests
page.within(first('.board .issue-count-badge-count')) do
page.within(first('.board [data-testid="issue-count-badge"]')) do
expect(page).to have_content('1')
end

View file

@ -16,7 +16,7 @@ RSpec.describe 'Ensure Boards do not show stale data on browser back', :js do
visit project_board_path(project, board)
wait_for_requests
page.within(first('.board .issue-count-badge-count')) do
page.within(first('.board [data-testid="issue-count-badge"]')) do
expect(page).to have_content('0')
end
end
@ -35,7 +35,7 @@ RSpec.describe 'Ensure Boards do not show stale data on browser back', :js do
page.go_back
wait_for_requests
page.within(first('.board .issue-count-badge-count')) do
page.within(first('.board [data-testid="issue-count-badge"]')) do
expect(page).to have_content('1')
end

View file

@ -24,7 +24,7 @@ RSpec.describe 'Group Boards' do
it 'adds an issue to the backlog' do
page.within(find('.board', match: :first)) do
issue_title = 'New Issue'
find(:css, '.issue-count-badge-add-button').click
click_button 'New issue'
wait_for_requests

View file

@ -41,13 +41,13 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).not_to have_selector('.js-issue-count-badge-add-button')
expect(page).not_to have_button 'Add a related issue'
end
end
context 'when logged in but not a member' do
before do
gitlab_sign_in(user)
sign_in(user)
end
it 'shows widget when internal project' do
@ -57,7 +57,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).not_to have_selector('.js-issue-count-badge-add-button')
expect(page).not_to have_button 'Add a related issue'
end
it 'does not show widget when private project' do
@ -76,7 +76,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).not_to have_selector('.js-issue-count-badge-add-button')
expect(page).not_to have_button 'Add a related issue'
end
it 'shows widget on their own public issue' do
@ -86,13 +86,13 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).not_to have_selector('.js-issue-count-badge-add-button')
expect(page).not_to have_button 'Add a related issue'
end
end
context 'when logged in and a guest' do
before do
gitlab_sign_in(user)
sign_in(user)
end
it 'shows widget when internal project' do
@ -103,7 +103,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).not_to have_selector('.js-issue-count-badge-add-button')
expect(page).not_to have_button 'Add a related issue'
end
it 'shows widget when private project' do
@ -114,7 +114,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).not_to have_selector('.js-issue-count-badge-add-button')
expect(page).not_to have_button 'Add a related issue'
end
it 'shows widget when public project' do
@ -125,13 +125,13 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).not_to have_selector('.js-issue-count-badge-add-button')
expect(page).not_to have_button 'Add a related issue'
end
end
context 'when logged in and a reporter' do
before do
gitlab_sign_in(user)
sign_in(user)
end
it 'shows widget when internal project' do
@ -142,7 +142,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).to have_selector('.js-issue-count-badge-add-button')
expect(page).to have_button 'Add a related issue'
end
it 'shows widget when private project' do
@ -153,7 +153,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).to have_selector('.js-issue-count-badge-add-button')
expect(page).to have_button 'Add a related issue'
end
it 'shows widget when public project' do
@ -164,7 +164,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).to have_selector('.js-issue-count-badge-add-button')
expect(page).to have_button 'Add a related issue'
end
it 'shows widget on their own public issue' do
@ -175,7 +175,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
expect(page).to have_selector('.js-issue-count-badge-add-button')
expect(page).to have_button 'Add a related issue'
end
end
end
@ -186,7 +186,7 @@ RSpec.describe 'Related issues', :js do
before do
project.add_guest(user)
gitlab_sign_in(user)
sign_in(user)
end
context 'visiting some issue someone else created' do
@ -216,7 +216,7 @@ RSpec.describe 'Related issues', :js do
before do
project.add_maintainer(user)
project_b.add_maintainer(user)
gitlab_sign_in(user)
sign_in(user)
end
context 'without existing related issues' do
@ -230,7 +230,7 @@ RSpec.describe 'Related issues', :js do
end
it 'add related issue' do
find('.js-issue-count-badge-add-button').click
click_button 'Add a related issue'
find('.js-add-issuable-form-input').set "#{issue_b.to_reference(project)} "
find('.js-add-issuable-form-add-button').click
@ -247,7 +247,7 @@ RSpec.describe 'Related issues', :js do
end
it 'add cross-project related issue' do
find('.js-issue-count-badge-add-button').click
click_button 'Add a related issue'
find('.js-add-issuable-form-input').set "#{issue_project_b_a.to_reference(project)} "
find('.js-add-issuable-form-add-button').click
@ -261,7 +261,7 @@ RSpec.describe 'Related issues', :js do
end
it 'pressing enter should submit the form' do
find('.js-issue-count-badge-add-button').click
click_button 'Add a related issue'
find('.js-add-issuable-form-input').set "#{issue_project_b_a.to_reference(project)} "
find('.js-add-issuable-form-input').native.send_key(:enter)
@ -275,7 +275,7 @@ RSpec.describe 'Related issues', :js do
end
it 'disallows duplicate entries' do
find('.js-issue-count-badge-add-button').click
click_button 'Add a related issue'
find('.js-add-issuable-form-input').set 'duplicate duplicate duplicate'
items = all('.js-add-issuable-form-token-list-item')
@ -288,7 +288,7 @@ RSpec.describe 'Related issues', :js do
it 'allows us to remove pending issues' do
# Tests against https://gitlab.com/gitlab-org/gitlab/issues/11625
find('.js-issue-count-badge-add-button').click
click_button 'Add a related issue'
find('.js-add-issuable-form-input').set 'issue1 issue2 issue3 '
items = all('.js-add-issuable-form-token-list-item')
@ -351,7 +351,7 @@ RSpec.describe 'Related issues', :js do
end
it 'add related issue' do
find('.js-issue-count-badge-add-button').click
click_button 'Add a related issue'
find('.js-add-issuable-form-input').set "##{issue_d.iid} "
find('.js-add-issuable-form-add-button').click
@ -367,7 +367,7 @@ RSpec.describe 'Related issues', :js do
end
it 'add invalid related issue' do
find('.js-issue-count-badge-add-button').click
click_button 'Add a related issue'
find('.js-add-issuable-form-input').set "#9999999 "
find('.js-add-issuable-form-add-button').click
@ -382,7 +382,7 @@ RSpec.describe 'Related issues', :js do
end
it 'add unauthorized related issue' do
find('.js-issue-count-badge-add-button').click
click_button 'Add a related issue'
find('.js-add-issuable-form-input').set "#{issue_project_unauthorized_a.to_reference(project)} "
find('.js-add-issuable-form-add-button').click

View file

@ -0,0 +1,65 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::StuckBuilds::DropRunningService do
let!(:runner) { create :ci_runner }
let!(:job) { create :ci_build, runner: runner }
let(:created_at) { }
let(:updated_at) { }
subject(:service) { described_class.new }
before do
job_attributes = { status: status }
job_attributes[:created_at] = created_at if created_at
job_attributes[:updated_at] = updated_at if updated_at
job.update!(job_attributes)
end
context 'when job is running' do
let(:status) { 'running' }
context 'when job was updated_at more than an hour ago' do
let(:updated_at) { 2.hours.ago }
it_behaves_like 'job is dropped'
end
context 'when job was updated in less than 1 hour ago' do
let(:updated_at) { 30.minutes.ago }
it_behaves_like 'job is unchanged'
end
end
%w(success skipped failed canceled scheduled pending).each do |status|
context "when job is #{status}" do
let(:status) { status }
let(:updated_at) { 2.days.ago }
context 'when created_at is the same as updated_at' do
let(:created_at) { 2.days.ago }
it_behaves_like 'job is unchanged'
end
context 'when created_at is before updated_at' do
let(:created_at) { 3.days.ago }
it_behaves_like 'job is unchanged'
end
end
end
context 'for deleted project' do
let(:status) { 'running' }
let(:updated_at) { 2.days.ago }
before do
job.project.update!(pending_delete: true)
end
it_behaves_like 'job is dropped'
end
end

View file

@ -17,48 +17,6 @@ RSpec.describe Ci::StuckBuilds::DropService do
job.update!(job_attributes)
end
shared_examples 'job is dropped' do
it 'changes status' do
expect(service).to receive(:drop).exactly(3).times.and_call_original
expect(service).to receive(:drop_stuck).exactly(:once).and_call_original
service.execute
job.reload
expect(job).to be_failed
expect(job).to be_stuck_or_timeout_failure
end
context 'when job have data integrity problem' do
it "does drop the job and logs the reason" do
job.update_columns(yaml_variables: '[{"key" => "value"}]')
expect(Gitlab::ErrorTracking).to receive(:track_exception)
.with(anything, a_hash_including(build_id: job.id))
.once
.and_call_original
service.execute
job.reload
expect(job).to be_failed
expect(job).to be_data_integrity_failure
end
end
end
shared_examples 'job is unchanged' do
it 'does not change status' do
expect(service).to receive(:drop).exactly(3).times.and_call_original
expect(service).to receive(:drop_stuck).exactly(:once).and_call_original
service.execute
job.reload
expect(job.status).to eq(status)
end
end
context 'when job is pending' do
let(:status) { 'pending' }
@ -195,7 +153,7 @@ RSpec.describe Ci::StuckBuilds::DropService do
context 'when job was updated_at more than an hour ago' do
let(:updated_at) { 2.hours.ago }
it_behaves_like 'job is dropped'
it_behaves_like 'job is unchanged'
end
context 'when job was updated in less than 1 hour ago' do
@ -238,7 +196,7 @@ RSpec.describe Ci::StuckBuilds::DropService do
job.project.update!(pending_delete: true)
end
it_behaves_like 'job is dropped'
it_behaves_like 'job is unchanged'
end
describe 'drop stale scheduled builds' do

View file

@ -71,7 +71,7 @@ module FeatureFlagHelpers
end
def add_linked_issue_button
find('.js-issue-count-badge-add-button')
find_button 'Add a related issue'
end
def remove_linked_issue_button

View file

@ -0,0 +1,38 @@
# frozen_string_literal: true
RSpec.shared_examples 'job is dropped' do
it 'changes status' do
service.execute
job.reload
expect(job).to be_failed
expect(job).to be_stuck_or_timeout_failure
end
context 'when job has data integrity problem' do
it 'drops the job and logs the reason' do
job.update_columns(yaml_variables: '[{"key" => "value"}]')
expect(Gitlab::ErrorTracking)
.to receive(:track_exception)
.with(anything, a_hash_including(build_id: job.id))
.once
.and_call_original
service.execute
job.reload
expect(job).to be_failed
expect(job).to be_data_integrity_failure
end
end
end
RSpec.shared_examples 'job is unchanged' do
it 'does not change status' do
service.execute
job.reload
expect(job.status).to eq(status)
end
end

View file

@ -63,7 +63,14 @@ RSpec.describe Quality::TestLevel do
context 'with a prefix' do
it 'returns a pattern' do
expect(described_class.new('ee/').pattern(:system))
.to eq("ee/spec/{features}{,/**/}*_spec.rb")
.to eq("{ee/}spec/{features}{,/**/}*_spec.rb")
end
end
context 'with several prefixes' do
it 'returns a pattern' do
expect(described_class.new(['', 'ee/', 'jh/']).pattern(:system))
.to eq("{,ee/,jh/}spec/{features}{,/**/}*_spec.rb")
end
end
@ -138,7 +145,14 @@ RSpec.describe Quality::TestLevel do
context 'with a prefix' do
it 'returns a regexp' do
expect(described_class.new('ee/').regexp(:system))
.to eq(%r{ee/spec/(features)})
.to eq(%r{(ee/)spec/(features)})
end
end
context 'with several prefixes' do
it 'returns a regexp' do
expect(described_class.new(['', 'ee/', 'jh/']).regexp(:system))
.to eq(%r{(|ee/|jh/)spec/(features)})
end
end

View file

@ -0,0 +1,70 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::StuckBuilds::DropRunningWorker do
include ExclusiveLeaseHelpers
let(:worker_lease_key) { Ci::StuckBuilds::DropRunningWorker::EXCLUSIVE_LEASE_KEY }
let(:worker_lease_uuid) { SecureRandom.uuid }
let(:worker2) { described_class.new }
subject(:worker) { described_class.new }
before do
stub_exclusive_lease(worker_lease_key, worker_lease_uuid)
end
describe '#perform' do
it_behaves_like 'an idempotent worker'
it 'executes an instance of Ci::StuckBuilds::DropRunningService' do
expect_next_instance_of(Ci::StuckBuilds::DropRunningService) do |service|
expect(service).to receive(:execute).exactly(:once)
end
worker.perform
end
context 'with an exclusive lease' do
it 'does not execute concurrently' do
expect(worker).to receive(:remove_lease).exactly(:once)
expect(worker2).not_to receive(:remove_lease)
worker.perform
stub_exclusive_lease_taken(worker_lease_key)
worker2.perform
end
it 'can execute in sequence' do
expect(worker).to receive(:remove_lease).at_least(:once)
expect(worker2).to receive(:remove_lease).at_least(:once)
worker.perform
worker2.perform
end
it 'cancels exclusive leases after worker perform' do
expect_to_cancel_exclusive_lease(worker_lease_key, worker_lease_uuid)
worker.perform
end
context 'when the DropRunningService fails' do
it 'ensures cancellation of the exclusive lease' do
expect_to_cancel_exclusive_lease(worker_lease_key, worker_lease_uuid)
allow_next_instance_of(Ci::StuckBuilds::DropRunningService) do |service|
allow(service).to receive(:execute) do
raise 'The query timed out'
end
end
expect { worker.perform }.to raise_error(/The query timed out/)
end
end
end
end
end

View file

@ -16,7 +16,13 @@ RSpec.describe StuckCiJobsWorker do
end
describe '#perform' do
it 'executes an instance of Ci::StuckBuildsDropService' do
it 'enqueues a Ci::StuckBuilds::DropRunningWorker job' do
expect(Ci::StuckBuilds::DropRunningWorker).to receive(:perform_in).with(20.minutes).exactly(:once)
worker.perform
end
it 'executes an instance of Ci::StuckBuilds::DropService' do
expect_next_instance_of(Ci::StuckBuilds::DropService) do |service|
expect(service).to receive(:execute).exactly(:once)
end

View file

@ -60,20 +60,20 @@ module Quality
system: ['features']
}.freeze
attr_reader :prefix
attr_reader :prefixes
def initialize(prefix = nil)
@prefix = prefix
def initialize(prefixes = nil)
@prefixes = Array(prefixes)
@patterns = {}
@regexps = {}
end
def pattern(level)
@patterns[level] ||= "#{prefix}spec/#{folders_pattern(level)}{,/**/}*#{suffix(level)}"
@patterns[level] ||= "#{prefixes_for_pattern}spec/#{folders_pattern(level)}{,/**/}*#{suffix(level)}"
end
def regexp(level)
@regexps[level] ||= Regexp.new("#{prefix}spec/#{folders_regex(level)}").freeze
@regexps[level] ||= Regexp.new("#{prefixes_for_regex}spec/#{folders_regex(level)}").freeze
end
def level_for(file_path)
@ -102,6 +102,20 @@ module Quality
private
def prefixes_for_pattern
return '' if prefixes.empty?
"{#{prefixes.join(',')}}"
end
def prefixes_for_regex
return '' if prefixes.empty?
regex_prefix = prefixes.map(&Regexp.method(:escape)).join('|')
"(#{regex_prefix})"
end
def suffix(level)
case level
when :frontend_fixture

View file

@ -964,20 +964,20 @@
stylelint-declaration-strict-value "1.7.7"
stylelint-scss "3.18.0"
"@gitlab/svgs@1.212.0":
version "1.212.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.212.0.tgz#21a5df04c52b10cc1b8521cd8ff7c7d6d13716db"
integrity sha512-dv0bYTHA3hwi3mNU3bGMq1cd4HVKKFNwCNPgkF91JSp4Xt8DDtJ0Yq4X49ASsq4zCJ3odgkq2aPjEa/Sr5nINQ==
"@gitlab/svgs@1.213.0":
version "1.213.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.213.0.tgz#fcd9794049d2b15f5796dbab2a3d501679153582"
integrity sha512-3d9EGpEkPDeW92Xx3FueFCJFZ/yL+uv5MWCUHmSt1tP9YmUhMXw/51c43c5+V17FuCyvhJS5tm3aEg3VYoWIRA==
"@gitlab/tributejs@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
"@gitlab/ui@32.11.4":
version "32.11.4"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.11.4.tgz#ead781c4fd57b4f7bc6818de99e56d023f94c397"
integrity sha512-plxOvtAIo+PIng1jBssj/QCx2ATIbZqQvLvCeezgAABgY107XhqZDw50VZL0texTX+0jGwB5PaXthmU/wnCk2w==
"@gitlab/ui@32.12.0":
version "32.12.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.12.0.tgz#a2e45a7587beb2b9a5014f36c10bac30e6f90f78"
integrity sha512-WP7uyf8Ujd2ONOIYLG6s3oIl8/IWpI2H12r7rwNG+yD8EOhvHdK8QS9+b5gpAewYJjT4r2AV8m9QJXZChmmO6w==
dependencies:
"@babel/standalone" "^7.0.0"
bootstrap-vue "2.18.1"