Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
2cf4bdd0b0
commit
6352d2f7c2
|
|
@ -1,6 +1,6 @@
|
|||
include:
|
||||
- project: gitlab-org/quality/pipeline-common
|
||||
ref: 7.13.3
|
||||
ref: 8.0.0
|
||||
file:
|
||||
- /ci/danger-review.yml
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
b8fda37aff7f658c1b0195fd36cefc93fa3bb718
|
||||
fd52f0c5d44c30584f934ea7774d4024654b63a3
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ export default {
|
|||
searchInProgress: false,
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
watch: {
|
||||
items() {
|
||||
if (this.searchText === '') {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
f425d63a9d6a474162cb59cf0aea0d0d56cd38e30cb32fde8387ca9e247187c9
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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|
|
||||
|
|
|
|||
|
|
@ -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. |
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue