Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
e020b4e98e
commit
c2afac6a37
39 changed files with 638 additions and 592 deletions
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { pickBy } from 'lodash';
|
||||
import { mapActions } from 'vuex';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { updateHistory, setUrlParams } from '~/lib/utils/url_utility';
|
||||
import { __ } from '~/locale';
|
||||
import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
|
||||
|
@ -35,7 +36,9 @@ export default {
|
|||
milestoneTitle,
|
||||
types,
|
||||
weight,
|
||||
epicId,
|
||||
} = this.filterParams;
|
||||
|
||||
let notParams = {};
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(this.filterParams, 'not')) {
|
||||
|
@ -47,6 +50,7 @@ export default {
|
|||
'not[types]': this.filterParams.not.types,
|
||||
'not[milestone_title]': this.filterParams.not.milestoneTitle,
|
||||
'not[weight]': this.filterParams.not.weight,
|
||||
'not[epic_id]': this.filterParams.not.epicId,
|
||||
},
|
||||
undefined,
|
||||
);
|
||||
|
@ -61,6 +65,7 @@ export default {
|
|||
search,
|
||||
types,
|
||||
weight,
|
||||
epic_id: getIdFromGraphQLId(epicId),
|
||||
};
|
||||
},
|
||||
},
|
||||
|
@ -86,6 +91,7 @@ export default {
|
|||
milestoneTitle,
|
||||
types,
|
||||
weight,
|
||||
epicId,
|
||||
} = this.filterParams;
|
||||
const filteredSearchValue = [];
|
||||
|
||||
|
@ -133,6 +139,13 @@ export default {
|
|||
});
|
||||
}
|
||||
|
||||
if (epicId) {
|
||||
filteredSearchValue.push({
|
||||
type: 'epic_id',
|
||||
value: { data: epicId, operator: '=' },
|
||||
});
|
||||
}
|
||||
|
||||
if (this.filterParams['not[authorUsername]']) {
|
||||
filteredSearchValue.push({
|
||||
type: 'author_username',
|
||||
|
@ -177,6 +190,13 @@ export default {
|
|||
});
|
||||
}
|
||||
|
||||
if (this.filterParams['not[epicId]']) {
|
||||
filteredSearchValue.push({
|
||||
type: 'epic_id',
|
||||
value: { data: this.filterParams['not[epicId]'], operator: '!=' },
|
||||
});
|
||||
}
|
||||
|
||||
if (search) {
|
||||
filteredSearchValue.push(search);
|
||||
}
|
||||
|
@ -216,6 +236,9 @@ export default {
|
|||
case 'weight':
|
||||
filterParams.weight = filter.value.data;
|
||||
break;
|
||||
case 'epic_id':
|
||||
filterParams.epicId = filter.value.data;
|
||||
break;
|
||||
case 'filtered-search-term':
|
||||
if (filter.value.data) plainText.push(filter.value.data);
|
||||
break;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { GlFilteredSearchToken } from '@gitlab/ui';
|
||||
import { mapActions } from 'vuex';
|
||||
import BoardFilteredSearch from '~/boards/components/board_filtered_search.vue';
|
||||
import { BoardType } from '~/boards/constants';
|
||||
import issueBoardFilters from '~/boards/issue_board_filters';
|
||||
import { TYPE_USER } from '~/graphql_shared/constants';
|
||||
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||
|
@ -19,6 +20,7 @@ export default {
|
|||
},
|
||||
i18n: {
|
||||
search: __('Search'),
|
||||
epic: __('Epic'),
|
||||
label: __('Label'),
|
||||
author: __('Author'),
|
||||
assignee: __('Assignee'),
|
||||
|
@ -42,7 +44,15 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
tokens() {
|
||||
isGroupBoard() {
|
||||
return this.boardType === BoardType.group;
|
||||
},
|
||||
epicsGroupPath() {
|
||||
return this.isGroupBoard
|
||||
? this.fullPath
|
||||
: this.fullPath.slice(0, this.fullPath.lastIndexOf('/'));
|
||||
},
|
||||
tokensCE() {
|
||||
const {
|
||||
label,
|
||||
is,
|
||||
|
@ -134,6 +144,9 @@ export default {
|
|||
},
|
||||
];
|
||||
},
|
||||
tokens() {
|
||||
return this.tokensCE;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['fetchMilestones']),
|
||||
|
|
|
@ -109,7 +109,7 @@ export default () => {
|
|||
});
|
||||
|
||||
if (gon?.features?.issueBoardsFilteredSearch) {
|
||||
initBoardsFilteredSearch(apolloProvider);
|
||||
initBoardsFilteredSearch(apolloProvider, parseBoolean($boardApp.dataset.epicFeatureAvailable));
|
||||
}
|
||||
|
||||
mountBoardApp($boardApp);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Vue from 'vue';
|
||||
import IssueBoardFilteredSearch from '~/boards/components/issue_board_filtered_search.vue';
|
||||
import IssueBoardFilteredSearch from 'ee_else_ce/boards/components/issue_board_filtered_search.vue';
|
||||
import store from '~/boards/stores';
|
||||
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
||||
import { queryToObject } from '~/lib/utils/url_utility';
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
IssueTypePath,
|
||||
IncidentTypePath,
|
||||
IncidentType,
|
||||
POLLING_DELAY,
|
||||
} from '../constants';
|
||||
import eventHub from '../event_hub';
|
||||
import getIssueStateQuery from '../queries/get_issue_state.query.graphql';
|
||||
|
@ -282,7 +283,7 @@ export default {
|
|||
});
|
||||
|
||||
if (!Visibility.hidden()) {
|
||||
this.poll.makeDelayedRequest(2000);
|
||||
this.poll.makeDelayedRequest(POLLING_DELAY);
|
||||
}
|
||||
|
||||
Visibility.change(() => {
|
||||
|
@ -457,6 +458,22 @@ export default {
|
|||
this.flashContainer = null;
|
||||
}
|
||||
},
|
||||
|
||||
taskListUpdateStarted() {
|
||||
this.poll.stop();
|
||||
},
|
||||
|
||||
taskListUpdateSucceeded() {
|
||||
this.poll.enable();
|
||||
this.poll.makeDelayedRequest(POLLING_DELAY);
|
||||
},
|
||||
|
||||
taskListUpdateFailed() {
|
||||
this.poll.enable();
|
||||
this.poll.makeDelayedRequest(POLLING_DELAY);
|
||||
|
||||
this.updateStoreState();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -552,7 +569,9 @@ export default {
|
|||
:issuable-type="issuableType"
|
||||
:update-url="updateEndpoint"
|
||||
:lock-version="state.lock_version"
|
||||
@taskListUpdateFailed="updateStoreState"
|
||||
@taskListUpdateStarted="taskListUpdateStarted"
|
||||
@taskListUpdateSucceeded="taskListUpdateSucceeded"
|
||||
@taskListUpdateFailed="taskListUpdateFailed"
|
||||
/>
|
||||
|
||||
<edited-component
|
||||
|
|
|
@ -86,11 +86,21 @@ export default {
|
|||
fieldName: 'description',
|
||||
lockVersion: this.lockVersion,
|
||||
selector: '.detail-page-description',
|
||||
onUpdate: this.taskListUpdateStarted.bind(this),
|
||||
onSuccess: this.taskListUpdateSuccess.bind(this),
|
||||
onError: this.taskListUpdateError.bind(this),
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
taskListUpdateStarted() {
|
||||
this.$emit('taskListUpdateStarted');
|
||||
},
|
||||
|
||||
taskListUpdateSuccess() {
|
||||
this.$emit('taskListUpdateSucceeded');
|
||||
},
|
||||
|
||||
taskListUpdateError() {
|
||||
createFlash({
|
||||
message: sprintf(
|
||||
|
|
|
@ -37,3 +37,5 @@ export const IncidentTypePath = 'issues/incident';
|
|||
export const IncidentType = 'incident';
|
||||
|
||||
export const issueState = { issueType: undefined, isDirty: false };
|
||||
|
||||
export const POLLING_DELAY = 2000;
|
||||
|
|
|
@ -12,6 +12,7 @@ export default class TaskList {
|
|||
this.lockVersion = options.lockVersion;
|
||||
this.taskListContainerSelector = `${this.selector} .js-task-list-container`;
|
||||
this.updateHandler = this.update.bind(this);
|
||||
this.onUpdate = options.onUpdate || (() => {});
|
||||
this.onSuccess = options.onSuccess || (() => {});
|
||||
this.onError =
|
||||
options.onError ||
|
||||
|
@ -96,6 +97,7 @@ export default class TaskList {
|
|||
},
|
||||
};
|
||||
|
||||
this.onUpdate();
|
||||
this.disableTaskListItems(e);
|
||||
|
||||
return axios
|
||||
|
|
|
@ -71,7 +71,7 @@ module Ci
|
|||
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :variables, class_name: 'Ci::PipelineVariable'
|
||||
has_many :deployments, through: :builds
|
||||
has_many :environments, -> { distinct }, through: :deployments
|
||||
has_many :environments, -> { distinct.allow_cross_joins_across_databases(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338658') }, through: :deployments
|
||||
has_many :latest_builds, -> { latest.with_project_and_metadata }, foreign_key: :commit_id, inverse_of: :pipeline, class_name: 'Ci::Build'
|
||||
has_many :downloadable_artifacts, -> do
|
||||
not_expired.or(where_exists(::Ci::Pipeline.artifacts_locked.where('ci_pipelines.id = ci_builds.commit_id'))).downloadable.with_job
|
||||
|
|
|
@ -6,6 +6,7 @@ module Groups
|
|||
@current_user = user
|
||||
@params = params.dup
|
||||
@chat_team = @params.delete(:create_chat_team)
|
||||
@create_event = @params.delete(:create_event)
|
||||
end
|
||||
|
||||
def execute
|
||||
|
@ -42,15 +43,23 @@ module Groups
|
|||
end
|
||||
end
|
||||
|
||||
after_create_hook
|
||||
|
||||
@group
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :create_event
|
||||
|
||||
def after_build_hook(group, params)
|
||||
# overridden in EE
|
||||
end
|
||||
|
||||
def after_create_hook
|
||||
# overridden in EE
|
||||
end
|
||||
|
||||
def remove_unallowed_params
|
||||
params.delete(:default_branch_protection) unless can?(current_user, :create_group_with_default_branch_protection)
|
||||
params.delete(:allow_mfa_for_subgroups)
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
= render 'shared/allow_request_access', form: f
|
||||
|
||||
= render_if_exists 'groups/member_lock_setting', f: f, group: @group
|
||||
= render_if_exists 'groups/user_caps_setting', f: f, group: @group
|
||||
|
|
|
@ -175,6 +175,8 @@
|
|||
- 1
|
||||
- - group_wikis_git_garbage_collect
|
||||
- 1
|
||||
- - groups_create_event
|
||||
- 1
|
||||
- - groups_export_memberships
|
||||
- 1
|
||||
- - groups_schedule_bulk_repository_shard_moves
|
||||
|
|
|
@ -134,7 +134,7 @@ job:
|
|||
## Inherit global configuration, but override specific settings per job
|
||||
|
||||
You can override cache settings without overwriting the global cache by using
|
||||
[anchors](../yaml/index.md#anchors). For example, if you want to override the
|
||||
[anchors](../yaml/yaml_specific_features.md#anchors). For example, if you want to override the
|
||||
`policy` for one job:
|
||||
|
||||
```yaml
|
||||
|
|
|
@ -139,6 +139,32 @@ In [GitLab 13.8 and earlier](https://gitlab.com/gitlab-org/gitlab/-/merge_reques
|
|||
the regular expression is `\d+[\s:\/\\]+\d+\s*`. [Feature flag](../../user/feature_flags.md)
|
||||
removed in [GitLab 13.11](https://gitlab.com/gitlab-org/gitlab/-/issues/322080).
|
||||
|
||||
## Hide jobs
|
||||
|
||||
To temporarily disable a job without deleting it from the configuration
|
||||
file:
|
||||
|
||||
- Comment out the job's configuration:
|
||||
|
||||
```yaml
|
||||
# hidden_job:
|
||||
# script:
|
||||
# - run test
|
||||
```
|
||||
|
||||
- Start the job name with a dot (`.`) and it is not processed by GitLab CI/CD:
|
||||
|
||||
```yaml
|
||||
.hidden_job:
|
||||
script:
|
||||
- run test
|
||||
```
|
||||
|
||||
You can use hidden jobs that start with `.` as templates for reusable configuration with:
|
||||
|
||||
- The [`extends` keyword](../yaml/index.md#extends).
|
||||
- [YAML anchors](../yaml/yaml_specific_features.md#anchors).
|
||||
|
||||
## Specifying variables when running manual jobs
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30485) in GitLab 12.2.
|
||||
|
|
|
@ -294,7 +294,7 @@ You can use the `$` character for both variables and paths. For example, if the
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322992) in GitLab 14.3.
|
||||
|
||||
Use [`!reference` tags](../yaml/index.md#reference-tags) to reuse rules in different
|
||||
Use [`!reference` tags](../yaml/yaml_specific_features.md#reference-tags) to reuse rules in different
|
||||
jobs. You can combine `!reference` rules with regular job-defined rules:
|
||||
|
||||
```yaml
|
||||
|
|
|
@ -83,7 +83,7 @@ where:
|
|||
- Configuration imported with [`include`](../yaml/index.md#include) is copied into the view.
|
||||
- Jobs that use [`extends`](../yaml/index.md#extends) display with the
|
||||
[extended configuration merged into the job](../yaml/index.md#merge-details).
|
||||
- YAML anchors are [replaced with the linked configuration](../yaml/index.md#anchors).
|
||||
- YAML anchors are [replaced with the linked configuration](../yaml/yaml_specific_features.md#anchors).
|
||||
|
||||
## Commit changes to CI configuration
|
||||
|
||||
|
|
|
@ -229,6 +229,15 @@ This functionality is only available:
|
|||
- For users with at least the Developer role.
|
||||
- If the stage contains [manual actions](#add-manual-interaction-to-your-pipeline).
|
||||
|
||||
### Skip a pipeline
|
||||
|
||||
To push a commit without triggering a pipeline, add `[ci skip]` or `[skip ci]`, using any
|
||||
capitalization, to your commit message.
|
||||
|
||||
Alternatively, if you are using Git 2.10 or later, use the `ci.skip` [Git push option](../../user/project/push_options.md#push-options-for-gitlab-cicd).
|
||||
The `ci.skip` push option does not skip merge request
|
||||
pipelines.
|
||||
|
||||
### Delete a pipeline
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24851) in GitLab 12.7.
|
||||
|
|
|
@ -24,7 +24,7 @@ In the `.gitlab-ci.yml` file, you can define:
|
|||
|
||||
The scripts are grouped into **jobs**, and jobs run as part of a larger
|
||||
**pipeline**. You can group multiple independent jobs into **stages** that run in a defined order.
|
||||
The CI/CD configuration needs at least one job that is [not hidden](index.md#hide-jobs).
|
||||
The CI/CD configuration needs at least one job that is [not hidden](../jobs/index.md#hide-jobs).
|
||||
|
||||
You should organize your jobs in a sequence that suits your application and is in accordance with
|
||||
the tests you wish to perform. To [visualize](../pipeline_editor/index.md#visualize-ci-configuration) the process, imagine
|
||||
|
|
|
@ -390,9 +390,9 @@ You can also store template files in a central repository and `include` them in
|
|||
`include` requires the external YAML file to have the extensions `.yml` or `.yaml`,
|
||||
otherwise the external file is not included.
|
||||
|
||||
You can't use [YAML anchors](#anchors) across different YAML files sourced by `include`.
|
||||
You can't use [YAML anchors](yaml_specific_features.md#anchors) across different YAML files sourced by `include`.
|
||||
You can only refer to anchors in the same file. To reuse configuration from different
|
||||
YAML files, use [`!reference` tags](#reference-tags) or the [`extends` keyword](#extends).
|
||||
YAML files, use [`!reference` tags](yaml_specific_features.md#reference-tags) or the [`extends` keyword](#extends).
|
||||
|
||||
`include` supports the following inclusion methods:
|
||||
|
||||
|
@ -427,6 +427,13 @@ In `include` sections in your `.gitlab-ci.yml` file, you can use:
|
|||
|
||||
- `$CI_COMMIT_REF_NAME` [predefined variable](../variables/predefined_variables.md) in GitLab 14.2
|
||||
and later.
|
||||
- When used in `include`, the `CI_COMMIT_REF_NAME` variable returns the full
|
||||
ref path, like `refs/heads/branch-name`. In other cases, this variable returns only
|
||||
the branch name, like `branch-name`.
|
||||
|
||||
To use `CI_COMMIT_REF_NAME` in `include:rules`, you might need to use `if: $CI_COMMIT_REF_NAME =~ /main/`
|
||||
(not `== main`). [An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/337633)
|
||||
to align `CI_COMMIT_REF_NAME` behavior in all cases.
|
||||
- [Project variables](../variables/index.md#add-a-cicd-variable-to-a-project)
|
||||
- [Group variables](../variables/index.md#add-a-cicd-variable-to-a-group)
|
||||
- [Instance variables](../variables/index.md#add-a-cicd-variable-to-an-instance)
|
||||
|
@ -703,7 +710,7 @@ All jobs except [trigger jobs](#trigger) require a `script` keyword.
|
|||
|
||||
- Single line commands.
|
||||
- Long commands [split over multiple lines](script.md#split-long-commands).
|
||||
- [YAML anchors](#yaml-anchors-for-scripts).
|
||||
- [YAML anchors](yaml_specific_features.md#yaml-anchors-for-scripts).
|
||||
|
||||
**Example of `script`:**
|
||||
|
||||
|
@ -742,7 +749,7 @@ Use `before_script` to define an array of commands that should run before each j
|
|||
|
||||
- Single line commands.
|
||||
- Long commands [split over multiple lines](script.md#split-long-commands).
|
||||
- [YAML anchors](#yaml-anchors-for-scripts).
|
||||
- [YAML anchors](yaml_specific_features.md#yaml-anchors-for-scripts).
|
||||
|
||||
**Example of `before_script`:**
|
||||
|
||||
|
@ -780,7 +787,7 @@ Use `after_script` to define an array of commands that run after each job, inclu
|
|||
|
||||
- Single line commands.
|
||||
- Long commands [split over multiple lines](script.md#split-long-commands).
|
||||
- [YAML anchors](#yaml-anchors-for-scripts).
|
||||
- [YAML anchors](yaml_specific_features.md#yaml-anchors-for-scripts).
|
||||
|
||||
**Example of `after_script`:**
|
||||
|
||||
|
@ -943,7 +950,7 @@ job2:
|
|||
|
||||
> Introduced in GitLab 11.3.
|
||||
|
||||
Use `extends` to reuse configuration sections. It's an alternative to [YAML anchors](#anchors)
|
||||
Use `extends` to reuse configuration sections. It's an alternative to [YAML anchors](yaml_specific_features.md#anchors)
|
||||
and is a little more flexible and readable. You can use `extends` to reuse configuration
|
||||
from [included configuration files](#use-extends-and-include-together).
|
||||
|
||||
|
@ -983,7 +990,7 @@ rspec:
|
|||
- $RSPEC
|
||||
```
|
||||
|
||||
`.tests` in this example is a [hidden job](#hide-jobs), but it's
|
||||
`.tests` in this example is a [hidden job](../jobs/index.md#hide-jobs), but it's
|
||||
possible to extend configuration from regular jobs as well.
|
||||
|
||||
`extends` supports multi-level inheritance. You should avoid using more than three levels,
|
||||
|
@ -1076,7 +1083,7 @@ In this example:
|
|||
- The `variables` sections merge, but `URL: "http://docker-url.internal"` overwrites `URL: "http://my-url.internal"`.
|
||||
- `tags: ['docker']` overwrites `tags: ['production']`.
|
||||
- `script` does not merge, but `script: ['rake rspec']` overwrites
|
||||
`script: ['echo "Hello world!"']`. You can use [YAML anchors](#anchors) to merge arrays.
|
||||
`script: ['echo "Hello world!"']`. You can use [YAML anchors](yaml_specific_features.md#anchors) to merge arrays.
|
||||
|
||||
#### Use `extends` and `include` together
|
||||
|
||||
|
@ -1111,8 +1118,11 @@ to the contents of the `script`:
|
|||
|
||||
Use `rules` to include or exclude jobs in pipelines.
|
||||
|
||||
Rules are evaluated *in order* until the first match. When a match is found, the job
|
||||
is either included or excluded from the pipeline, depending on the configuration.
|
||||
Rules are evaluated when the pipeline is created, and evaluated *in order*
|
||||
until the first match. When a match is found, the job is either included or excluded from the pipeline,
|
||||
depending on the configuration.
|
||||
|
||||
You cannot use dotenv variables created in job scripts in rules, because rules are evaluated before any jobs run.
|
||||
|
||||
`rules` replaces [`only/except`](#only--except) and they can't be used together
|
||||
in the same job. If you configure one job to use both keywords, the GitLab returns
|
||||
|
@ -1140,7 +1150,7 @@ The job is not added to the pipeline:
|
|||
- If no rules match.
|
||||
- If a rule matches and has `when: never`.
|
||||
|
||||
You can use [`!reference` tags](#reference-tags) to [reuse `rules` configuration](../jobs/job_control.md#reuse-rules-in-different-jobs)
|
||||
You can use [`!reference` tags](yaml_specific_features.md#reference-tags) to [reuse `rules` configuration](../jobs/job_control.md#reuse-rules-in-different-jobs)
|
||||
in different jobs.
|
||||
|
||||
#### `rules:if`
|
||||
|
@ -2177,7 +2187,7 @@ Also in the example, `GIT_STRATEGY` is set to `none`. If the
|
|||
the runner won't try to check out the code after the branch is deleted.
|
||||
|
||||
The example also overwrites global variables. If your `stop` `environment` job depends
|
||||
on global variables, use [anchor variables](#yaml-anchors-for-variables) when you set the `GIT_STRATEGY`
|
||||
on global variables, use [anchor variables](yaml_specific_features.md#yaml-anchors-for-variables) when you set the `GIT_STRATEGY`
|
||||
to change the job without overriding the global variables.
|
||||
|
||||
The `stop_review_app` job is **required** to have the following keywords defined:
|
||||
|
@ -4541,7 +4551,7 @@ If a variable of the same name is defined globally and for a specific job, the
|
|||
All YAML-defined variables are also set to any linked
|
||||
[Docker service containers](../services/index.md).
|
||||
|
||||
You can use [YAML anchors for variables](#yaml-anchors-for-variables).
|
||||
You can use [YAML anchors for variables](yaml_specific_features.md#yaml-anchors-for-variables).
|
||||
|
||||
### Prefill variables in manual pipelines
|
||||
|
||||
|
@ -4577,311 +4587,6 @@ You can use [CI/CD variables](../variables/index.md) to configure how the runner
|
|||
You can also use variables to configure how many times a runner
|
||||
[attempts certain stages of job execution](../runners/configure_runners.md#job-stages-attempts).
|
||||
|
||||
## YAML-specific features
|
||||
|
||||
In your `.gitlab-ci.yml` file, you can use YAML-specific features like anchors (`&`), aliases (`*`),
|
||||
and map merging (`<<`). Use these features to reduce the complexity
|
||||
of the code in the `.gitlab-ci.yml` file.
|
||||
|
||||
Read more about the various [YAML features](https://learnxinyminutes.com/docs/yaml/).
|
||||
|
||||
In most cases, the [`extends` keyword](#extends) is more user friendly and you should
|
||||
use it when possible.
|
||||
|
||||
You can use YAML anchors to merge YAML arrays.
|
||||
|
||||
### Anchors
|
||||
|
||||
YAML has a feature called 'anchors' that you can use to duplicate
|
||||
content across your document.
|
||||
|
||||
Use anchors to duplicate or inherit properties. Use anchors with [hidden jobs](#hide-jobs)
|
||||
to provide templates for your jobs. When there are duplicate keys, GitLab
|
||||
performs a reverse deep merge based on the keys.
|
||||
|
||||
You can't use YAML anchors across multiple files when using the [`include`](#include)
|
||||
keyword. Anchors are only valid in the file they were defined in. To reuse configuration
|
||||
from different YAML files, use [`!reference` tags](#reference-tags) or the
|
||||
[`extends` keyword](#extends).
|
||||
|
||||
The following example uses anchors and map merging. It creates two jobs,
|
||||
`test1` and `test2`, that inherit the `.job_template` configuration, each
|
||||
with their own custom `script` defined:
|
||||
|
||||
```yaml
|
||||
.job_template: &job_configuration # Hidden yaml configuration that defines an anchor named 'job_configuration'
|
||||
image: ruby:2.6
|
||||
services:
|
||||
- postgres
|
||||
- redis
|
||||
|
||||
test1:
|
||||
<<: *job_configuration # Merge the contents of the 'job_configuration' alias
|
||||
script:
|
||||
- test1 project
|
||||
|
||||
test2:
|
||||
<<: *job_configuration # Merge the contents of the 'job_configuration' alias
|
||||
script:
|
||||
- test2 project
|
||||
```
|
||||
|
||||
`&` sets up the name of the anchor (`job_configuration`), `<<` means "merge the
|
||||
given hash into the current one," and `*` includes the named anchor
|
||||
(`job_configuration` again). The expanded version of this example is:
|
||||
|
||||
```yaml
|
||||
.job_template:
|
||||
image: ruby:2.6
|
||||
services:
|
||||
- postgres
|
||||
- redis
|
||||
|
||||
test1:
|
||||
image: ruby:2.6
|
||||
services:
|
||||
- postgres
|
||||
- redis
|
||||
script:
|
||||
- test1 project
|
||||
|
||||
test2:
|
||||
image: ruby:2.6
|
||||
services:
|
||||
- postgres
|
||||
- redis
|
||||
script:
|
||||
- test2 project
|
||||
```
|
||||
|
||||
You can use anchors to define two sets of services. For example, `test:postgres`
|
||||
and `test:mysql` share the `script` defined in `.job_template`, but use different
|
||||
`services`, defined in `.postgres_services` and `.mysql_services`:
|
||||
|
||||
```yaml
|
||||
.job_template: &job_configuration
|
||||
script:
|
||||
- test project
|
||||
tags:
|
||||
- dev
|
||||
|
||||
.postgres_services:
|
||||
services: &postgres_configuration
|
||||
- postgres
|
||||
- ruby
|
||||
|
||||
.mysql_services:
|
||||
services: &mysql_configuration
|
||||
- mysql
|
||||
- ruby
|
||||
|
||||
test:postgres:
|
||||
<<: *job_configuration
|
||||
services: *postgres_configuration
|
||||
tags:
|
||||
- postgres
|
||||
|
||||
test:mysql:
|
||||
<<: *job_configuration
|
||||
services: *mysql_configuration
|
||||
```
|
||||
|
||||
The expanded version is:
|
||||
|
||||
```yaml
|
||||
.job_template:
|
||||
script:
|
||||
- test project
|
||||
tags:
|
||||
- dev
|
||||
|
||||
.postgres_services:
|
||||
services:
|
||||
- postgres
|
||||
- ruby
|
||||
|
||||
.mysql_services:
|
||||
services:
|
||||
- mysql
|
||||
- ruby
|
||||
|
||||
test:postgres:
|
||||
script:
|
||||
- test project
|
||||
services:
|
||||
- postgres
|
||||
- ruby
|
||||
tags:
|
||||
- postgres
|
||||
|
||||
test:mysql:
|
||||
script:
|
||||
- test project
|
||||
services:
|
||||
- mysql
|
||||
- ruby
|
||||
tags:
|
||||
- dev
|
||||
```
|
||||
|
||||
You can see that the hidden jobs are conveniently used as templates, and
|
||||
`tags: [postgres]` overwrites `tags: [dev]`.
|
||||
|
||||
#### YAML anchors for scripts
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23005) in GitLab 12.5.
|
||||
|
||||
You can use [YAML anchors](#anchors) with [script](#script), [`before_script`](#before_script),
|
||||
and [`after_script`](#after_script) to use predefined commands in multiple jobs:
|
||||
|
||||
```yaml
|
||||
.some-script-before: &some-script-before
|
||||
- echo "Execute this script first"
|
||||
|
||||
.some-script: &some-script
|
||||
- echo "Execute this script second"
|
||||
- echo "Execute this script too"
|
||||
|
||||
.some-script-after: &some-script-after
|
||||
- echo "Execute this script last"
|
||||
|
||||
job1:
|
||||
before_script:
|
||||
- *some-script-before
|
||||
script:
|
||||
- *some-script
|
||||
- echo "Execute something, for this job only"
|
||||
after_script:
|
||||
- *some-script-after
|
||||
|
||||
job2:
|
||||
script:
|
||||
- *some-script-before
|
||||
- *some-script
|
||||
- echo "Execute something else, for this job only"
|
||||
- *some-script-after
|
||||
```
|
||||
|
||||
#### YAML anchors for variables
|
||||
|
||||
Use [YAML anchors](#anchors) with `variables` to repeat assignment
|
||||
of variables across multiple jobs. You can also use YAML anchors when a job
|
||||
requires a specific `variables` block that would otherwise override the global variables.
|
||||
|
||||
The following example shows how override the `GIT_STRATEGY` variable without affecting
|
||||
the use of the `SAMPLE_VARIABLE` variable:
|
||||
|
||||
```yaml
|
||||
# global variables
|
||||
variables: &global-variables
|
||||
SAMPLE_VARIABLE: sample_variable_value
|
||||
ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value
|
||||
|
||||
# a job that must set the GIT_STRATEGY variable, yet depend on global variables
|
||||
job_no_git_strategy:
|
||||
stage: cleanup
|
||||
variables:
|
||||
<<: *global-variables
|
||||
GIT_STRATEGY: none
|
||||
script: echo $SAMPLE_VARIABLE
|
||||
```
|
||||
|
||||
### Hide jobs
|
||||
|
||||
If you want to temporarily disable a job, rather than commenting out all the
|
||||
lines where the job is defined:
|
||||
|
||||
```yaml
|
||||
# hidden_job:
|
||||
# script:
|
||||
# - run test
|
||||
```
|
||||
|
||||
Instead, you can start its name with a dot (`.`) and it is not processed by
|
||||
GitLab CI/CD. In the following example, `.hidden_job` is ignored:
|
||||
|
||||
```yaml
|
||||
.hidden_job:
|
||||
script:
|
||||
- run test
|
||||
```
|
||||
|
||||
Use this feature to ignore jobs, or use the
|
||||
[YAML-specific features](#yaml-specific-features) and transform the hidden jobs
|
||||
into templates.
|
||||
|
||||
### `!reference` tags
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/266173) in GitLab 13.9.
|
||||
> - `rules` keyword support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322992) in GitLab 14.3.
|
||||
|
||||
Use the `!reference` custom YAML tag to select keyword configuration from other job
|
||||
sections and reuse it in the current section. Unlike [YAML anchors](#anchors), you can
|
||||
use `!reference` tags to reuse configuration from [included](#include) configuration
|
||||
files as well.
|
||||
|
||||
In the following example, a `script` and an `after_script` from two different locations are
|
||||
reused in the `test` job:
|
||||
|
||||
- `setup.yml`:
|
||||
|
||||
```yaml
|
||||
.setup:
|
||||
script:
|
||||
- echo creating environment
|
||||
```
|
||||
|
||||
- `.gitlab-ci.yml`:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- local: setup.yml
|
||||
|
||||
.teardown:
|
||||
after_script:
|
||||
- echo deleting environment
|
||||
|
||||
test:
|
||||
script:
|
||||
- !reference [.setup, script]
|
||||
- echo running my own command
|
||||
after_script:
|
||||
- !reference [.teardown, after_script]
|
||||
```
|
||||
|
||||
In the following example, `test-vars-1` reuses all the variables in `.vars`, while `test-vars-2`
|
||||
selects a specific variable and reuses it as a new `MY_VAR` variable.
|
||||
|
||||
```yaml
|
||||
.vars:
|
||||
variables:
|
||||
URL: "http://my-url.internal"
|
||||
IMPORTANT_VAR: "the details"
|
||||
|
||||
test-vars-1:
|
||||
variables: !reference [.vars, variables]
|
||||
script:
|
||||
- printenv
|
||||
|
||||
test-vars-2:
|
||||
variables:
|
||||
MY_VAR: !reference [.vars, variables, IMPORTANT_VAR]
|
||||
script:
|
||||
- printenv
|
||||
```
|
||||
|
||||
You can't reuse a section that already includes a `!reference` tag. Only one level
|
||||
of nesting is supported.
|
||||
|
||||
## Skip Pipeline
|
||||
|
||||
To push a commit without triggering a pipeline, add `[ci skip]` or `[skip ci]`, using any
|
||||
capitalization, to your commit message.
|
||||
|
||||
Alternatively, if you are using Git 2.10 or later, use the `ci.skip` [Git push option](../../user/project/push_options.md#push-options-for-gitlab-cicd).
|
||||
The `ci.skip` push option does not skip merge request
|
||||
pipelines.
|
||||
|
||||
## Processing Git pushes
|
||||
|
||||
GitLab creates at most four branch and tag pipelines when
|
||||
|
|
278
doc/ci/yaml/yaml_specific_features.md
Normal file
278
doc/ci/yaml/yaml_specific_features.md
Normal file
|
@ -0,0 +1,278 @@
|
|||
---
|
||||
stage: Verify
|
||||
group: Pipeline Authoring
|
||||
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
|
||||
type: reference
|
||||
---
|
||||
|
||||
# YAML-specific features
|
||||
|
||||
In your `.gitlab-ci.yml` file, you can use YAML-specific features like anchors (`&`), aliases (`*`),
|
||||
and map merging (`<<`). Use these features to reduce the complexity
|
||||
of the code in the `.gitlab-ci.yml` file.
|
||||
|
||||
Read more about the various [YAML features](https://learnxinyminutes.com/docs/yaml/).
|
||||
|
||||
In most cases, the [`extends` keyword](index.md#extends) is more user friendly and you should
|
||||
use it when possible.
|
||||
|
||||
You can use YAML anchors to merge YAML arrays.
|
||||
|
||||
## Anchors
|
||||
|
||||
YAML has a feature called 'anchors' that you can use to duplicate
|
||||
content across your document.
|
||||
|
||||
Use anchors to duplicate or inherit properties. Use anchors with [hidden jobs](../jobs/index.md#hide-jobs)
|
||||
to provide templates for your jobs. When there are duplicate keys, GitLab
|
||||
performs a reverse deep merge based on the keys.
|
||||
|
||||
You can't use YAML anchors across multiple files when using the [`include`](index.md#include)
|
||||
keyword. Anchors are only valid in the file they were defined in. To reuse configuration
|
||||
from different YAML files, use [`!reference` tags](#reference-tags) or the
|
||||
[`extends` keyword](index.md#extends).
|
||||
|
||||
The following example uses anchors and map merging. It creates two jobs,
|
||||
`test1` and `test2`, that inherit the `.job_template` configuration, each
|
||||
with their own custom `script` defined:
|
||||
|
||||
```yaml
|
||||
.job_template: &job_configuration # Hidden yaml configuration that defines an anchor named 'job_configuration'
|
||||
image: ruby:2.6
|
||||
services:
|
||||
- postgres
|
||||
- redis
|
||||
|
||||
test1:
|
||||
<<: *job_configuration # Merge the contents of the 'job_configuration' alias
|
||||
script:
|
||||
- test1 project
|
||||
|
||||
test2:
|
||||
<<: *job_configuration # Merge the contents of the 'job_configuration' alias
|
||||
script:
|
||||
- test2 project
|
||||
```
|
||||
|
||||
`&` sets up the name of the anchor (`job_configuration`), `<<` means "merge the
|
||||
given hash into the current one," and `*` includes the named anchor
|
||||
(`job_configuration` again). The expanded version of this example is:
|
||||
|
||||
```yaml
|
||||
.job_template:
|
||||
image: ruby:2.6
|
||||
services:
|
||||
- postgres
|
||||
- redis
|
||||
|
||||
test1:
|
||||
image: ruby:2.6
|
||||
services:
|
||||
- postgres
|
||||
- redis
|
||||
script:
|
||||
- test1 project
|
||||
|
||||
test2:
|
||||
image: ruby:2.6
|
||||
services:
|
||||
- postgres
|
||||
- redis
|
||||
script:
|
||||
- test2 project
|
||||
```
|
||||
|
||||
You can use anchors to define two sets of services. For example, `test:postgres`
|
||||
and `test:mysql` share the `script` defined in `.job_template`, but use different
|
||||
`services`, defined in `.postgres_services` and `.mysql_services`:
|
||||
|
||||
```yaml
|
||||
.job_template: &job_configuration
|
||||
script:
|
||||
- test project
|
||||
tags:
|
||||
- dev
|
||||
|
||||
.postgres_services:
|
||||
services: &postgres_configuration
|
||||
- postgres
|
||||
- ruby
|
||||
|
||||
.mysql_services:
|
||||
services: &mysql_configuration
|
||||
- mysql
|
||||
- ruby
|
||||
|
||||
test:postgres:
|
||||
<<: *job_configuration
|
||||
services: *postgres_configuration
|
||||
tags:
|
||||
- postgres
|
||||
|
||||
test:mysql:
|
||||
<<: *job_configuration
|
||||
services: *mysql_configuration
|
||||
```
|
||||
|
||||
The expanded version is:
|
||||
|
||||
```yaml
|
||||
.job_template:
|
||||
script:
|
||||
- test project
|
||||
tags:
|
||||
- dev
|
||||
|
||||
.postgres_services:
|
||||
services:
|
||||
- postgres
|
||||
- ruby
|
||||
|
||||
.mysql_services:
|
||||
services:
|
||||
- mysql
|
||||
- ruby
|
||||
|
||||
test:postgres:
|
||||
script:
|
||||
- test project
|
||||
services:
|
||||
- postgres
|
||||
- ruby
|
||||
tags:
|
||||
- postgres
|
||||
|
||||
test:mysql:
|
||||
script:
|
||||
- test project
|
||||
services:
|
||||
- mysql
|
||||
- ruby
|
||||
tags:
|
||||
- dev
|
||||
```
|
||||
|
||||
You can see that the hidden jobs are conveniently used as templates, and
|
||||
`tags: [postgres]` overwrites `tags: [dev]`.
|
||||
|
||||
### YAML anchors for scripts
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23005) in GitLab 12.5.
|
||||
|
||||
You can use [YAML anchors](#anchors) with [script](index.md#script), [`before_script`](index.md#before_script),
|
||||
and [`after_script`](index.md#after_script) to use predefined commands in multiple jobs:
|
||||
|
||||
```yaml
|
||||
.some-script-before: &some-script-before
|
||||
- echo "Execute this script first"
|
||||
|
||||
.some-script: &some-script
|
||||
- echo "Execute this script second"
|
||||
- echo "Execute this script too"
|
||||
|
||||
.some-script-after: &some-script-after
|
||||
- echo "Execute this script last"
|
||||
|
||||
job1:
|
||||
before_script:
|
||||
- *some-script-before
|
||||
script:
|
||||
- *some-script
|
||||
- echo "Execute something, for this job only"
|
||||
after_script:
|
||||
- *some-script-after
|
||||
|
||||
job2:
|
||||
script:
|
||||
- *some-script-before
|
||||
- *some-script
|
||||
- echo "Execute something else, for this job only"
|
||||
- *some-script-after
|
||||
```
|
||||
|
||||
### YAML anchors for variables
|
||||
|
||||
Use [YAML anchors](#anchors) with `variables` to repeat assignment
|
||||
of variables across multiple jobs. You can also use YAML anchors when a job
|
||||
requires a specific `variables` block that would otherwise override the global variables.
|
||||
|
||||
The following example shows how override the `GIT_STRATEGY` variable without affecting
|
||||
the use of the `SAMPLE_VARIABLE` variable:
|
||||
|
||||
```yaml
|
||||
# global variables
|
||||
variables: &global-variables
|
||||
SAMPLE_VARIABLE: sample_variable_value
|
||||
ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value
|
||||
|
||||
# a job that must set the GIT_STRATEGY variable, yet depend on global variables
|
||||
job_no_git_strategy:
|
||||
stage: cleanup
|
||||
variables:
|
||||
<<: *global-variables
|
||||
GIT_STRATEGY: none
|
||||
script: echo $SAMPLE_VARIABLE
|
||||
```
|
||||
|
||||
## `!reference` tags
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/266173) in GitLab 13.9.
|
||||
> - `rules` keyword support [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322992) in GitLab 14.3.
|
||||
|
||||
Use the `!reference` custom YAML tag to select keyword configuration from other job
|
||||
sections and reuse it in the current section. Unlike [YAML anchors](#anchors), you can
|
||||
use `!reference` tags to reuse configuration from [included](index.md#include) configuration
|
||||
files as well.
|
||||
|
||||
In the following example, a `script` and an `after_script` from two different locations are
|
||||
reused in the `test` job:
|
||||
|
||||
- `setup.yml`:
|
||||
|
||||
```yaml
|
||||
.setup:
|
||||
script:
|
||||
- echo creating environment
|
||||
```
|
||||
|
||||
- `.gitlab-ci.yml`:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- local: setup.yml
|
||||
|
||||
.teardown:
|
||||
after_script:
|
||||
- echo deleting environment
|
||||
|
||||
test:
|
||||
script:
|
||||
- !reference [.setup, script]
|
||||
- echo running my own command
|
||||
after_script:
|
||||
- !reference [.teardown, after_script]
|
||||
```
|
||||
|
||||
In the following example, `test-vars-1` reuses all the variables in `.vars`, while `test-vars-2`
|
||||
selects a specific variable and reuses it as a new `MY_VAR` variable.
|
||||
|
||||
```yaml
|
||||
.vars:
|
||||
variables:
|
||||
URL: "http://my-url.internal"
|
||||
IMPORTANT_VAR: "the details"
|
||||
|
||||
test-vars-1:
|
||||
variables: !reference [.vars, variables]
|
||||
script:
|
||||
- printenv
|
||||
|
||||
test-vars-2:
|
||||
variables:
|
||||
MY_VAR: !reference [.vars, variables, IMPORTANT_VAR]
|
||||
script:
|
||||
- printenv
|
||||
```
|
||||
|
||||
You can't reuse a section that already includes a `!reference` tag. Only one level
|
||||
of nesting is supported.
|
|
@ -664,7 +664,7 @@ then included in individual jobs via [`extends`](../ci/yaml/index.md#extends).
|
|||
The `rules` definitions are composed of `if:` conditions and `changes:` patterns,
|
||||
which are also defined in
|
||||
[`rules.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/rules.gitlab-ci.yml)
|
||||
and included in `rules` definitions via [YAML anchors](../ci/yaml/index.md#anchors)
|
||||
and included in `rules` definitions via [YAML anchors](../ci/yaml/yaml_specific_features.md#anchors)
|
||||
|
||||
#### `if:` conditions
|
||||
|
||||
|
|
|
@ -72,6 +72,12 @@ Starting with GitLab version 14.1, free self-managed users running [GitLab EE](.
|
|||
|
||||
1. [Email from GitLab](../../tools/email.md).
|
||||
|
||||
##### Features available in 14.4 and later
|
||||
|
||||
1. [Repository size limit](../../user/admin_area/settings/account_and_limit_settings.md#repository-size-limit).
|
||||
|
||||
1. [Restrict group access by IP address](../../user/group/index.md#restrict-group-access-by-ip-address).
|
||||
|
||||
NOTE:
|
||||
Registration is not yet required for participation, but will be added in a future milestone.
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ my_fuzz_target:
|
|||
- ./gitlab-cov-fuzz run --regression=$REGRESSION -- <your fuzz target>
|
||||
```
|
||||
|
||||
The included template makes available the [hidden job](../../../ci/yaml/index.md#hide-jobs)
|
||||
The included template makes available the [hidden job](../../../ci/jobs/index.md#hide-jobs)
|
||||
`.fuzz_base`, which you must [extend](../../../ci/yaml/index.md#extends) for each of your fuzz
|
||||
targets. Each fuzz target **must** have a separate job. For example, the
|
||||
[go-fuzzing-example project](https://gitlab.com/gitlab-org/security-products/demos/go-fuzzing-example)
|
||||
|
|
|
@ -36,13 +36,10 @@ toggle the list of the milestone bars.
|
|||
|
||||
## Sort and filter the Roadmap
|
||||
|
||||
> - Filtering roadmaps by milestone [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218621) in GitLab 13.7.
|
||||
> - Filtering roadmaps by milestone is [deployed behind a feature flag](../../feature_flags.md), enabled by default.
|
||||
> - Filtering roadmaps by milestone is enabled on GitLab.com.
|
||||
> - Filtering roadmaps by milestone is recommended for production use.
|
||||
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-filtering-roadmaps-by-milestone). **(PREMIUM SELF)**
|
||||
> - Filtering by milestone [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218621) in GitLab 13.7 [with a flag](../../../administration/feature_flags.md) named `roadmap_daterange_filter`. Enabled by default.
|
||||
> - Filtering by epic confidentiality [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218624) in GitLab 13.9.
|
||||
> - Filtering by epic [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218623) in GitLab 13.11.
|
||||
> - Filtering by milestone [feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323917) in GitLab 14.5.
|
||||
|
||||
WARNING:
|
||||
Filtering roadmaps by milestone might not be available to you. Check the **version history** note above for details.
|
||||
|
@ -77,25 +74,6 @@ You can also filter epics in the Roadmap view by the epics':
|
|||
|
||||
Roadmaps can also be [visualized inside an epic](../epics/index.md#roadmap-in-epics).
|
||||
|
||||
### Enable or disable filtering roadmaps by milestone **(PREMIUM SELF)**
|
||||
|
||||
Filtering roadmaps by milestone is under development but ready for production use.
|
||||
It is deployed behind a feature flag that is **enabled by default**.
|
||||
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
|
||||
can opt to disable it.
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:async_filtering)
|
||||
```
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:async_filtering)
|
||||
```
|
||||
|
||||
## Timeline duration
|
||||
|
||||
> - Introduced in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.0.
|
||||
|
@ -104,13 +82,8 @@ Feature.disable(:async_filtering)
|
|||
### Date range presets
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/204994) in GitLab 14.3. [Deployed behind the `roadmap_daterange_filter` flag](../../../administration/feature_flags.md), disabled by default.
|
||||
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/323917) in GitLab 14.3.
|
||||
|
||||
FLAG:
|
||||
On self-managed GitLab, by default this feature is not available. To make it available per group,
|
||||
ask an administrator to [enable the `roadmap_daterange_filter` flag](../../../administration/feature_flags.md).
|
||||
On GitLab.com, this feature is available.
|
||||
The feature is ready for production use.
|
||||
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/323917) in GitLab 14.3.
|
||||
> - [Feature flag `roadmap_daterange_filter` removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72419) in GitLab 14.5.
|
||||
|
||||
Roadmap provides three date range options, each with predetermined timeline duration:
|
||||
|
||||
|
|
|
@ -197,21 +197,22 @@ card includes:
|
|||
Users with the [Reporter and higher roles](../permissions.md) can use all the functionality of the
|
||||
issue board feature to create or delete lists. They can also drag issues from one list to another.
|
||||
|
||||
## How GitLab orders issues in a list
|
||||
|
||||
When visiting a board, issues appear ordered in any list. You're able to change
|
||||
that order by dragging the issues. The changed order is saved, so that anybody who visits the same
|
||||
board later sees the reordering, with some exceptions.
|
||||
## Ordering issues in a list
|
||||
|
||||
When an issue is created, the system assigns a relative order value that is greater than the maximum value
|
||||
of that issue's project or root group. This means the issue will be at the bottom of any issue list that
|
||||
it appears in.
|
||||
|
||||
When you visit a board, issues appear ordered in any list. You're able to change
|
||||
that order by dragging the issues. The changed order is saved, so that anybody who visits the same
|
||||
board later sees the reordering, with some exceptions.
|
||||
|
||||
Any time you drag and reorder the issue, its relative order value changes accordingly.
|
||||
Then, any time that issue appears in any board, the ordering is done according to
|
||||
the updated relative order value. If a user in your GitLab instance
|
||||
drags issue `A` above issue `B`, the ordering is maintained when these two issues are subsequently
|
||||
loaded in any board in the same instance. This could be a different project board or a different group
|
||||
loaded in any board in the same instance.
|
||||
This could be a different project board or a different group
|
||||
board, for example.
|
||||
|
||||
This ordering also affects [issue lists](issues/sorting_issue_lists.md).
|
||||
|
|
|
@ -23,7 +23,7 @@ The available sorting options can change based on the context of the list.
|
|||
For sorting by issue priority, see [Label Priority](../labels.md#label-priority).
|
||||
|
||||
In group and project issue lists, it is also possible to order issues manually,
|
||||
similar to [issue boards](../issue_board.md#how-gitlab-orders-issues-in-a-list).
|
||||
similar to [issue boards](../issue_board.md#ordering-issues-in-a-list).
|
||||
|
||||
## Sorting by popularity
|
||||
|
||||
|
@ -48,7 +48,7 @@ the updated relative order value is used for the ordering.
|
|||
So, if anyone drags issue `A` above issue `B` in your GitLab instance,
|
||||
this ordering is maintained whenever they appear together in any list.
|
||||
|
||||
This ordering also affects [issue boards](../issue_board.md#how-gitlab-orders-issues-in-a-list).
|
||||
This ordering also affects [issue boards](../issue_board.md#ordering-issues-in-a-list).
|
||||
Changing the order in an issue list changes the ordering in an issue board,
|
||||
and vice versa.
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ for details on avoiding two pipelines for a single merge request.
|
|||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211482) in GitLab 13.1.
|
||||
|
||||
When the **Pipelines must succeed** checkbox is checked, [skipped pipelines](../../../ci/yaml/index.md#skip-pipeline) prevent
|
||||
When the **Pipelines must succeed** checkbox is checked, [skipped pipelines](../../../ci/pipelines/index.md#skip-a-pipeline) prevent
|
||||
merge requests from being merged. To change this behavior:
|
||||
|
||||
1. Navigate to your project's **Settings > General** page.
|
||||
|
|
|
@ -41,7 +41,7 @@ to a branch in the repository. When you use the command line, you can commit mul
|
|||
If the project is configured with [GitLab CI/CD](../../../ci/index.md),
|
||||
you trigger a pipeline per push, not per commit.
|
||||
- **Skip pipelines:**
|
||||
Add the [`ci skip`](../../../ci/yaml/index.md#skip-pipeline) keyword to
|
||||
Add the [`ci skip`](../../../ci/pipelines/index.md#skip-a-pipeline) keyword to
|
||||
your commit message to make GitLab CI/CD skip the pipeline.
|
||||
- **Cross-link issues and merge requests:**
|
||||
Use [cross-linking](../issues/crosslinking_issues.md#from-commit-messages)
|
||||
|
|
|
@ -272,6 +272,49 @@ included_attributes:
|
|||
- :updated_at
|
||||
- :filepath
|
||||
- :link_type
|
||||
container_expiration_policy:
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :next_run_at
|
||||
- :project_id
|
||||
- :name_regex
|
||||
- :cadence
|
||||
- :older_than
|
||||
- :keep_n
|
||||
- :enabled
|
||||
- :name_regex_keep
|
||||
project_feature:
|
||||
- :project_id
|
||||
- :merge_requests_access_level
|
||||
- :issues_access_level
|
||||
- :wiki_access_level
|
||||
- :snippets_access_level
|
||||
- :builds_access_level
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :repository_access_level
|
||||
- :pages_access_level
|
||||
- :forking_access_level
|
||||
- :metrics_dashboard_access_level
|
||||
- :operations_access_level
|
||||
- :analytics_access_level
|
||||
- :security_and_compliance_access_level
|
||||
- :container_registry_access_level
|
||||
prometheus_metrics:
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :project_id
|
||||
- :y_label
|
||||
- :unit
|
||||
- :legend
|
||||
- :title
|
||||
- :query
|
||||
- :group
|
||||
- :dashboard_path
|
||||
service_desk_setting:
|
||||
- :project_id
|
||||
- :issue_template_key
|
||||
- :project_key
|
||||
|
||||
# Do not include the following attributes for the models specified.
|
||||
excluded_attributes:
|
||||
|
@ -656,4 +699,13 @@ ee:
|
|||
- :name
|
||||
- :created_at
|
||||
- :updated_at
|
||||
|
||||
project_feature:
|
||||
- :requirements_access_level
|
||||
security_setting:
|
||||
- :project_id
|
||||
- :created_at
|
||||
- :updated_at
|
||||
- :auto_fix_container_scanning
|
||||
- :auto_fix_dast
|
||||
- :auto_fix_dependency_scanning
|
||||
- :auto_fix_sast
|
||||
|
|
|
@ -55,18 +55,15 @@ module Gitlab
|
|||
|
||||
attr_reader :mode, :size_limit, :compression_threshold
|
||||
|
||||
def initialize(
|
||||
worker_class, job,
|
||||
mode: Gitlab::CurrentSettings.sidekiq_job_limiter_mode,
|
||||
compression_threshold: Gitlab::CurrentSettings.sidekiq_job_limiter_compression_threshold_bytes,
|
||||
size_limit: Gitlab::CurrentSettings.sidekiq_job_limiter_limit_bytes
|
||||
)
|
||||
def initialize(worker_class, job)
|
||||
@worker_class = worker_class
|
||||
@job = job
|
||||
|
||||
set_mode(mode)
|
||||
set_compression_threshold(compression_threshold)
|
||||
set_size_limit(size_limit)
|
||||
current_settings = Gitlab::CurrentSettings.current_application_settings
|
||||
|
||||
@mode = current_settings.sidekiq_job_limiter_mode
|
||||
@compression_threshold = current_settings.sidekiq_job_limiter_compression_threshold_bytes
|
||||
@size_limit = current_settings.sidekiq_job_limiter_limit_bytes
|
||||
end
|
||||
|
||||
def validate!
|
||||
|
@ -90,30 +87,6 @@ module Gitlab
|
|||
|
||||
private
|
||||
|
||||
def set_mode(mode)
|
||||
@mode = (mode || TRACK_MODE).to_s.strip
|
||||
unless MODES.include?(@mode)
|
||||
::Sidekiq.logger.warn "Invalid Sidekiq size limiter mode: #{@mode}. Fallback to #{TRACK_MODE} mode."
|
||||
@mode = TRACK_MODE
|
||||
end
|
||||
end
|
||||
|
||||
def set_compression_threshold(compression_threshold)
|
||||
@compression_threshold = (compression_threshold || DEFAULT_COMPRESSION_THRESHOLD_BYTES).to_i
|
||||
if @compression_threshold <= 0
|
||||
::Sidekiq.logger.warn "Invalid Sidekiq size limiter compression threshold: #{@compression_threshold}"
|
||||
@compression_threshold = DEFAULT_COMPRESSION_THRESHOLD_BYTES
|
||||
end
|
||||
end
|
||||
|
||||
def set_size_limit(size_limit)
|
||||
@size_limit = (size_limit || DEFAULT_SIZE_LIMIT).to_i
|
||||
if @size_limit < 0
|
||||
::Sidekiq.logger.warn "Invalid Sidekiq size limiter limit: #{@size_limit}"
|
||||
@size_limit = DEFAULT_SIZE_LIMIT
|
||||
end
|
||||
end
|
||||
|
||||
def exceed_limit_error(job_args)
|
||||
ExceedLimitError.new(@worker_class, job_args.bytesize, @size_limit).tap do |exception|
|
||||
# This should belong to Gitlab::ErrorTracking. We'll remove this
|
||||
|
|
|
@ -37127,6 +37127,9 @@ msgstr ""
|
|||
msgid "User and IP rate limits"
|
||||
msgstr ""
|
||||
|
||||
msgid "User cap"
|
||||
msgstr ""
|
||||
|
||||
msgid "User created at"
|
||||
msgstr ""
|
||||
|
||||
|
@ -38429,6 +38432,9 @@ msgstr ""
|
|||
msgid "When merge requests and commits in the default branch close, any issues they reference also close."
|
||||
msgstr ""
|
||||
|
||||
msgid "When the number of active users exceeds this number, additional users must be %{user_cap_docs_link_start}approved by an owner%{user_cap_docs_link_end}. Leave empty if you don't want to enforce approvals."
|
||||
msgstr ""
|
||||
|
||||
msgid "When this merge request is accepted"
|
||||
msgid_plural "When these merge requests are accepted"
|
||||
msgstr[0] ""
|
||||
|
@ -39678,9 +39684,6 @@ msgstr ""
|
|||
msgid "Zentao issues"
|
||||
msgstr ""
|
||||
|
||||
msgid "Zentao user"
|
||||
msgstr ""
|
||||
|
||||
msgid "ZentaoIntegration|An error occurred while requesting data from the ZenTao service."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -9,28 +9,33 @@ jest.mock('~/boards/issue_board_filters');
|
|||
describe('IssueBoardFilter', () => {
|
||||
let wrapper;
|
||||
|
||||
const createComponent = () => {
|
||||
const createComponent = ({ epicFeatureAvailable = false } = {}) => {
|
||||
wrapper = shallowMount(IssueBoardFilteredSpec, {
|
||||
props: { fullPath: '', boardType: '' },
|
||||
propsData: { fullPath: 'gitlab-org', boardType: 'group' },
|
||||
provide: {
|
||||
epicFeatureAvailable,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
let fetchAuthorsSpy;
|
||||
let fetchLabelsSpy;
|
||||
beforeEach(() => {
|
||||
fetchAuthorsSpy = jest.fn();
|
||||
fetchLabelsSpy = jest.fn();
|
||||
|
||||
issueBoardFilters.mockReturnValue({
|
||||
fetchAuthors: fetchAuthorsSpy,
|
||||
fetchLabels: fetchLabelsSpy,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
describe('default', () => {
|
||||
let fetchAuthorsSpy;
|
||||
let fetchLabelsSpy;
|
||||
beforeEach(() => {
|
||||
fetchAuthorsSpy = jest.fn();
|
||||
fetchLabelsSpy = jest.fn();
|
||||
|
||||
issueBoardFilters.mockReturnValue({
|
||||
fetchAuthors: fetchAuthorsSpy,
|
||||
fetchLabels: fetchLabelsSpy,
|
||||
});
|
||||
|
||||
createComponent();
|
||||
});
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import IssuableApp from '~/issue_show/components/app.vue';
|
|||
import DescriptionComponent from '~/issue_show/components/description.vue';
|
||||
import IncidentTabs from '~/issue_show/components/incidents/incident_tabs.vue';
|
||||
import PinnedLinks from '~/issue_show/components/pinned_links.vue';
|
||||
import { IssuableStatus, IssuableStatusText } from '~/issue_show/constants';
|
||||
import { IssuableStatus, IssuableStatusText, POLLING_DELAY } from '~/issue_show/constants';
|
||||
import eventHub from '~/issue_show/event_hub';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { visitUrl } from '~/lib/utils/url_utility';
|
||||
|
@ -643,4 +643,40 @@ describe('Issuable output', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('taskListUpdateStarted', () => {
|
||||
it('stops polling', () => {
|
||||
jest.spyOn(wrapper.vm.poll, 'stop');
|
||||
|
||||
wrapper.vm.taskListUpdateStarted();
|
||||
|
||||
expect(wrapper.vm.poll.stop).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('taskListUpdateSucceeded', () => {
|
||||
it('enables polling', () => {
|
||||
jest.spyOn(wrapper.vm.poll, 'enable');
|
||||
jest.spyOn(wrapper.vm.poll, 'makeDelayedRequest');
|
||||
|
||||
wrapper.vm.taskListUpdateSucceeded();
|
||||
|
||||
expect(wrapper.vm.poll.enable).toHaveBeenCalled();
|
||||
expect(wrapper.vm.poll.makeDelayedRequest).toHaveBeenCalledWith(POLLING_DELAY);
|
||||
});
|
||||
});
|
||||
|
||||
describe('taskListUpdateFailed', () => {
|
||||
it('enables polling and calls updateStoreState', () => {
|
||||
jest.spyOn(wrapper.vm.poll, 'enable');
|
||||
jest.spyOn(wrapper.vm.poll, 'makeDelayedRequest');
|
||||
jest.spyOn(wrapper.vm, 'updateStoreState');
|
||||
|
||||
wrapper.vm.taskListUpdateFailed();
|
||||
|
||||
expect(wrapper.vm.poll.enable).toHaveBeenCalled();
|
||||
expect(wrapper.vm.poll.makeDelayedRequest).toHaveBeenCalledWith(POLLING_DELAY);
|
||||
expect(wrapper.vm.updateStoreState).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -114,6 +114,8 @@ describe('Description component', () => {
|
|||
dataType: 'issuableType',
|
||||
fieldName: 'description',
|
||||
selector: '.detail-page-description',
|
||||
onUpdate: expect.any(Function),
|
||||
onSuccess: expect.any(Function),
|
||||
onError: expect.any(Function),
|
||||
lockVersion: 0,
|
||||
});
|
||||
|
@ -150,6 +152,26 @@ describe('Description component', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('taskListUpdateStarted', () => {
|
||||
it('emits event to parent', () => {
|
||||
const spy = jest.spyOn(vm, '$emit');
|
||||
|
||||
vm.taskListUpdateStarted();
|
||||
|
||||
expect(spy).toHaveBeenCalledWith('taskListUpdateStarted');
|
||||
});
|
||||
});
|
||||
|
||||
describe('taskListUpdateSuccess', () => {
|
||||
it('emits event to parent', () => {
|
||||
const spy = jest.spyOn(vm, '$emit');
|
||||
|
||||
vm.taskListUpdateSuccess();
|
||||
|
||||
expect(spy).toHaveBeenCalledWith('taskListUpdateSucceeded');
|
||||
});
|
||||
});
|
||||
|
||||
describe('taskListUpdateError', () => {
|
||||
it('should create flash notification and emit an event to parent', () => {
|
||||
const msg =
|
||||
|
|
|
@ -125,6 +125,7 @@ describe('TaskList', () => {
|
|||
const response = { data: { lock_version: 3 } };
|
||||
jest.spyOn(taskList, 'enableTaskListItems').mockImplementation(() => {});
|
||||
jest.spyOn(taskList, 'disableTaskListItems').mockImplementation(() => {});
|
||||
jest.spyOn(taskList, 'onUpdate').mockImplementation(() => {});
|
||||
jest.spyOn(taskList, 'onSuccess').mockImplementation(() => {});
|
||||
jest.spyOn(axios, 'patch').mockReturnValue(Promise.resolve(response));
|
||||
|
||||
|
@ -151,8 +152,11 @@ describe('TaskList', () => {
|
|||
},
|
||||
};
|
||||
|
||||
taskList
|
||||
.update(event)
|
||||
const update = taskList.update(event);
|
||||
|
||||
expect(taskList.onUpdate).toHaveBeenCalled();
|
||||
|
||||
update
|
||||
.then(() => {
|
||||
expect(taskList.disableTaskListItems).toHaveBeenCalledWith(event);
|
||||
expect(axios.patch).toHaveBeenCalledWith(endpoint, patchData);
|
||||
|
@ -168,12 +172,17 @@ describe('TaskList', () => {
|
|||
it('should handle request error and enable task list items', (done) => {
|
||||
const response = { data: { error: 1 } };
|
||||
jest.spyOn(taskList, 'enableTaskListItems').mockImplementation(() => {});
|
||||
jest.spyOn(taskList, 'onUpdate').mockImplementation(() => {});
|
||||
jest.spyOn(taskList, 'onError').mockImplementation(() => {});
|
||||
jest.spyOn(axios, 'patch').mockReturnValue(Promise.reject({ response })); // eslint-disable-line prefer-promise-reject-errors
|
||||
|
||||
const event = { detail: {} };
|
||||
taskList
|
||||
.update(event)
|
||||
|
||||
const update = taskList.update(event);
|
||||
|
||||
expect(taskList.onUpdate).toHaveBeenCalled();
|
||||
|
||||
update
|
||||
.then(() => {
|
||||
expect(taskList.enableTaskListItems).toHaveBeenCalledWith(event);
|
||||
expect(taskList.onError).toHaveBeenCalledWith(response.data);
|
||||
|
|
|
@ -81,24 +81,28 @@ RSpec.describe Gitlab::ImportExport::AttributesPermitter do
|
|||
let(:attributes_permitter) { described_class.new }
|
||||
|
||||
where(:relation_name, :permitted_attributes_defined) do
|
||||
:user | false
|
||||
:author | false
|
||||
:ci_cd_settings | true
|
||||
:metrics_setting | true
|
||||
:project_badges | true
|
||||
:pipeline_schedules | true
|
||||
:error_tracking_setting | true
|
||||
:auto_devops | true
|
||||
:boards | true
|
||||
:custom_attributes | true
|
||||
:labels | true
|
||||
:protected_branches | true
|
||||
:protected_tags | true
|
||||
:create_access_levels | true
|
||||
:merge_access_levels | true
|
||||
:push_access_levels | true
|
||||
:releases | true
|
||||
:links | true
|
||||
:user | false
|
||||
:author | false
|
||||
:ci_cd_settings | true
|
||||
:metrics_setting | true
|
||||
:project_badges | true
|
||||
:pipeline_schedules | true
|
||||
:error_tracking_setting | true
|
||||
:auto_devops | true
|
||||
:boards | true
|
||||
:custom_attributes | true
|
||||
:labels | true
|
||||
:protected_branches | true
|
||||
:protected_tags | true
|
||||
:create_access_levels | true
|
||||
:merge_access_levels | true
|
||||
:push_access_levels | true
|
||||
:releases | true
|
||||
:links | true
|
||||
:container_expiration_policy | true
|
||||
:project_feature | true
|
||||
:prometheus_metrics | true
|
||||
:service_desk_setting | true
|
||||
end
|
||||
|
||||
with_them do
|
||||
|
|
|
@ -59,111 +59,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
|
|||
expect(validator.size_limit).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the input mode is valid' do
|
||||
it 'does not log a warning message' do
|
||||
expect(::Sidekiq.logger).not_to receive(:warn)
|
||||
|
||||
described_class.new(TestSizeLimiterWorker, job_payload, mode: 'track')
|
||||
described_class.new(TestSizeLimiterWorker, job_payload, mode: 'compress')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the input mode is invalid' do
|
||||
it 'defaults to track mode and logs a warning message' do
|
||||
expect(::Sidekiq.logger).to receive(:warn).with('Invalid Sidekiq size limiter mode: invalid. Fallback to track mode.')
|
||||
|
||||
validator = described_class.new(TestSizeLimiterWorker, job_payload, mode: 'invalid')
|
||||
|
||||
expect(validator.mode).to eql('track')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the input mode is empty' do
|
||||
it 'defaults to track mode' do
|
||||
expect(::Sidekiq.logger).not_to receive(:warn)
|
||||
|
||||
validator = described_class.new(TestSizeLimiterWorker, job_payload, mode: nil)
|
||||
|
||||
expect(validator.mode).to eql('track')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the size input is valid' do
|
||||
it 'does not log a warning message' do
|
||||
expect(::Sidekiq.logger).not_to receive(:warn)
|
||||
|
||||
described_class.new(TestSizeLimiterWorker, job_payload, size_limit: 300)
|
||||
described_class.new(TestSizeLimiterWorker, job_payload, size_limit: 0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the size input is invalid' do
|
||||
it 'logs a warning message' do
|
||||
expect(::Sidekiq.logger).to receive(:warn).with('Invalid Sidekiq size limiter limit: -1')
|
||||
|
||||
validator = described_class.new(TestSizeLimiterWorker, job_payload, size_limit: -1)
|
||||
|
||||
expect(validator.size_limit).to be(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the size input is empty' do
|
||||
it 'defaults to 0' do
|
||||
expect(::Sidekiq.logger).not_to receive(:warn)
|
||||
|
||||
validator = described_class.new(TestSizeLimiterWorker, job_payload, size_limit: nil)
|
||||
|
||||
expect(validator.size_limit).to be(described_class::DEFAULT_SIZE_LIMIT)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the compression threshold is valid' do
|
||||
it 'does not log a warning message' do
|
||||
expect(::Sidekiq.logger).not_to receive(:warn)
|
||||
|
||||
described_class.new(TestSizeLimiterWorker, job_payload, compression_threshold: 300)
|
||||
described_class.new(TestSizeLimiterWorker, job_payload, compression_threshold: 1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the compression threshold is negative' do
|
||||
it 'logs a warning message' do
|
||||
expect(::Sidekiq.logger).to receive(:warn).with('Invalid Sidekiq size limiter compression threshold: -1')
|
||||
|
||||
described_class.new(TestSizeLimiterWorker, job_payload, compression_threshold: -1)
|
||||
end
|
||||
|
||||
it 'falls back to the default' do
|
||||
validator = described_class.new(TestSizeLimiterWorker, job_payload, compression_threshold: -1)
|
||||
|
||||
expect(validator.compression_threshold).to be(100_000)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the compression threshold is zero' do
|
||||
it 'logs a warning message' do
|
||||
expect(::Sidekiq.logger).to receive(:warn).with('Invalid Sidekiq size limiter compression threshold: 0')
|
||||
|
||||
described_class.new(TestSizeLimiterWorker, job_payload, compression_threshold: 0)
|
||||
end
|
||||
|
||||
it 'falls back to the default' do
|
||||
validator = described_class.new(TestSizeLimiterWorker, job_payload, compression_threshold: 0)
|
||||
|
||||
expect(validator.compression_threshold).to be(100_000)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the compression threshold is empty' do
|
||||
it 'defaults to 100_000' do
|
||||
expect(::Sidekiq.logger).not_to receive(:warn)
|
||||
|
||||
validator = described_class.new(TestSizeLimiterWorker, job_payload)
|
||||
|
||||
expect(validator.compression_threshold).to be(100_000)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'validate limit job payload size' do
|
||||
|
@ -171,20 +66,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
|
|||
let(:compression_threshold) { nil }
|
||||
let(:mode) { 'track' }
|
||||
|
||||
context 'when size limit negative' do
|
||||
let(:size_limit) { -1 }
|
||||
|
||||
it 'does not track jobs' do
|
||||
expect(Gitlab::ErrorTracking).not_to receive(:track_exception)
|
||||
|
||||
validate.call(TestSizeLimiterWorker, job_payload(a: 'a' * 300))
|
||||
end
|
||||
|
||||
it 'does not raise exception' do
|
||||
expect { validate.call(TestSizeLimiterWorker, job_payload(a: 'a' * 300)) }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'when size limit is 0' do
|
||||
let(:size_limit) { 0 }
|
||||
let(:job) { job_payload(a: 'a' * 300) }
|
||||
|
@ -438,36 +319,20 @@ RSpec.describe Gitlab::SidekiqMiddleware::SizeLimiter::Validator, :aggregate_fai
|
|||
end
|
||||
|
||||
describe '#validate!' do
|
||||
context 'when creating an instance with the related configuration variables' do
|
||||
let(:validate) do
|
||||
->(worker_clas, job) do
|
||||
described_class.new(worker_class, job).validate!
|
||||
end
|
||||
let(:validate) do
|
||||
->(worker_class, job) do
|
||||
described_class.new(worker_class, job).validate!
|
||||
end
|
||||
|
||||
before do
|
||||
stub_application_setting(
|
||||
sidekiq_job_limiter_mode: mode,
|
||||
sidekiq_job_limiter_compression_threshold_bytes: compression_threshold,
|
||||
sidekiq_job_limiter_limit_bytes: size_limit
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'validate limit job payload size'
|
||||
end
|
||||
|
||||
context 'when creating an instance with mode and size limit' do
|
||||
let(:validate) do
|
||||
->(worker_clas, job) do
|
||||
validator = described_class.new(
|
||||
worker_class, job,
|
||||
mode: mode, size_limit: size_limit, compression_threshold: compression_threshold
|
||||
)
|
||||
validator.validate!
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'validate limit job payload size'
|
||||
before do
|
||||
stub_application_setting(
|
||||
sidekiq_job_limiter_mode: mode,
|
||||
sidekiq_job_limiter_compression_threshold_bytes: compression_threshold,
|
||||
sidekiq_job_limiter_limit_bytes: size_limit
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'validate limit job payload size'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -80,7 +80,7 @@ RSpec.describe BulkImports::FileTransfer::ProjectConfig do
|
|||
|
||||
describe '#tree_relation_definition_for' do
|
||||
it 'returns relation definition' do
|
||||
expected = { service_desk_setting: { except: [:outgoing_name, :file_template_project_id], include: [] } }
|
||||
expected = { service_desk_setting: { except: [:outgoing_name, :file_template_project_id], include: [], only: %i[project_id issue_template_key project_key] } }
|
||||
|
||||
expect(subject.tree_relation_definition_for('service_desk_setting')).to eq(expected)
|
||||
end
|
||||
|
|
|
@ -50,8 +50,6 @@
|
|||
- "./spec/requests/api/graphql/packages/pypi_spec.rb"
|
||||
- "./spec/requests/api/graphql/project/packages_spec.rb"
|
||||
- "./spec/requests/api/package_files_spec.rb"
|
||||
- "./spec/services/environments/stop_service_spec.rb"
|
||||
- "./spec/services/merge_requests/post_merge_service_spec.rb"
|
||||
- "./spec/services/packages/conan/create_package_file_service_spec.rb"
|
||||
- "./spec/services/packages/create_package_file_service_spec.rb"
|
||||
- "./spec/services/packages/generic/create_package_file_service_spec.rb"
|
||||
|
|
Loading…
Reference in a new issue