Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
53f456b167
commit
05b83be3ee
39 changed files with 578 additions and 173 deletions
|
@ -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>
|
||||
|
|
|
@ -45,7 +45,7 @@ export default {
|
|||
this.tiptapEditor.chain()[this.editorCommand]().focus().run();
|
||||
}
|
||||
|
||||
this.$emit('click', { contentType });
|
||||
this.$emit('execute', { contentType });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,5 +6,6 @@ module ChaosQueue
|
|||
included do
|
||||
queue_namespace :chaos
|
||||
feature_category_not_owned!
|
||||
tags :exclude_from_gitlab_com
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,6 +8,7 @@ module HashedStorage
|
|||
|
||||
queue_namespace :hashed_storage
|
||||
loggable_arguments 1
|
||||
tags :exclude_from_gitlab_com
|
||||
|
||||
attr_reader :project_id
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ module HashedStorage
|
|||
|
||||
queue_namespace :hashed_storage
|
||||
loggable_arguments 1
|
||||
tags :exclude_from_gitlab_com
|
||||
|
||||
attr_reader :project_id
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix commit messages text color in dark mode
|
||||
merge_request: 61082
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Validate CI pipeline jobs dependencies
|
||||
merge_request: 60999
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fixed preview review comment not working with single file diff mode
|
||||
merge_request: 61032
|
||||
author:
|
||||
type: fixed
|
|
@ -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
|
|
@ -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
|
5
config/initializers/active_record_renamed_table.rb
Normal file
5
config/initializers/active_record_renamed_table.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
ActiveRecord::ConnectionAdapters::SchemaCache.prepend(Gitlab::Database::SchemaCacheWithRenamedTable)
|
||||
end
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
140
doc/development/database/rename_database_tables.md
Normal file
140
doc/development/database/rename_database_tables.md
Normal 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.
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
33
lib/gitlab/database/rename_table_helpers.rb
Normal file
33
lib/gitlab/database/rename_table_helpers.rb
Normal 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
|
55
lib/gitlab/database/schema_cache_with_renamed_table.rb
Normal file
55
lib/gitlab/database/schema_cache_with_renamed_table.rb
Normal 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
|
|
@ -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 ""
|
||||
|
||||
|
|
|
@ -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 });
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue