Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-12-08 00:11:45 +00:00
parent 2cf4bdd0b0
commit 6352d2f7c2
24 changed files with 276 additions and 166 deletions

View File

@ -1,6 +1,6 @@
include:
- project: gitlab-org/quality/pipeline-common
ref: 7.13.3
ref: 8.0.0
file:
- /ci/danger-review.yml

View File

@ -1 +1 @@
b8fda37aff7f658c1b0195fd36cefc93fa3bb718
fd52f0c5d44c30584f934ea7774d4024654b63a3

View File

@ -1,5 +1,5 @@
<script>
import { GlSearchBoxByClick, GlButton } from '@gitlab/ui';
import { GlSearchBoxByType, GlButton } from '@gitlab/ui';
// eslint-disable-next-line no-restricted-imports
import { mapState, mapActions } from 'vuex';
import { s__ } from '~/locale';
@ -22,7 +22,7 @@ export default {
},
components: {
GlButton,
GlSearchBoxByClick,
GlSearchBoxByType,
GroupFilter,
ProjectFilter,
MarkdownDrawer,
@ -87,53 +87,47 @@ export default {
<template>
<section>
<div class="gl-display-flex gl-flex-wrap gl-justify-content-end gl-pt-6 gl-pb-5">
<div class="gl-lg-display-flex gl-flex-direction-row gl-justify-content-space-between gl-pt-5">
<template v-if="showSyntaxOptions">
<div class="gl-pb-6">
<gl-button
category="tertiary"
variant="link"
size="small"
button-text-classes="gl-font-sm!"
@click="onToggleDrawer"
>{{ $options.i18n.syntaxOptionsLabel }}
</gl-button>
</div>
<markdown-drawer ref="markdownDrawer" :document-path="documentBasedOnSearchType" />
</template>
<search-type-indicator />
</div>
<div class="gl-p-5 gl-bg-gray-10 gl-border-b gl-border-t">
<div class="search-page-form gl-lg-display-flex gl-flex-direction-column">
<div class="gl-lg-display-flex gl-flex-direction-row gl-align-items-flex-end">
<div class="gl-flex-grow-1 gl-mb-4 gl-lg-mb-0 gl-lg-mr-2">
<div
class="gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-mb-0 gl-md-mb-4"
>
<label class="gl-mb-1 gl-md-pb-2">{{ $options.i18n.searchLabel }}</label>
<template v-if="showSyntaxOptions">
<gl-button
category="tertiary"
variant="link"
size="small"
button-text-classes="gl-font-sm!"
@click="onToggleDrawer"
>{{ $options.i18n.syntaxOptionsLabel }}
</gl-button>
<markdown-drawer ref="markdownDrawer" :document-path="documentBasedOnSearchType" />
</template>
</div>
<gl-search-box-by-click
id="dashboard_search"
v-model="search"
name="search"
:placeholder="$options.i18n.searchPlaceholder"
@submit="applyQuery"
/>
</div>
<div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-3 gl-min-w-20">
<label id="groupfilterDropdown" class="gl-display-block gl-mb-1 gl-md-pb-2">{{
$options.i18n.groupFieldLabel
}}</label>
<group-filter label-id="groupfilterDropdown" :group-initial-json="groupInitialJson" />
</div>
<div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-ml-3 gl-min-w-20">
<label id="projectfilterDropdown" class="gl-display-block gl-mb-1 gl-md-pb-2">{{
$options.i18n.projectFieldLabel
}}</label>
<project-filter
label-id="projectfilterDropdown"
:project-initial-json="projectInitialJson"
/>
</div>
</div>
<div class="search-page-form gl-lg-display-flex gl-flex-direction-row gl-align-items-flex-end">
<div class="gl-flex-grow-1 gl-lg-mb-0 gl-lg-mr-2">
<gl-search-box-by-type
id="dashboard_search"
v-model="search"
name="search"
:placeholder="$options.i18n.searchPlaceholder"
@submit="applyQuery"
@keydown.enter.stop.prevent="applyQuery"
/>
</div>
<div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-3 gl-min-w-20">
<label id="groupfilterDropdown" class="gl-display-block gl-mb-1 gl-md-pb-2">{{
$options.i18n.groupFieldLabel
}}</label>
<group-filter label-id="groupfilterDropdown" :group-initial-json="groupInitialJson" />
</div>
<div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-ml-3 gl-min-w-20">
<label id="projectfilterDropdown" class="gl-display-block gl-mb-1 gl-md-pb-2">{{
$options.i18n.projectFieldLabel
}}</label>
<project-filter
label-id="projectfilterDropdown"
:project-initial-json="projectInitialJson"
/>
</div>
</div>
</section>

View File

@ -75,7 +75,6 @@ export default {
searchInProgress: false,
};
},
computed: {},
watch: {
items() {
if (this.searchText === '') {

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
class RemoveUseLegacyWebIdeColumn < Gitlab::Database::Migration[2.2]
milestone '16.7'
enable_lock_retries!
def up
remove_column :user_preferences, :use_legacy_web_ide
end
def down
add_column :user_preferences, :use_legacy_web_ide, :boolean, default: false, null: false
end
end

View File

@ -0,0 +1 @@
f425d63a9d6a474162cb59cf0aea0d0d56cd38e30cb32fde8387ca9e247187c9

View File

@ -24653,7 +24653,6 @@ CREATE TABLE user_preferences (
diffs_deletion_color text,
diffs_addition_color text,
markdown_automatic_lists boolean DEFAULT true NOT NULL,
use_legacy_web_ide boolean DEFAULT false NOT NULL,
use_new_navigation boolean,
achievements_enabled boolean DEFAULT true NOT NULL,
pinned_nav_items jsonb DEFAULT '{}'::jsonb NOT NULL,

View File

@ -198,7 +198,7 @@ http://secondary.example.com/
Last status report was: 1 minute ago
```
There are up to three statuses for each item. For example, for `Project Repositories`, you see the following lines:
Each item can have up to three statuses. For example, for `Project Repositories`, you see the following lines:
```plaintext
Project Repositories: succeeded 12345 / total 12345 (100%)
@ -738,16 +738,75 @@ If large repositories are affected by this problem,
their resync may take a long time and cause significant load on your Geo sites,
storage and network systems.
If you see the error message `Synchronization failed - Error syncing repository` along with `fatal: fsck error in packed object`, this indicates
a consistency check error when syncing the repository.
The following error message indicates a consistency check error when syncing the repository:
One example of a consistency error is: `error: object f4a87a3be694fbbd6e50a668a31a8513caeaafe3: hasDotgit: contains '.git`.
```plaintext
Synchronization failed - Error syncing repository [..] fatal: fsck error in packed object
```
Removing the malformed objects causing consistency errors require rewriting the repository history, which is not always an option. However,
it's possible to override the consistency checks instead. To do that, follow
[the instructions in the Gitaly docs](../../gitaly/configure_gitaly.md#repository-consistency-checks).
Several issues can trigger this error. For example, problems with email addresses:
You can also get the error message `Synchronization failed - Error syncing repository` along with the following log messages, this indicates that the expected `geo` remote is not present in the `.git/config` file
```plaintext
Error syncing repository: 13:fetch remote: "error: object <SHA>: badEmail: invalid author/committer line - bad email
fatal: fsck error in packed object
fatal: fetch-pack: invalid index-pack output
```
Another issue that can trigger this error is `object <SHA>: hasDotgit: contains '.git'`. Check the specific errors because you might have more than one problem across all
your repositories.
A second synchronization error can also be caused by repository check issues:
```plaintext
Error syncing repository: 13:Received RST_STREAM with error code 2.
```
These errors can be observed by [immediately syncing all failed repositories](#sync-all-failed-repositories-now).
Removing the malformed objects causing consistency errors involves rewriting the repository history, which is usually not an option.
To ignore these consistency checks, reconfigure Gitaly **on the secondary Geo sites** to ignore these `git fsck` issues.
The following configuration example:
- [Uses the new configuration structure](../../../update/versions/gitlab_16_changes.md#gitaly-configuration-structure-change) required from GitLab 16.0.
- Ignores five common check failures.
[The Gitaly documentation has more details](../../gitaly/configure_gitaly.md#repository-consistency-checks)
about other Git check failures and older versions of GitLab.
```ruby
gitaly['configuration'] = {
git: {
config: [
{ key: "fsck.duplicateEntries", value: "ignore" },
{ key: "fsck.badFilemode", value: "ignore" },
{ key: "fsck.missingEmail", value: "ignore" },
{ key: "fsck.badEmail", value: "ignore" },
{ key: "fsck.hasDotgit", value: "ignore" },
{ key: "fetch.fsck.duplicateEntries", value: "ignore" },
{ key: "fetch.fsck.badFilemode", value: "ignore" },
{ key: "fetch.fsck.missingEmail", value: "ignore" },
{ key: "fetch.fsck.badEmail", value: "ignore" },
{ key: "fetch.fsck.hasDotgit", value: "ignore" },
{ key: "receive.fsck.duplicateEntries", value: "ignore" },
{ key: "receive.fsck.badFilemode", value: "ignore" },
{ key: "receive.fsck.missingEmail", value: "ignore" },
{ key: "receive.fsck.badEmail", value: "ignore" },
{ key: "receive.fsck.hasDotgit", value: "ignore" },
],
},
}
```
GitLab 16.1 and later [include an enhancement](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/5879) that might resolve some of these issues.
[Gitaly issue 5625](https://gitlab.com/gitlab-org/gitaly/-/issues/5625) proposes to ensure that Geo replicates repositories even if the source repository contains
problematic commits.
#### Related error `does not appear to be a git repository`
You can also get the error message `Synchronization failed - Error syncing repository` along with the following log messages.
This error indicates that the expected Geo remote is not present in the `.git/config` file
of a repository on the secondary Geo site's file system:
```json
@ -965,6 +1024,11 @@ The following script:
- Displays the project details and the reasons for the last failure.
- Attempts to resync the repository.
- Reports back if a failure occurs, and why.
- Might take some time to complete. Each repository check must complete
before reporting back the result. If your session times out, take measures
to allow the process to continue running such as starting a `screen` session,
or running it using [Rails runner](../../operations/rails_console.md#using-the-rails-runner)
and `nohup`.
```ruby
Geo::ProjectRegistry.sync_failed('repository').find_each do |p|

View File

@ -21278,6 +21278,7 @@ Represents a member role.
| <a id="memberroleenabledpermissions"></a>`enabledPermissions` **{warning-solid}** | [`[MemberRolePermission!]`](#memberrolepermission) | **Introduced** in 16.5. This feature is an Experiment. It can be changed or removed at any time. Array of all permissions enabled for the custom role. |
| <a id="memberroleid"></a>`id` | [`MemberRoleID!`](#memberroleid) | ID of the member role. |
| <a id="memberrolemanageprojectaccesstokens"></a>`manageProjectAccessTokens` **{warning-solid}** | [`Boolean`](#boolean) | **Introduced** in 16.5. This feature is an Experiment. It can be changed or removed at any time. Permission to admin project access tokens. |
| <a id="memberrolememberscount"></a>`membersCount` **{warning-solid}** | [`Int!`](#int) | **Introduced** in 16.7. This feature is an Experiment. It can be changed or removed at any time. Total number of members with the custom role. |
| <a id="memberrolename"></a>`name` | [`String!`](#string) | Name of the member role. |
| <a id="memberrolereadcode"></a>`readCode` **{warning-solid}** | [`Boolean`](#boolean) | **Introduced** in 16.5. This feature is an Experiment. It can be changed or removed at any time. Permission to read code. |
| <a id="memberrolereaddependency"></a>`readDependency` **{warning-solid}** | [`Boolean`](#boolean) | **Introduced** in 16.5. This feature is an Experiment. It can be changed or removed at any time. Permission to read dependency. |

View File

@ -1,7 +1,7 @@
---
status: proposed
creation-date: "2023-10-10"
authors: [ "@thomasrandolph", "@patrickbajao", "@igor.drozdov", "@jerasmus", "@iamphill" ]
authors: [ "@thomasrandolph", "@patrickbajao", "@igor.drozdov", "@jerasmus", "@iamphill", "@slashmanov" ]
coach: [ "@ntepluhina" ]
approvers: [ ]
owning-stage: "~devops::create"
@ -55,16 +55,34 @@ In essence, we'll strive to meet every goal at each decision but prioritise the
## Proposal
<!--
This is where we get down to the specifics of what the proposal actually is,
but keep it simple! This should have enough detail that reviewers can
understand exactly what you're proposing, but should not include things like
API designs or implementation. The "Design Details" section below is for the
real nitty-gritty.
New diffs introduce a paradigm shift in our approach to rendering diffs.
Previously, we had two different approaches to rendering diffs:
You might want to consider including the pros and cons of the proposed solution so that they can be
compared with the pros and cons of alternatives.
-->
1. Merge requests heavily utilized client-side rendering.
1. All other pages used server-side rendering with sprinkles of JavaScript.
In merge requests, most of the rendering work was done on the client:
- The backend would only generate a JSON response with diffs data.
- The client would be responsible for both drawing the diffs and reacting to user input.
This led to us adopting a
[virtualized scrolling solution](https://github.com/Akryum/vue-virtual-scroller/tree/v1/packages/vue-virtual-scroller)
for client-side rendering, which sped up drawing large diff file lists significantly.
Unfortunately, this came with downsides of a very high maintenance cost and
[constant bugs](https://gitlab.com/gitlab-org/gitlab/-/issues/427155#note_1607184794).
The user experience also suffered because we couldn't show diffs right away
when you visited a page, and had to wait for the JSON response first.
Lastly, this approach went completely parallel to the server-rendered diffs used on other pages,
which resulted in two completely separate codebases for the diffs.
The new-diffs approach changes that by doing the following:
1. Stop using virtualized scrolling for rendering diffs.
1. Move most of the rendering work to the server.
1. Enhance server-rendered HTML on the client.
1. Unify diffs codebase across merge requests and other pages.
### Accessibility
@ -122,6 +140,42 @@ To measure our success, we need to set meaningful metrics. These metrics should
---
<sup>1</sup>: [The Performance Inequality Gap, 2023](https://infrequently.org/2022/12/performance-baseline-2023/)
### New architecture overview
New diffs introduce a change in responsibilities for both frontend and backend.
The backend will:
1. Prepare diffs data.
1. Highlight diff lines.
1. Render diffs as HTML.
1. Embed diffs metadata into the final response.
The frontend will:
1. Enhance existing and future diffs HTML.
1. Fetch and render additional diffs HTML that didn't fit into the page document.
#### Static and dynamic separation
To achieve the separation of concerns, we should distinguish between static and dynamic UI on the page:
- Everything that is static should always be rendered on the server.
- Everything dynamic should be enhanced on the client.
As an example: a highlighted diff line doesn't change with user input, so we should consider rendering it on the server.
#### Performance optimizations
To improve the perceived performance of the page we should implement the following techniques:
1. Limit the number of diffs rendered on the page at first.
1. Use [HTML streaming](https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/101)
to render the rest of the diffs.
1. Use Web Components to hook into diff files appearing on the page.
1. Apply `content-visibility` whenever possible to reduce redraw overhead.
1. Render diff discussions asynchronously.
### Front end
#### High-level implementation

View File

@ -77,7 +77,8 @@ Notifications and mentions can be disabled in
When you mention a group in a comment, every member of the group gets a to-do item
added to their To-do list.
1. Open the MR or issue.
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Issues** or **Merge requests**, and find your issue or merge request.
1. In a comment, type `@` followed by the user, group, or subgroup namespace.
For example, `@alex`, `@alex-team`, or `@alex-team/marketing`.
1. Select **Comment**.
@ -96,8 +97,9 @@ persist, even when you:
To add a commit diff comment:
1. To select a specific commit, on the merge request, select the **Commits** tab, select the commit
message. To view the latest commit, select the **Changes** tab.
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Merge requests**, and find your merge request.
1. Select the **Commits** tab, then select the commit message.
1. By the line you want to comment on, hover over the line number and select **Comment** (**{comment}**).
You can select multiple lines by dragging the **Comment** (**{comment}**) icon.
1. Enter your comment and select **Start a review** or **Add comment now**.
@ -157,10 +159,11 @@ Prerequisites:
To lock an issue or merge request:
1. On the right sidebar, next to **Lock discussion**, select **Edit**.
1. On the confirmation dialog, select **Lock**.
1. On the left sidebar, select **Search or go to** and find your project.
1. Select **Issues** or **Merge requests**, and find your issue or merge request.
1. On the top right, select **Merge request actions** or **Issue actions** (**{ellipsis_v}**), then select **Lock discussion**.
Notes are added to the page details.
A system note is added to the page details.
If an issue or merge request is closed with a locked discussion, then you cannot reopen it until the discussion is unlocked.
@ -189,7 +192,7 @@ Prerequisites:
To add an internal note:
1. Start adding a new comment.
1. On the issue or epic, in the **Comment** text box, type a comment.
1. Below the comment, select the **Make this an internal note** checkbox.
1. Select **Add internal note**.
@ -204,7 +207,7 @@ changes ([system notes](../project/system_notes.md)). System notes include chang
objects, or changes to labels, assignees, and the milestone.
GitLab saves your preference, and applies it to every issue, merge request, or epic you view.
1. Open the **Overview** tab in a merge request, issue, or epic.
1. On a merge request, issue, or epic, select the **Overview** tab.
1. On the right side of the page, from the **Sort or filter** dropdown list, select a filter:
- **Show all activity**: Display all user comments and system notes.
- **Show comments only**: Display only user comments.

View File

@ -92,6 +92,7 @@ module Gitlab
# If a newer pipeline already build a PagesDeployment
def validate_outdated_sha
return if latest?
return if latest_pipeline_id.blank?
return if latest_pipeline_id <= build.pipeline_id
errors.add(:base, 'build SHA is outdated for this ref')

View File

@ -18,7 +18,6 @@ QA::Runtime::Browser.configure!
QA::Specs::Helpers::FeatureSetup.configure!
QA::Runtime::AllureReport.configure!
QA::Runtime::Scenario.from_env(QA::Runtime::Env.runtime_scenario_attributes)
QA::Support::KnapsackReport.configure!
QA::Service::DockerRun::Video.configure!
# Enable zero monkey patching mode before loading any other RSpec code.

View File

@ -58,16 +58,6 @@ module QA
File.write(selective_path, filtered_timed_specs.to_json)
end
# Add '-selective-parallel' suffix to report name
#
# @return [String]
def selective_path
extension = File.extname(report_path)
directory = File.dirname(report_path)
file_name = File.basename(report_path, extension)
File.join(directory, "#{file_name}-selective-parallel#{extension}")
end
# Rename and move new regenerated report to a separate folder used to indicate report name
#
# @return [void]
@ -103,7 +93,7 @@ module QA
report = jsons
.map { |json| JSON.parse(File.read(json)) }
.reduce({}, :merge)
.sort_by { |k, v| v } # sort report by execution time
.sort_by { |_k, v| v } # sort report by execution time
.to_h
next logger.warn("Knapsack generated empty report for '#{name}', skipping upload!") if report.empty?
@ -188,6 +178,17 @@ module QA
{ google_json_key_string: json_key }
end
# Add '-selective-parallel' suffix to report name
#
# @return [String]
def selective_path
extension = File.extname(report_path)
directory = File.dirname(report_path)
file_name = File.basename(report_path, extension)
File.join(directory, "#{file_name}-selective-parallel#{extension}")
end
end
end
end

View File

@ -24,16 +24,9 @@ RSpec.describe QA::Support::KnapsackReport do
end
it 'creates a filtered file based on qa_tests' do
expect(File).to receive(:write)
.with('knapsack/instance-selective-parallel.json', expected_output.to_json)
expect(File).to receive(:write).with('knapsack/instance-selective-parallel.json', expected_output.to_json)
knapsack_report.create_for_selective(qa_tests)
end
end
describe '#selective_path' do
it 'returns the path with file name suffixed with -selective-parallel' do
expect(knapsack_report.selective_path).to eq('knapsack/instance-selective-parallel.json')
end
end
end

View File

@ -53,8 +53,8 @@ RSpec.describe 'User searches for code', :js, :disable_rate_limiter, feature_cat
let(:expected_result) { 'Update capybara, rspec-rails, poltergeist to recent versions' }
before do
fill_in('dashboard_search', with: 'rspec')
find('.gl-search-box-by-click-search-button').click
submit_dashboard_search('rspec')
select_search_scope('Code')
end
it 'finds code and links to blob' do
@ -81,8 +81,8 @@ RSpec.describe 'User searches for code', :js, :disable_rate_limiter, feature_cat
search = 'for naming files'
ref_selector = 'v1.0.0'
fill_in('dashboard_search', with: search)
find('.gl-search-box-by-click-search-button').click
submit_dashboard_search(search)
select_search_scope('Code')
expect(page).to have_selector('.results', text: expected_result)
@ -99,52 +99,6 @@ RSpec.describe 'User searches for code', :js, :disable_rate_limiter, feature_cat
end
end
context 'when header search' do
context 'search code within refs' do
let(:ref_name) { 'v1.0.0' }
before do
visit(project_tree_path(project, ref_name))
submit_search('gitlab-grack')
wait_for_requests
select_search_scope('Code')
end
it 'shows ref switcher in code result summary' do
expect(find('.ref-selector')).to have_text(ref_name)
end
it 'persists branch name across search' do
find('.gl-search-box-by-click-search-button').click
expect(find('.ref-selector')).to have_text(ref_name)
end
# this example is use to test the design that the refs is not
# only represent the branch as well as the tags.
it 'ref switcher list all the branches and tags' do
find('.ref-selector').click
wait_for_requests
page.within('.ref-selector') do
expect(page).to have_selector('li', text: 'add-ipython-files')
expect(page).to have_selector('li', text: 'v1.0.0')
end
end
it 'search result changes when refs switched' do
expect(find('.results')).not_to have_content('path = gitlab-grack')
find('.ref-selector').click
wait_for_requests
select_listbox_item('add-ipython-files')
expect(page).to have_selector('.results', text: 'path = gitlab-grack')
end
end
end
it 'no ref switcher shown in issue result summary' do
issue = create(:issue, title: 'test', project: project)
visit(project_tree_path(project))

View File

@ -11,8 +11,7 @@ RSpec.describe 'User searches for issues', :js, :clean_gitlab_redis_rate_limitin
let!(:issue2) { create(:issue, :closed, :confidential, title: 'issue Bar', project: project) }
def search_for_issue(search)
fill_in('dashboard_search', with: search)
find('.gl-search-box-by-click-search-button').click
submit_dashboard_search(search)
select_search_scope('Issues')
end

View File

@ -10,8 +10,7 @@ RSpec.describe 'User searches for merge requests', :js, :clean_gitlab_redis_rate
let_it_be(:merge_request2) { create(:merge_request, :simple, title: 'Merge Request Bar', source_project: project, target_project: project) }
def search_for_mr(search)
fill_in('dashboard_search', with: search)
find('.gl-search-box-by-click-search-button').click
submit_dashboard_search(search)
select_search_scope('Merge requests')
end

View File

@ -21,8 +21,7 @@ RSpec.describe 'User searches for milestones', :js, :clean_gitlab_redis_rate_lim
include_examples 'search timeouts', 'milestones'
it 'finds a milestone' do
fill_in('dashboard_search', with: milestone1.title)
find('.gl-search-box-by-click-search-button').click
submit_dashboard_search(milestone1.title)
select_search_scope('Milestones')
page.within('.results') do
@ -41,8 +40,7 @@ RSpec.describe 'User searches for milestones', :js, :clean_gitlab_redis_rate_lim
select_listbox_item project.name
end
fill_in('dashboard_search', with: milestone1.title)
find('.gl-search-box-by-click-search-button').click
submit_dashboard_search(milestone1.title)
select_search_scope('Milestones')
page.within('.results') do

View File

@ -16,9 +16,7 @@ RSpec.describe 'User searches for projects', :js, :disable_rate_limiter, feature
it 'finds a project' do
visit(search_path)
fill_in('dashboard_search', with: project.name[0..3])
click_button('Search')
submit_dashboard_search(project.name[0..3])
expect(page).to have_link(project.name)
end
@ -26,7 +24,7 @@ RSpec.describe 'User searches for projects', :js, :disable_rate_limiter, feature
it 'preserves the group being searched in' do
visit(search_path(group_id: project.namespace.id))
submit_search('foo')
submit_dashboard_search('foo')
expect(find('#group_id', visible: false).value).to eq(project.namespace.id.to_s)
end
@ -34,7 +32,7 @@ RSpec.describe 'User searches for projects', :js, :disable_rate_limiter, feature
it 'preserves the project being searched in' do
visit(search_path(project_id: project.id))
submit_search('foo')
submit_dashboard_search('foo')
expect(find('#project_id', visible: false).value).to eq(project.id.to_s)
end

View File

@ -33,8 +33,7 @@ RSpec.describe 'User searches for wiki pages', :js, :clean_gitlab_redis_rate_lim
select_listbox_item project.name
end
fill_in('dashboard_search', with: search_term)
find('.gl-search-box-by-click-search-button').click
submit_dashboard_search(search_term)
select_search_scope('Wiki')
page.within('.results') do

View File

@ -1,4 +1,4 @@
import { GlSearchBoxByClick, GlButton } from '@gitlab/ui';
import { GlSearchBoxByType, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
// eslint-disable-next-line no-restricted-imports
@ -43,7 +43,7 @@ describe('GlobalSearchTopbar', () => {
});
};
const findGlSearchBox = () => wrapper.findComponent(GlSearchBoxByClick);
const findGlSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
const findGroupFilter = () => wrapper.findComponent(GroupFilter);
const findProjectFilter = () => wrapper.findComponent(ProjectFilter);
const findSyntaxOptionButton = () => wrapper.findComponent(GlButton);

View File

@ -5,8 +5,8 @@ require 'spec_helper'
RSpec.describe Gitlab::Pages::DeploymentUpdate, feature_category: :pages do
let_it_be(:project, refind: true) { create(:project, :repository) }
let_it_be(:old_pipeline) { create(:ci_pipeline, project: project, sha: project.commit('HEAD').sha) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit('HEAD').sha) }
let_it_be(:old_pipeline) { create(:ci_pipeline, project: project, sha: project.commit('HEAD~~').sha) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit('HEAD~').sha) }
let(:build) { create(:ci_build, pipeline: pipeline, ref: 'HEAD') }
let(:invalid_file) { fixture_file_upload('spec/fixtures/dk.png') }
@ -137,4 +137,35 @@ RSpec.describe Gitlab::Pages::DeploymentUpdate, feature_category: :pages do
expect(pages_deployment_update).to be_valid
end
end
context 'when validating if current build is outdated' do
before do
create(:ci_job_artifact, :correct_checksum, file: file, job: build)
create(:ci_job_artifact, file_type: :metadata, file_format: :gzip, file: metadata, job: build)
build.reload
end
context 'when there is NOT a newer build' do
it 'does not fail' do
expect(pages_deployment_update).to be_valid
end
end
context 'when there is a newer build' do
before do
new_pipeline = create(:ci_pipeline, project: project, sha: project.commit('HEAD').sha)
new_build = create(:ci_build, name: 'pages', pipeline: new_pipeline, ref: 'HEAD')
create(:ci_job_artifact, :correct_checksum, file: file, job: new_build)
create(:ci_job_artifact, file_type: :metadata, file_format: :gzip, file: metadata, job: new_build)
create(:pages_deployment, project: project, ci_build: new_build)
new_build.reload
end
it 'fails with outdated reference message' do
expect(pages_deployment_update).not_to be_valid
expect(pages_deployment_update.errors.full_messages)
.to include('build SHA is outdated for this ref')
end
end
end
end

View File

@ -35,6 +35,15 @@ module SearchHelpers
end
end
def submit_dashboard_search(query)
visit(search_path) unless page.has_css?('#dashboard_search')
search_form = page.find('input[name="search"]', match: :first)
search_form.fill_in(with: query)
search_form.send_keys(:enter)
end
def select_search_scope(scope)
within_testid('search-filter') do
click_link scope