Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-05-07 15:10:39 +00:00
parent 53f456b167
commit 05b83be3ee
39 changed files with 578 additions and 173 deletions

View file

@ -1,6 +1,6 @@
<script>
import { GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui';
import { mapActions, mapGetters } from 'vuex';
import { mapActions, mapGetters, mapState } from 'vuex';
import PreviewItem from './preview_item.vue';
export default {
@ -11,13 +11,22 @@ export default {
PreviewItem,
},
computed: {
...mapState('diffs', ['viewDiffsFileByFile']),
...mapGetters('batchComments', ['draftsCount', 'sortedDrafts']),
},
methods: {
...mapActions('diffs', ['toggleActiveFileByHash']),
...mapActions('batchComments', ['scrollToDraft']),
isLast(index) {
return index === this.sortedDrafts.length - 1;
},
async onClickDraft(draft) {
if (this.viewDiffsFileByFile && draft.file_hash) {
await this.toggleActiveFileByHash(draft.file_hash);
}
await this.scrollToDraft(draft);
},
},
};
</script>
@ -35,7 +44,8 @@ export default {
<gl-dropdown-item
v-for="(draft, index) in sortedDrafts"
:key="draft.id"
@click="scrollToDraft(draft)"
data-testid="preview-item"
@click="onClickDraft(draft)"
>
<preview-item :draft="draft" :is-last="isLast(index)" />
</gl-dropdown-item>

View file

@ -45,7 +45,7 @@ export default {
this.tiptapEditor.chain()[this.editorCommand]().focus().run();
}
this.$emit('click', { contentType });
this.$emit('execute', { contentType });
},
},
};

View file

@ -1,19 +1,34 @@
<script>
import Tracking from '~/tracking';
import { CONTENT_EDITOR_TRACKING_LABEL, TOOLBAR_CONTROL_TRACKING_ACTION } from '../constants';
import { ContentEditor } from '../services/content_editor';
import Divider from './divider.vue';
import ToolbarButton from './toolbar_button.vue';
const trackingMixin = Tracking.mixin({
label: CONTENT_EDITOR_TRACKING_LABEL,
});
export default {
components: {
ToolbarButton,
Divider,
},
mixins: [trackingMixin],
props: {
contentEditor: {
type: ContentEditor,
required: true,
},
},
methods: {
trackToolbarControlExecution({ contentType: property, value }) {
this.track(TOOLBAR_CONTROL_TRACKING_ACTION, {
property,
value,
});
},
},
};
</script>
<template>
@ -27,6 +42,7 @@ export default {
editor-command="toggleBold"
:label="__('Bold text')"
:tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
data-testid="italic"
@ -35,6 +51,7 @@ export default {
editor-command="toggleItalic"
:label="__('Italic text')"
:tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
data-testid="code"
@ -43,6 +60,7 @@ export default {
editor-command="toggleCode"
:label="__('Code')"
:tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/>
<divider />
<toolbar-button
@ -52,6 +70,7 @@ export default {
editor-command="toggleBlockquote"
:label="__('Insert a quote')"
:tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
data-testid="bullet-list"
@ -60,6 +79,7 @@ export default {
editor-command="toggleBulletList"
:label="__('Add a bullet list')"
:tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/>
<toolbar-button
data-testid="ordered-list"
@ -68,6 +88,7 @@ export default {
editor-command="toggleOrderedList"
:label="__('Add a numbered list')"
:tiptap-editor="contentEditor.tiptapEditor"
@execute="trackToolbarControlExecution"
/>
</div>
</template>

View file

@ -3,3 +3,6 @@ import { s__ } from '~/locale';
export const PROVIDE_SERIALIZER_OR_RENDERER_ERROR = s__(
'ContentEditor|You have to provide a renderMarkdown function or a custom serializer',
);
export const CONTENT_EDITOR_TRACKING_LABEL = 'content_editor';
export const TOOLBAR_CONTROL_TRACKING_ACTION = 'execute_toolbar_control';

View file

@ -173,7 +173,7 @@ export default {
<pre
v-if="commit.description_html"
:class="{ 'js-toggle-content': collapsible, 'd-block': !collapsible }"
class="commit-row-description gl-mb-3 text-dark"
class="commit-row-description gl-mb-3 gl-text-body"
v-html="commitDescription"
></pre>
</div>

View file

@ -645,9 +645,6 @@ export const convertObjectPropsToCamelCase = (obj = {}, options = {}) =>
export const convertObjectPropsToSnakeCase = (obj = {}, options = {}) =>
convertObjectProps(convertToSnakeCase, obj, options);
export const imagePath = (imgUrl) =>
`${gon.asset_host || ''}${gon.relative_url_root || ''}/assets/${imgUrl}`;
export const addSelectOnFocusBehaviour = (selector = '.js-select-on-focus') => {
// Click a .js-select-on-focus field, select the contents
// Prevent a mouseup event from deselecting the input

View file

@ -105,8 +105,6 @@ module Ci
end
def valid_local?
return true unless Gitlab::Ci::Features.validate_build_dependencies?(project)
local.all?(&:valid_dependency?)
end

View file

@ -65,7 +65,8 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
:tags: []
:tags:
- :exclude_from_gitlab_com
- :name: chaos:chaos_db_spin
:worker_name: Chaos::DbSpinWorker
:feature_category: :not_owned
@ -74,7 +75,8 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
:tags: []
:tags:
- :exclude_from_gitlab_com
- :name: chaos:chaos_kill
:worker_name: Chaos::KillWorker
:feature_category: :not_owned
@ -83,7 +85,8 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
:tags: []
:tags:
- :exclude_from_gitlab_com
- :name: chaos:chaos_leak_mem
:worker_name: Chaos::LeakMemWorker
:feature_category: :not_owned
@ -92,7 +95,8 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
:tags: []
:tags:
- :exclude_from_gitlab_com
- :name: chaos:chaos_sleep
:worker_name: Chaos::SleepWorker
:feature_category: :not_owned
@ -101,7 +105,8 @@
:resource_boundary: :unknown
:weight: 2
:idempotent:
:tags: []
:tags:
- :exclude_from_gitlab_com
- :name: container_repository:cleanup_container_repository
:worker_name: CleanupContainerRepositoryWorker
:feature_category: :container_registry
@ -1014,7 +1019,8 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
:tags: []
:tags:
- :exclude_from_gitlab_com
- :name: hashed_storage:hashed_storage_project_migrate
:worker_name: HashedStorage::ProjectMigrateWorker
:feature_category: :source_code_management
@ -1023,7 +1029,8 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
:tags: []
:tags:
- :exclude_from_gitlab_com
- :name: hashed_storage:hashed_storage_project_rollback
:worker_name: HashedStorage::ProjectRollbackWorker
:feature_category: :source_code_management
@ -1032,7 +1039,8 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
:tags: []
:tags:
- :exclude_from_gitlab_com
- :name: hashed_storage:hashed_storage_rollbacker
:worker_name: HashedStorage::RollbackerWorker
:feature_category: :source_code_management
@ -1041,7 +1049,8 @@
:resource_boundary: :unknown
:weight: 1
:idempotent:
:tags: []
:tags:
- :exclude_from_gitlab_com
- :name: incident_management:clusters_applications_check_prometheus_health
:worker_name: Clusters::Applications::CheckPrometheusHealthWorker
:feature_category: :incident_management

View file

@ -6,5 +6,6 @@ module ChaosQueue
included do
queue_namespace :chaos
feature_category_not_owned!
tags :exclude_from_gitlab_com
end
end

View file

@ -8,6 +8,7 @@ module HashedStorage
queue_namespace :hashed_storage
feature_category :source_code_management
tags :exclude_from_gitlab_com
# @param [Integer] start initial ID of the batch
# @param [Integer] finish last ID of the batch

View file

@ -8,6 +8,7 @@ module HashedStorage
queue_namespace :hashed_storage
loggable_arguments 1
tags :exclude_from_gitlab_com
attr_reader :project_id

View file

@ -8,6 +8,7 @@ module HashedStorage
queue_namespace :hashed_storage
loggable_arguments 1
tags :exclude_from_gitlab_com
attr_reader :project_id

View file

@ -8,6 +8,7 @@ module HashedStorage
queue_namespace :hashed_storage
feature_category :source_code_management
tags :exclude_from_gitlab_com
# @param [Integer] start initial ID of the batch
# @param [Integer] finish last ID of the batch

View file

@ -0,0 +1,5 @@
---
title: Fix commit messages text color in dark mode
merge_request: 61082
author:
type: fixed

View file

@ -0,0 +1,5 @@
---
title: Validate CI pipeline jobs dependencies
merge_request: 60999
author:
type: changed

View file

@ -0,0 +1,5 @@
---
title: Fixed preview review comment not working with single file diff mode
merge_request: 61032
author:
type: fixed

View file

@ -1,8 +0,0 @@
---
name: ci_validate_build_dependencies
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14009
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/257852
milestone: '10.3'
type: development
group: group::continuous integration
default_enabled: true

View file

@ -1,8 +0,0 @@
---
name: ci_validate_build_dependencies_override
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14009
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/257852
milestone: '10.3'
type: development
group: group::continuous integration
default_enabled: false

View file

@ -0,0 +1,5 @@
# frozen_string_literal: true
ActiveSupport.on_load(:active_record) do
ActiveRecord::ConnectionAdapters::SchemaCache.prepend(Gitlab::Database::SchemaCacheWithRenamedTable)
end

View file

@ -370,42 +370,6 @@ steps below.
If the `expire` directive is not set explicitly in your pipeline, artifacts expire per the
default artifacts expiration setting, which you can find in the [CI/CD Administration settings](../user/admin_area/settings/continuous_integration.md).
## Validation for dependencies
> Introduced in GitLab 10.3.
To disable [the dependencies validation](../ci/yaml/README.md#when-a-dependent-job-fails),
you can enable the `ci_validate_build_dependencies_override` feature flag from a Rails console.
**In Omnibus installations:**
1. Enter the Rails console:
```shell
sudo gitlab-rails console
```
1. Enable the feature flag to disable the validation:
```ruby
Feature.enable(:ci_validate_build_dependencies_override)
```
**In installations from source:**
1. Enter the Rails console:
```shell
cd /home/git/gitlab
sudo -u git -H bundle exec rails console -e production
```
1. Enable the feature flag to disable the validation:
```ruby
Feature.enable(:ci_validate_build_dependencies_override)
```
## Set the maximum file size of the artifacts
If artifacts are enabled, you can change the maximum file size of the

View file

@ -3264,10 +3264,6 @@ If the artifacts of the job that is set as a dependency are
[deleted](../pipelines/job_artifacts.md#delete-job-artifacts), then
the dependent job fails.
You can ask your administrator to
[flip this switch](../../administration/job_artifacts.md#validation-for-dependencies)
and bring back the old behavior.
#### `artifacts:exclude`
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15122) in GitLab 13.1

View file

@ -365,6 +365,12 @@ if the application no longer uses the table.
Renaming tables requires downtime as an application may continue
using the old table name during/after a database migration.
If the table and the ActiveRecord model is not in use yet, removing the old
table and creating a new one is the preferred way to "rename" the table.
Renaming a table is possible without downtime by following our multi-release
[rename table process](database/rename_database_tables.md#rename-table-without-downtime).
## Adding Foreign Keys
Adding foreign keys usually works in 3 steps:

View file

@ -0,0 +1,140 @@
---
stage: Enablement
group: Database
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
---
# Rename table without downtime
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54354) in GitLab 13.12.
With our database helper methods built into GitLab, it's possible to rename a database table without downtime.
The technique builds on top of database views, using the following steps:
1. Rename the database table.
1. Create a database view using the old table name by pointing to the new table name.
1. Add workaround for ActiveRecord's schema cache.
For example, consider that we are renaming the `issues` table name to `tickets`. Run:
```sql
BEGIN;
ALTER TABLE issues RENAME TO tickets;
CREATE VIEW issues AS SELECT * FROM tickets;
COMMIT;
```
As database views do not expose the underlying table schema (default values, not null
constraints, and indexes), we need further steps to update the application to use the new
table name. ActiveRecord heavily relies on this data, for example, to initialize new
models.
To work around this limitation, we need to tell ActiveRecord to acquire this information
from a different table using the new table name.
## Migration strategy breakdown
### Release N.M: Mark the ActiveRecord model's table
Consider the current release as "Release N.M".
In this release, register the database table so that it instructs ActiveRecord to fetch the
database table information (for `SchemaCache`) using the new table name (if it's present). Otherwise, fall back
to the old table name. This is necessary to avoid errors during a zero-downtime deployment.
1. Edit the `TABLES_TO_BE_RENAMED` constant in: `lib/gitlab/database.rb`
```ruby
TABLES_TO_BE_RENAMED = {
'issues' => 'tickets'
}.freeze
```
Note that, in this release (N.M), the `tickets` database table does not exist yet. This step is preparing for the actual table rename in release N.M+1.
### Release N.M+1: Rename the database table
Consider the next release as "Release N.M".
Execute a standard migration (not a post-migration):
```ruby
include Gitlab::Database::MigrationHelpers
def up
rename_table_safely(:issues, :tickets)
end
def down
undo_rename_table_safely(:issues, :tickets)
end
```
**Important notes:**
- Let other developers know that the table is going to be renamed.
- Ping the `@gl-database` group in your merge request.
- Add a note in the Engineering Week-in-Review document: `table_name` is going to be renamed in N.M. Modifications to this table are not allowed in release N.M and N.M+1.
- The helper method uses the standard `rename_table` helper from Rails for renaming the table.
- The helper renames the sequence and the indexes. Sometimes it diverges from the standard Rails convention
when naming indexes, so there is a possibility that not all indexes are properly renamed. After running
the migration locally, check if there are inconsistently named indexes (`db/structure.sql`). Those can be
renamed manually in a separate migration, which can be also part of the release M.N+1.
- Foreign key columns might still contain the old table name. For smaller tables, follow our [standard column
rename process](../avoiding_downtime_in_migrations.md#renaming-columns)
- Avoid renaming database tables which are using with triggers.
- Table modifications (add or remove columns) are not allowed during the rename process, please make sure that all changes to the table happen before the rename migration is started (or in the next release).
- As the index names might change, verify that the model does not use bulk insert
(for example, `insert_all` and `upsert_all`) with the `unique_by: index_name` option.
Renaming an index while using these methods may break functionality.
- Modify the model code to point to the new database table. Do this by
renaming the model directly or setting the `self.table_name` variable.
At this point, we don't have applications using the old database table name in their queries.
1. Remove the database view through a post-migration:
```ruby
include Gitlab::Database::MigrationHelpers
def up
finalize_table_rename(:issues, :tickets)
end
def down
undo_finalize_table_rename(:issues, :tickets)
end
```
1. Additionally the table definition from `TABLES_TO_BE_RENAMED` **must** be removed.
To do so, edit the `TABLES_TO_BE_RENAMED` constant in `lib/gitlab/database.rb`:
From:
```ruby
TABLES_TO_BE_RENAMED = {
'issues' => 'tickets'
}.freeze
```
To:
```ruby
TABLES_TO_BE_RENAMED = {}.freeze
```
#### Zero-downtime deployments
When the application is upgraded without downtime, there can be application instances
running the old code. The old code still references the old database table. The queries
still function without any problems, because the backward-compatible database view is
in place.
In case the old version of the application needs to be restarted or reconnected to the
database, ActiveRecord fetches the column information again. At this time, our previously
marked table (`TABLES_TO_BE_RENAMED`) instructs ActiveRecord to use the new database table name
when fetching the database table information.
The new version of the application will use the new database table.

View file

@ -316,11 +316,11 @@ choose to remove the migration code and tests so that:
anymore.
To be extra safe, we will not delete migrations that were created in the last
minor version before the major upgrade. So, if the we are upgrading to `%14.0`,
we should not delete migrations that were only added in `%13.11`. This is an
minor version before the major upgrade. So, if we are upgrading to `%14.0`,
we should not delete migrations that were only added in `%13.12`. This is an
extra safety net as we expect there are migrations that get merged that may
take multiple weeks to finish on GitLab.com. It would be bad if we upgraded
GitLab.com to `%14.0` before the migrations in `%13.11` were finished. Since
GitLab.com to `%14.0` before the migrations in `%13.12` were finished. Since
our deployments to GitLab.com are automated and we currently don't have
automated checks to prevent this, the extra precaution is warranted.
Additionally, even if we did have automated checks to prevent it, we wouldn't
@ -340,7 +340,7 @@ being upgraded to, we do the following:
def migrate
log_raise "Migration has been deleted in the last major version upgrade." \
"Migrations are supposed to be finished before upgrading major version https://docs.gitlab.com/ee/update/#upgrading-to-a-new-major-version ." \
"In order to correct this issue you will need to reacreate your index from scratch https://docs.gitlab.com/ee/integration/elasticsearch.html#last-resort-to-recreate-an-index ."
"To correct this issue, recreate your index from scratch: https://docs.gitlab.com/ee/integration/elasticsearch.html#last-resort-to-recreate-an-index."
end
def completed?

View file

@ -339,7 +339,8 @@ sudo -u git -H GITLAB_ASSUME_YES=1 bundle exec rake gitlab:backup:restore RAILS_
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37158) in GitLab 13.3.
Repositories can be backed up concurrently to help fully use CPU time. The
When using [multiple repository storages](../administration/repository_storage_paths.md),
repositories can be backed up concurrently to help fully use CPU time. The
following variables are available to modify the default behavior of the Rake
task:
@ -349,7 +350,7 @@ task:
back up at the same time on each storage. This allows the repository backups
to be spread across storages. Defaults to `1`.
For example, for Omnibus GitLab installations:
For example, for Omnibus GitLab installations with 4 repository storages:
```shell
sudo gitlab-backup create GITLAB_BACKUP_MAX_CONCURRENCY=4 GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=1

View file

@ -47,11 +47,6 @@ module Gitlab
::Feature.enabled?(:ci_trace_log_invalid_chunks, project, type: :ops, default_enabled: false)
end
def self.validate_build_dependencies?(project)
::Feature.enabled?(:ci_validate_build_dependencies, project, default_enabled: :yaml) &&
::Feature.disabled?(:ci_validate_build_dependencies_override, project)
end
def self.display_quality_on_mr_diff?(project)
::Feature.enabled?(:codequality_mr_diff, project, default_enabled: false)
end

View file

@ -2,6 +2,14 @@
module Gitlab
module Database
# This constant is used when renaming tables concurrently.
# If you plan to rename a table using the `rename_table_safely` method, add your table here one milestone before the rename.
# Example:
# TABLES_TO_BE_RENAMED = {
# 'old_name' => 'new_name'
# }.freeze
TABLES_TO_BE_RENAMED = {}.freeze
# Minimum PostgreSQL version requirement per documentation:
# https://docs.gitlab.com/ee/install/requirements.html#postgresql-requirements
MINIMUM_POSTGRES_VERSION = 11

View file

@ -5,6 +5,7 @@ module Gitlab
module MigrationHelpers
include Migrations::BackgroundMigrationHelpers
include DynamicModelHelpers
include Migrations::RenameTableHelpers
# https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
MAX_IDENTIFIER_NAME_LENGTH = 63

View file

@ -0,0 +1,33 @@
# frozen_string_literal: true
module Gitlab
module Database
module RenameTableHelpers
def rename_table_safely(old_table_name, new_table_name)
with_lock_retries do
rename_table(old_table_name, new_table_name)
execute("CREATE VIEW #{old_table_name} AS SELECT * FROM #{new_table_name}")
end
end
def undo_rename_table_safely(old_table_name, new_table_name)
with_lock_retries do
execute("DROP VIEW IF EXISTS #{old_table_name}")
rename_table(new_table_name, old_table_name)
end
end
def finalize_table_rename(old_table_name, new_table_name)
with_lock_retries do
execute("DROP VIEW IF EXISTS #{old_table_name}")
end
end
def undo_finalize_table_rename(old_table_name, new_table_name)
with_lock_retries do
execute("CREATE VIEW #{old_table_name} AS SELECT * FROM #{new_table_name}")
end
end
end
end
end

View file

@ -0,0 +1,55 @@
# frozen_string_literal: true
module Gitlab
module Database
module SchemaCacheWithRenamedTable
# Override methods in ActiveRecord::ConnectionAdapters::SchemaCache
def clear!
super
clear_renamed_tables_cache!
end
def clear_data_source_cache!(name)
super(name)
clear_renamed_tables_cache!
end
def primary_keys(table_name)
super(underlying_table(table_name))
end
def columns(table_name)
super(underlying_table(table_name))
end
def columns_hash(table_name)
super(underlying_table(table_name))
end
def indexes(table_name)
super(underlying_table(table_name))
end
private
def underlying_table(table_name)
renamed_tables_cache.fetch(table_name, table_name)
end
def renamed_tables_cache
@renamed_tables ||= begin
Gitlab::Database::TABLES_TO_BE_RENAMED.select do |old_name, new_name|
ActiveRecord::Base.connection.view_exists?(old_name)
end
end
end
def clear_renamed_tables_cache!
@renamed_tables = nil # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
end
end
end

View file

@ -5040,6 +5040,12 @@ msgstr ""
msgid "BillingPlan|Upgrade for free"
msgstr ""
msgid "Billings|As a user on a free or trial namespace, you'll need to verify your account with a credit card to run pipelines. This is required to help prevent cryptomining attacks on GitLab infrastructure. %{strongStart}GitLab will not charge or store your credit card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
msgstr ""
msgid "Billings|User Verification Required"
msgstr ""
msgid "Billings|Verify User Account"
msgstr ""
@ -11265,6 +11271,9 @@ msgstr ""
msgid "DevopsAdoption|Adopted"
msgstr ""
msgid "DevopsAdoption|Adoption"
msgstr ""
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@ -26999,6 +27008,9 @@ msgstr ""
msgid "Remove user from project"
msgstr ""
msgid "Remove..."
msgstr ""
msgid "Removed"
msgstr ""
@ -30656,15 +30668,33 @@ msgstr ""
msgid "StatusCheck|API to check"
msgstr ""
msgid "StatusCheck|Add status check"
msgstr ""
msgid "StatusCheck|An error occurred fetching the status checks."
msgstr ""
msgid "StatusCheck|Check for a status response in Merge Requests. Failures do not block merges. %{link_start}Learn more%{link_end}."
msgstr ""
msgid "StatusCheck|Invoke an external API as part of the approvals"
msgstr ""
msgid "StatusCheck|No status checks are defined yet."
msgstr ""
msgid "StatusCheck|Remove status check"
msgstr ""
msgid "StatusCheck|Remove status check?"
msgstr ""
msgid "StatusCheck|Service name"
msgstr ""
msgid "StatusCheck|Status checks"
msgstr ""
msgid "StatusCheck|Status to check"
msgstr ""
@ -31747,6 +31777,9 @@ msgstr ""
msgid "The \"Require approval from CODEOWNERS\" setting was moved to %{banner_link_start}Protected Branches%{banner_link_end}"
msgstr ""
msgid "The %{featureName} feature is part of your GitLab Ultimate trial."
msgstr ""
msgid "The %{link_start}true-up model%{link_end} allows having more users, and additional users will incur a retroactive charge on renewal."
msgstr ""
@ -38207,6 +38240,9 @@ msgid_plural "merge requests"
msgstr[0] ""
msgstr[1] ""
msgid "merge request approvals"
msgstr ""
msgid "merged %{timeAgo}"
msgstr ""

View file

@ -0,0 +1,71 @@
import Vue from 'vue';
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PreviewDropdown from '~/batch_comments/components/preview_dropdown.vue';
Vue.use(Vuex);
let wrapper;
const toggleActiveFileByHash = jest.fn();
const scrollToDraft = jest.fn();
function factory({ viewDiffsFileByFile = false, draftsCount = 1, sortedDrafts = [] } = {}) {
const store = new Vuex.Store({
modules: {
diffs: {
namespaced: true,
actions: {
toggleActiveFileByHash,
},
state: {
viewDiffsFileByFile,
},
},
batchComments: {
namespaced: true,
actions: { scrollToDraft },
getters: { draftsCount: () => draftsCount, sortedDrafts: () => sortedDrafts },
},
},
});
wrapper = shallowMountExtended(PreviewDropdown, {
store,
});
}
describe('Batch comments preview dropdown', () => {
afterEach(() => {
wrapper.destroy();
});
describe('clicking draft', () => {
it('it toggles active file when viewDiffsFileByFile is true', async () => {
factory({
viewDiffsFileByFile: true,
sortedDrafts: [{ id: 1, file_hash: 'hash' }],
});
wrapper.findByTestId('preview-item').vm.$emit('click');
await Vue.nextTick();
expect(toggleActiveFileByHash).toHaveBeenCalledWith(expect.anything(), 'hash');
expect(scrollToDraft).toHaveBeenCalledWith(expect.anything(), { id: 1, file_hash: 'hash' });
});
it('calls scrollToDraft', async () => {
factory({
viewDiffsFileByFile: false,
sortedDrafts: [{ id: 1 }],
});
wrapper.findByTestId('preview-item').vm.$emit('click');
await Vue.nextTick();
expect(scrollToDraft).toHaveBeenCalledWith(expect.anything(), { id: 1 });
});
});
});

View file

@ -83,7 +83,7 @@ describe('content_editor/components/toolbar_button', () => {
await findButton().trigger('click');
expect(toggleFooSpy).toHaveBeenCalled();
expect(wrapper.emitted().click).toHaveLength(1);
expect(wrapper.emitted().execute).toHaveLength(1);
});
it('does not executes the content type command when executeCommand = false', async () => {
@ -92,7 +92,7 @@ describe('content_editor/components/toolbar_button', () => {
await findButton().trigger('click');
expect(toggleFooSpy).not.toHaveBeenCalled();
expect(wrapper.emitted().click).toHaveLength(1);
expect(wrapper.emitted().execute).toHaveLength(1);
});
});
});

View file

@ -1,12 +1,17 @@
import { shallowMount } from '@vue/test-utils';
import { mockTracking } from 'helpers/tracking_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import TopToolbar from '~/content_editor/components/top_toolbar.vue';
import {
TOOLBAR_CONTROL_TRACKING_ACTION,
CONTENT_EDITOR_TRACKING_LABEL,
} from '~/content_editor/constants';
import { createContentEditor } from '~/content_editor/services/create_content_editor';
describe('content_editor/components/top_toolbar', () => {
let wrapper;
let contentEditor;
let trackingSpy;
const buildEditor = () => {
contentEditor = createContentEditor({ renderMarkdown: () => true });
};
@ -21,6 +26,10 @@ describe('content_editor/components/top_toolbar', () => {
);
};
beforeEach(() => {
trackingSpy = mockTracking(undefined, null, jest.spyOn);
});
beforeEach(() => {
buildEditor();
});
@ -29,7 +38,7 @@ describe('content_editor/components/top_toolbar', () => {
wrapper.destroy();
});
it.each`
describe.each`
testId | buttonProps
${'bold'} | ${{ contentType: 'bold', iconName: 'bold', label: 'Bold text', editorCommand: 'toggleBold' }}
${'italic'} | ${{ contentType: 'italic', iconName: 'italic', label: 'Italic text', editorCommand: 'toggleItalic' }}
@ -37,11 +46,31 @@ describe('content_editor/components/top_toolbar', () => {
${'blockquote'} | ${{ contentType: 'blockquote', iconName: 'quote', label: 'Insert a quote', editorCommand: 'toggleBlockquote' }}
${'bullet-list'} | ${{ contentType: 'bulletList', iconName: 'list-bulleted', label: 'Add a bullet list', editorCommand: 'toggleBulletList' }}
${'ordered-list'} | ${{ contentType: 'orderedList', iconName: 'list-numbered', label: 'Add a numbered list', editorCommand: 'toggleOrderedList' }}
`('renders $testId button', ({ testId, buttonProps }) => {
buildWrapper();
expect(wrapper.findByTestId(testId).props()).toEqual({
...buttonProps,
tiptapEditor: contentEditor.tiptapEditor,
`('given a $testId toolbar control', ({ testId, buttonProps }) => {
beforeEach(() => {
buildWrapper();
});
it('renders the toolbar control with the provided properties', () => {
expect(wrapper.findByTestId(testId).props()).toEqual({
...buttonProps,
tiptapEditor: contentEditor.tiptapEditor,
});
});
it.each`
control | eventData
${'bold'} | ${{ contentType: 'bold' }}
${'blockquote'} | ${{ contentType: 'blockquote', value: 1 }}
`('tracks the execution of toolbar controls', ({ control, eventData }) => {
const { contentType, value } = eventData;
wrapper.findByTestId(control).vm.$emit('execute', eventData);
expect(trackingSpy).toHaveBeenCalledWith(undefined, TOOLBAR_CONTROL_TRACKING_ACTION, {
label: CONTENT_EDITOR_TRACKING_LABEL,
property: contentType,
value,
});
});
});
});

View file

@ -218,15 +218,18 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
end
context 'N+1 queries' do
it 'avoids N+1 queries when calculating variables of jobs' do
it 'avoids N+1 queries when calculating variables of jobs', :use_sql_query_cache do
warm_up_pipeline, warm_up_command = prepare_pipeline1
perform_seed(warm_up_pipeline, warm_up_command)
pipeline1, command1 = prepare_pipeline1
pipeline2, command2 = prepare_pipeline2
control = ActiveRecord::QueryRecorder.new do
control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
perform_seed(pipeline1, command1)
end
expect { perform_seed(pipeline2, command2) }.not_to exceed_query_limit(
expect { perform_seed(pipeline2, command2) }.not_to exceed_all_query_limit(
control.count + expected_extra_queries
)
end

View file

@ -0,0 +1,83 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Database::SchemaCacheWithRenamedTable do
let(:old_model) do
Class.new(ActiveRecord::Base) do
self.table_name = 'projects'
end
end
let(:new_model) do
Class.new(ActiveRecord::Base) do
self.table_name = 'projects_new'
end
end
before do
stub_const('Gitlab::Database::TABLES_TO_BE_RENAMED', { 'projects' => 'projects_new' })
end
context 'when table is not renamed yet' do
before do
old_model.reset_column_information
ActiveRecord::Base.connection.schema_cache.clear!
end
it 'uses the original table to look up metadata' do
expect(old_model.primary_key).to eq('id')
end
end
context 'when table is renamed' do
before do
ActiveRecord::Base.connection.execute("ALTER TABLE projects RENAME TO projects_new")
ActiveRecord::Base.connection.execute("CREATE VIEW projects AS SELECT * FROM projects_new")
old_model.reset_column_information
ActiveRecord::Base.connection.schema_cache.clear!
end
it 'uses the renamed table to look up metadata' do
expect(old_model.primary_key).to eq('id')
end
it 'has primary key' do
expect(old_model.primary_key).to eq('id')
expect(old_model.primary_key).to eq(new_model.primary_key)
end
it 'has the same column definitions' do
expect(old_model.columns).to eq(new_model.columns)
end
it 'has the same indexes' do
indexes_for_old_table = ActiveRecord::Base.connection.schema_cache.indexes('projects')
indexes_for_new_table = ActiveRecord::Base.connection.schema_cache.indexes('projects_new')
expect(indexes_for_old_table).to eq(indexes_for_new_table)
end
it 'has the same column_hash' do
columns_hash_for_old_table = ActiveRecord::Base.connection.schema_cache.columns_hash('projects')
columns_hash_for_new_table = ActiveRecord::Base.connection.schema_cache.columns_hash('projects_new')
expect(columns_hash_for_old_table).to eq(columns_hash_for_new_table)
end
describe 'when the table behind a model is actually a view' do
let(:group) { create(:group) }
let(:project_attributes) { attributes_for(:project, namespace_id: group.id).except(:creator) }
let(:record) { old_model.create!(project_attributes) }
it 'can persist records' do
expect(record.reload.attributes).to eq(new_model.find(record.id).attributes)
end
it 'can find records' do
expect(old_model.find_by_id(record.id)).not_to be_nil
end
end
end
end

View file

@ -18,10 +18,6 @@ RSpec.describe Ci::BuildDependencies do
let!(:rubocop_test) { create(:ci_build, pipeline: pipeline, name: 'rubocop', stage_idx: 1, stage: 'test') }
let!(:staging) { create(:ci_build, pipeline: pipeline, name: 'staging', stage_idx: 2, stage: 'deploy') }
before do
stub_feature_flags(ci_validate_build_dependencies_override: false)
end
context 'for local dependencies' do
subject { described_class.new(job).all }
@ -378,14 +374,6 @@ RSpec.describe Ci::BuildDependencies do
end
it { is_expected.to eq(false) }
context 'when ci_validate_build_dependencies_override feature flag is enabled' do
before do
stub_feature_flags(ci_validate_build_dependencies_override: job.project)
end
it { is_expected.to eq(true) }
end
end
end
end

View file

@ -3631,41 +3631,24 @@ RSpec.describe Ci::Build do
end
let!(:job) { create(:ci_build, :pending, pipeline: pipeline, stage_idx: 1, options: options) }
let!(:pre_stage_job) { create(:ci_build, :success, pipeline: pipeline, name: 'test', stage_idx: 0) }
context 'when validates for dependencies is enabled' do
before do
stub_feature_flags(ci_validate_build_dependencies_override: false)
end
context 'when "dependencies" keyword is not defined' do
let(:options) { {} }
let!(:pre_stage_job) { create(:ci_build, :success, pipeline: pipeline, name: 'test', stage_idx: 0) }
context 'when "dependencies" keyword is not defined' do
let(:options) { {} }
it { expect(job).to have_valid_build_dependencies }
end
context 'when "dependencies" keyword is empty' do
let(:options) { { dependencies: [] } }
it { expect(job).to have_valid_build_dependencies }
end
context 'when "dependencies" keyword is specified' do
let(:options) { { dependencies: ['test'] } }
it_behaves_like 'validation is active'
end
it { expect(job).to have_valid_build_dependencies }
end
context 'when validates for dependencies is disabled' do
context 'when "dependencies" keyword is empty' do
let(:options) { { dependencies: [] } }
it { expect(job).to have_valid_build_dependencies }
end
context 'when "dependencies" keyword is specified' do
let(:options) { { dependencies: ['test'] } }
before do
stub_feature_flags(ci_validate_build_dependencies_override: true)
end
it_behaves_like 'validation is not active'
it_behaves_like 'validation is active'
end
end

View file

@ -516,10 +516,6 @@ module Ci
end
end
before do
stub_feature_flags(ci_validate_build_dependencies_override: false)
end
let!(:pre_stage_job) { create(:ci_build, :success, pipeline: pipeline, name: 'test', stage_idx: 0) }
let!(:pending_job) do
@ -530,37 +526,7 @@ module Ci
subject { execute(specific_runner) }
context 'when validates for dependencies is enabled' do
before do
stub_feature_flags(ci_validate_build_dependencies_override: false)
end
it_behaves_like 'validation is active'
context 'when the main feature flag is enabled for a specific project' do
before do
stub_feature_flags(ci_validate_build_dependencies: pipeline.project)
end
it_behaves_like 'validation is active'
end
context 'when the main feature flag is enabled for a different project' do
before do
stub_feature_flags(ci_validate_build_dependencies: create(:project))
end
it_behaves_like 'validation is not active'
end
end
context 'when validates for dependencies is disabled' do
before do
stub_feature_flags(ci_validate_build_dependencies_override: true)
end
it_behaves_like 'validation is not active'
end
it_behaves_like 'validation is active'
end
context 'when build is degenerated' do