Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-08-23 09:09:29 +00:00
parent 2c9bd42a67
commit 04eb990a84
42 changed files with 11882 additions and 414 deletions

View File

@ -359,10 +359,10 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/api/jobs.md @marcel.amirault
/doc/api/keys.md @aqualls
/doc/api/labels.md @msedlakjakubowski
/doc/api/license.md @kpaizee
/doc/api/license.md @fneill
/doc/api/linked_epics.md @msedlakjakubowski
/doc/api/lint.md @marcel.amirault
/doc/api/managed_licenses.md @kpaizee
/doc/api/managed_licenses.md @fneill
/doc/api/markdown.md @aqualls
/doc/api/members.md @eread
/doc/api/merge_request_approvals.md @aqualls

View File

@ -198,32 +198,6 @@ Layout/HashAlignment:
- 'spec/models/user_spec.rb'
- 'spec/presenters/clusters/cluster_presenter_spec.rb'
- 'spec/presenters/project_presenter_spec.rb'
- 'spec/requests/api/ci/job_artifacts_spec.rb'
- 'spec/requests/api/ci/jobs_spec.rb'
- 'spec/requests/api/ci/runner/jobs_request_post_spec.rb'
- 'spec/requests/api/feature_flags_spec.rb'
- 'spec/requests/api/graphql/ci/config_spec.rb'
- 'spec/requests/api/graphql/ci/group_variables_spec.rb'
- 'spec/requests/api/graphql/ci/instance_variables_spec.rb'
- 'spec/requests/api/graphql/ci/project_variables_spec.rb'
- 'spec/requests/api/graphql/ci/runner_spec.rb'
- 'spec/requests/api/graphql/ci/runners_spec.rb'
- 'spec/requests/api/graphql/mutations/releases/update_spec.rb'
- 'spec/requests/api/graphql/project/issue/design_collection/version_spec.rb'
- 'spec/requests/api/graphql/project/terraform/state_spec.rb'
- 'spec/requests/api/graphql/project/terraform/states_spec.rb'
- 'spec/requests/api/graphql/query_spec.rb'
- 'spec/requests/api/groups_spec.rb'
- 'spec/requests/api/internal/base_spec.rb'
- 'spec/requests/api/issues/get_group_issues_spec.rb'
- 'spec/requests/api/projects_spec.rb'
- 'spec/requests/api/suggestions_spec.rb'
- 'spec/requests/api/unleash_spec.rb'
- 'spec/requests/git_http_spec.rb'
- 'spec/requests/oauth_tokens_spec.rb'
- 'spec/requests/openid_connect_spec.rb'
- 'spec/requests/projects/environments_controller_spec.rb'
- 'spec/requests/projects/merge_requests_discussions_spec.rb'
- 'spec/routing/project_routing_spec.rb'
- 'spec/serializers/ci/lint/job_entity_spec.rb'
- 'spec/serializers/container_repository_entity_spec.rb'

View File

@ -18,5 +18,10 @@ module Types
field :issuable_dates_updated, subscription: Subscriptions::IssuableUpdated, null: true,
description: 'Triggered when the due date or start date of an issuable is updated.'
field :merge_request_reviewers_updated,
subscription: Subscriptions::IssuableUpdated,
null: true,
description: 'Triggered when the reviewers of a merge request are updated.'
end
end

View File

@ -183,58 +183,6 @@ module NotificationRecipients
add_recipients(target.subscribers(project), :subscription, NotificationReason::SUBSCRIBED)
end
# rubocop: disable CodeReuse/ActiveRecord
def user_ids_notifiable_on(resource, notification_level = nil)
return [] unless resource
scope = resource.notification_settings
if notification_level
scope = scope.where(level: NotificationSetting.levels[notification_level])
end
scope.pluck(:user_id)
end
# rubocop: enable CodeReuse/ActiveRecord
# Build a list of user_ids based on project notification settings
def select_project_members_ids(global_setting, user_ids_global_level_watch)
user_ids = user_ids_notifiable_on(project, :watch)
# If project setting is global, add to watch list if global setting is watch
user_ids + (global_setting & user_ids_global_level_watch)
end
# Build a list of user_ids based on group notification settings
def select_group_members_ids(group, project_members, global_setting, user_ids_global_level_watch)
uids = user_ids_notifiable_on(group, :watch)
# Group setting is global, add to user_ids list if global setting is watch
uids + (global_setting & user_ids_global_level_watch) - project_members
end
# rubocop: disable CodeReuse/ActiveRecord
def user_ids_with_global_level_watch(ids)
settings_with_global_level_of(:watch, ids).pluck(:user_id)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def user_ids_with_global_level_custom(ids, action)
settings_with_global_level_of(:custom, ids).pluck(:user_id)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def settings_with_global_level_of(level, ids)
NotificationSetting.where(
user_id: ids,
source_type: nil,
level: NotificationSetting.levels[level]
)
end
# rubocop: enable CodeReuse/ActiveRecord
def add_labels_subscribers(labels: nil)
return unless target.respond_to? :labels

View File

@ -1232,6 +1232,7 @@ GET /groups/:id/hooks/:hook_id
"url": "http://example.com/hook",
"group_id": 3,
"push_events": true,
"push_events_branch_filter": "",
"issues_events": true,
"confidential_issues_events": true,
"merge_requests_events": true,
@ -1258,10 +1259,11 @@ POST /groups/:id/hooks
```
| Attribute | Type | Required | Description |
| -----------------------------| -------------- | ---------| ----------- |
| -----------------------------| -------------- |----------| ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
| `url` | string | yes | The hook URL |
| `push_events` | boolean | no | Trigger hook on push events |
| `push_events_branch_filter` | string | No | Trigger hook on push events for matching branches only. |
| `issues_events` | boolean | no | Trigger hook on issues events |
| `confidential_issues_events` | boolean | no | Trigger hook on confidential issues events |
| `merge_requests_events` | boolean | no | Trigger hook on merge requests events |
@ -1291,6 +1293,7 @@ PUT /groups/:id/hooks/:hook_id
| `hook_id` | integer | yes | The ID of the group hook |
| `url` | string | yes | The hook URL |
| `push_events` | boolean | no | Trigger hook on push events |
| `push_events_branch_filter` | string | No | Trigger hook on push events for matching branches only. |
| `issues_events` | boolean | no | Trigger hook on issues events |
| `confidential_issues_events` | boolean | no | Trigger hook on confidential issues events |
| `merge_requests_events` | boolean | no | Trigger hook on merge requests events |

View File

@ -125,7 +125,7 @@ As an experiment, we want to introduce a `local` reviewer status for database re
focusing on work from a team/stage, but not outside of it. This helps to focus and build great domain
knowledge. We are not introducing changes to the reviewer roulette till we evaluate the impact and feedback from this
experiment. We ask to respect reviewers who decline reviews based on their focus on `local` reviews. For tracking purposes,
please use in your personal YAML file entry: `- reviewer database local` instead of `- reviewer database`.
please use in your personal YAML file entry: `- reviewer database local` instead of `- reviewer database`.
### Approval guidelines
@ -330,7 +330,7 @@ Maintainers are the DRI of assuring that the acceptance criteria of a merge requ
In general, [quality is everyones responsibility](https://about.gitlab.com/handbook/engineering/quality/),
but maintainers of an MR are held responsible for **ensuring** that an MR meets those general quality standards.
If a maintainer feels that an MR is substantial enough, or requires a [domain expert](#domain-experts),
If a maintainer feels that an MR is substantial enough, or requires a [domain expert](#domain-experts),
maintainers have the discretion to request a review from another reviewer, or maintainer. Here are some
examples of maintainers proactively doing this during review:
@ -419,7 +419,7 @@ first time.
codebase. Thorough descriptions help all reviewers understand your request
and test effectively.
- If you know your change depends on another being merged first, note it in the
description and set a [merge request dependency](../user/project/merge_requests/merge_request_dependencies.md).
description and set a [merge request dependency](../user/project/merge_requests/dependencies.md).
- Be grateful for the reviewer's suggestions. ("Good call. I'll make that change.")
- Don't take it personally. The review is of the code, not of you.
- Explain why the code exists. ("It's like that because of these reasons. Would
@ -490,7 +490,7 @@ experience, refactors the existing code). Then:
optionally resolve within the merge request or follow-up at a later stage.
- There's a [Chrome/Firefox add-on](https://gitlab.com/conventionalcomments/conventional-comments-button) which you can use to apply [Conventional Comment](https://conventionalcomments.org/) prefixes.
- Ensure there are no open dependencies. Check [linked issues](../user/project/issues/related_issues.md) for blockers. Clarify with the authors
if necessary. If blocked by one or more open MRs, set an [MR dependency](../user/project/merge_requests/merge_request_dependencies.md).
if necessary. If blocked by one or more open MRs, set an [MR dependency](../user/project/merge_requests/dependencies.md).
- After a round of line notes, it can be helpful to post a summary note such as
"Looks good to me", or "Just a couple things to address."
- Let the author know if changes are required following your review.

View File

@ -83,6 +83,31 @@ You can silence deprecation warnings by setting the environment variable
SILENCE_DEPRECATIONS=1 bin/rspec spec/models/project_spec.rb
```
### Test order
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93137) in GitLab 15.3.
All new spec files are run in [random order](https://gitlab.com/gitlab-org/gitlab/-/issues/337399)
to surface flaky tests that are dependent on test order.
When randomized:
- We append the `(order random)` to example group description.
- The used seed is shown in the spec output below the test suite summary. For example, `Randomized with seed 27443`.
For a list of spec files which are still run in defined order, see [`rspec_order_todo.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/support/rspec_order_todo.yml).
To make spec files run in random order, check their order dependency with:
```shell
scripts/rspec_check_order_dependence spec/models/project_spec.rb
```
If the specs pass the check the script removes them from
[`rspec_order_todo.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/support/rspec_order_todo.yml) automatically.
If the specs fail the check they must be fixed before than can run in random order.
### Test speed
GitLab has a massive test suite that, without [parallelization](../pipelines.md#test-suite-parallelization), can take hours

View File

@ -12,13 +12,16 @@ Configure your groups to control group permissions and access.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/34370) in GitLab 12.8.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/224129) in GitLab 13.4.
> - [Moved to Settings/Repository](https://gitlab.com/gitlab-org/gitlab/-/issues/220365) in GitLab 15.4.
Group push rules allow group maintainers to set
[push rules](../project/repository/push_rules.md) for newly created projects in the specific group.
To configure push rules for a group:
1. Go to the groups's **Push Rules** page.
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Settings > Repository** page.
1. Expand the **Pre-defined push rules** section.
1. Select the settings you want.
1. Select **Save Push Rules**.
@ -132,8 +135,8 @@ To prevent sharing outside of the group's hierarchy:
## Prevent a project from being shared with groups
Prevent projects in a group from
[sharing a project with another group](../project/members/share_project_with_groups.md)
Prevent projects in a group from
[sharing a project with another group](../project/members/share_project_with_groups.md)
to enable tighter control over project access.
To prevent a project from being shared with other groups:

View File

@ -0,0 +1,163 @@
---
stage: Create
group: Code Review
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, concepts
---
# Merge request dependencies **(PREMIUM)**
A single feature can span several merge requests, spread out across multiple projects,
and the order in which the work merges can be significant. Use merge request dependencies
when it's important to merge work in a specific order. Some examples:
- Ensure changes to a required library are merged before changes to a project that
imports the library.
- Prevent a documentation-only merge request from merging before the feature work
is itself merged.
- Require a merge request updating a permissions matrix to merge, before merging work
from someone who hasn't yet been granted permissions.
If your project `me/myexample` imports a library from `myfriend/library`,
you might want to update your project to use a new feature in `myfriend/library`.
However, if you merge changes to your project before the external library adds the
new feature, you would break the default branch in your project. A merge request
dependency prevents your work from merging too soon:
```mermaid
graph TB
A['me/myexample' project]
B['myfriend/library' project]
C[Merge request #1:<br>Create new version 2.5]
D[Merge request #2:<br>Add version 2.5<br>to build]
A-->|contains| D
B---->|contains| C
D-.->|depends on| C
C-.->|blocks| D
```
You could mark your `me/myexample` merge request as a [draft](drafts.md)
and explain why in the comments. However, this approach is manual and does not scale, especially
if your merge request relies on several others in multiple projects. Instead,
use the draft (or ready) state to track the readiness of an individual
merge request, and a merge request dependency to enforce merge order.
NOTE:
Merge request dependencies are a **PREMIUM** feature, but this restriction is
enforced only for the dependent merge request. A merge request in a **PREMIUM**
project can depend on a merge request in a **FREE** project, but a merge request
in a **FREE** project cannot be marked as dependent.
## View dependencies for a merge request
If a merge request is dependent on another, the merge request reports section shows
information about the dependency:
![Dependencies in merge request widget](img/dependencies_view_v15_3.png)
To view dependency information on a merge request:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Scroll to the merge request reports area. Dependent merge requests display information
about the total number of dependencies set, such as
**(status-warning)** **Depends on 1 merge request being merged**.
1. Select **Expand** to view the title, milestone, assignee, and pipeline status
of each dependency.
Until your merge request's dependencies all merge, your merge request
cannot be merged. The message
**Merge blocked: you can only merge after the above items are resolved** displays.
### Closed merge requests
Closed merge requests still prevent their dependents from being merged, because
a merge request can close regardless of whether or not the planned work actually merged.
If a merge request closes and the dependency is no longer relevant,
remove it as a dependency to unblock the dependent merge request.
## Create a new dependent merge request
When you create a new merge request, you can prevent it from merging until after
other specific work merges, even if the merge request is in a different project.
Prerequisites:
- You must have at least the Developer role or be allowed to create merge requests in the project.
- The dependent merge request must be in a project in a **PREMIUM** or higher tier.
To create a new merge request and mark it as dependent on another:
1. [Create a new merge request](creating_merge_requests.md).
1. In **Merge request dependencies**, paste either the reference or the full URL
to the merge requests that should merge before this work merges. References
are in the form of `path/to/project!merge_request_id`.
1. Select **Create merge request**.
## Edit a merge request to add a dependency
You can edit an existing merge request and mark it as dependent on another.
Prerequisite:
- You must have at least the Developer role or be allowed to edit merge requests in the project.
To do this:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Select **Edit**.
1. In **Merge request dependencies**, paste either the reference or the full URL
to the merge requests that should merge before this work merges. References
are in the form of `path/to/project!merge_request_id`.
## Remove a dependency from a merge request
You can edit a dependent merge request and remove a dependency.
Prerequisite:
- You must have a role in the project that allows you to edit merge requests.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Select **Edit**.
1. Scroll to **Merge request dependencies** and select **Remove** next to the reference
for each dependency you want to remove.
NOTE:
Dependencies for merge requests you don't have access to are displayed as
**1 inaccessible merge request**, and can be removed the same way.
1. Select **Save changes**.
## Troubleshooting
### API support for managing merge request dependencies
No API support exists for managing dependencies. For more information, read
[issue #12551](https://gitlab.com/gitlab-org/gitlab/-/issues/12551).
### Preserving dependencies on project import or export
Dependencies are not preserved when projects are imported or exported. For more
information, read [issue #12549](https://gitlab.com/gitlab-org/gitlab/-/issues/12549).
### Complex merge order dependencies are unsupported
GitLab supports direct dependencies between merge requests, but does not support
[indirect (nested) dependencies](https://gitlab.com/gitlab-org/gitlab/-/issues/11393).
Acceptable dependency patterns include:
- A single merge request can directly depend on a single merge request.
- A single merge request can directly depend on multiple merge requests.
- Multiple merge requests can directly depend on a single merge request.
The indirect, nested dependency between `myfriend/library!10` and `mycorp/example!100` shown in this example is not supported:
```mermaid
graph LR;
A[myfriend/library!10]-->|depends on| B[herfriend/another-lib!1]
B-->|depends on| C[mycorp/example!100]
```

View File

@ -66,7 +66,7 @@ After you have created the merge request, you can also:
- [Discuss](../../discussions/index.md) your implementation with your team in the merge request thread.
- [Perform inline code reviews](reviews/index.md).
- Add [merge request dependencies](merge_request_dependencies.md) to restrict it to be merged only when other merge requests have been merged.
- Add [merge request dependencies](dependencies.md) to restrict it to be merged only when other merge requests have been merged.
- Preview continuous integration [pipelines on the merge request widget](widgets.md).
- Preview how your changes look directly on your deployed application with [Review Apps](widgets.md#live-preview-with-review-apps).
- [Allow collaboration on merge requests across forks](allow_collaboration.md).

View File

@ -1,163 +1,11 @@
---
stage: Create
group: Code Review
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, concepts
redirect_to: 'dependencies.md'
remove_date: '2022-11-22'
---
# Merge request dependencies **(PREMIUM)**
This document was moved to [another location](dependencies.md).
A single feature can span several merge requests, spread out across multiple projects,
and the order in which the work merges can be significant. Use merge request dependencies
when it's important to merge work in a specific order. Some examples:
- Ensure changes to a required library are merged before changes to a project that
imports the library.
- Prevent a documentation-only merge request from merging before the feature work
is itself merged.
- Require a merge request updating a permissions matrix to merge, before merging work
from someone who hasn't yet been granted permissions.
If your project `me/myexample` imports a library from `myfriend/library`,
you might want to update your project to use a new feature in `myfriend/library`.
However, if you merge changes to your project before the external library adds the
new feature, you would break the default branch in your project. A merge request
dependency prevents your work from merging too soon:
```mermaid
graph TB
A['me/myexample' project]
B['myfriend/library' project]
C[Merge request #1:<br>Create new version 2.5]
D[Merge request #2:<br>Add version 2.5<br>to build]
A-->|contains| D
B---->|contains| C
D-.->|depends on| C
C-.->|blocks| D
```
You could mark your `me/myexample` merge request as a [draft](drafts.md)
and explain why in the comments. However, this approach is manual and does not scale, especially
if your merge request relies on several others in multiple projects. Instead,
use the draft (or ready) state to track the readiness of an individual
merge request, and a merge request dependency to enforce merge order.
NOTE:
Merge request dependencies are a **PREMIUM** feature, but this restriction is
enforced only for the dependent merge request. A merge request in a **PREMIUM**
project can depend on a merge request in a **FREE** project, but a merge request
in a **FREE** project cannot be marked as dependent.
## View dependencies for a merge request
If a merge request is dependent on another, the merge request reports section shows
information about the dependency:
![Dependencies in merge request widget](img/dependencies_view_v15_3.png)
To view dependency information on a merge request:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Scroll to the merge request reports area. Dependent merge requests display information
about the total number of dependencies set, such as
**(status-warning)** **Depends on 1 merge request being merged**.
1. Select **Expand** to view the title, milestone, assignee, and pipeline status
of each dependency.
Until your merge request's dependencies all merge, your merge request
cannot be merged. The message
**Merge blocked: you can only merge after the above items are resolved** displays.
### Closed merge requests
Closed merge requests still prevent their dependents from being merged, because
a merge request can close regardless of whether or not the planned work actually merged.
If a merge request closes and the dependency is no longer relevant,
remove it as a dependency to unblock the dependent merge request.
## Create a new dependent merge request
When you create a new merge request, you can prevent it from merging until after
other specific work merges, even if the merge request is in a different project.
Prerequisites:
- You must have at least the Developer role or be allowed to create merge requests in the project.
- The dependent merge request must be in a project in a **PREMIUM** or higher tier.
To create a new merge request and mark it as dependent on another:
1. [Create a new merge request](creating_merge_requests.md).
1. In **Merge request dependencies**, paste either the reference or the full URL
to the merge requests that should merge before this work merges. References
are in the form of `path/to/project!merge_request_id`.
1. Select **Create merge request**.
## Edit a merge request to add a dependency
You can edit an existing merge request and mark it as dependent on another.
Prerequisite:
- You must have at least the Developer role or be allowed to edit merge requests in the project.
To do this:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Select **Edit**.
1. In **Merge request dependencies**, paste either the reference or the full URL
to the merge requests that should merge before this work merges. References
are in the form of `path/to/project!merge_request_id`.
## Remove a dependency from a merge request
You can edit a dependent merge request and remove a dependency.
Prerequisite:
- You must have a role in the project that allows you to edit merge requests.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Merge requests** and identify your merge request.
1. Select **Edit**.
1. Scroll to **Merge request dependencies** and select **Remove** next to the reference
for each dependency you want to remove.
NOTE:
Dependencies for merge requests you don't have access to are displayed as
**1 inaccessible merge request**, and can be removed the same way.
1. Select **Save changes**.
## Troubleshooting
### API support for managing merge request dependencies
No API support exists for managing dependencies. For more information, read
[issue #12551](https://gitlab.com/gitlab-org/gitlab/-/issues/12551).
### Preserving dependencies on project import or export
Dependencies are not preserved when projects are imported or exported. For more
information, read [issue #12549](https://gitlab.com/gitlab-org/gitlab/-/issues/12549).
### Complex merge order dependencies are unsupported
GitLab supports direct dependencies between merge requests, but does not support
[indirect (nested) dependencies](https://gitlab.com/gitlab-org/gitlab/-/issues/11393).
Acceptable dependency patterns include:
- A single merge request can directly depend on a single merge request.
- A single merge request can directly depend on multiple merge requests.
- Multiple merge requests can directly depend on a single merge request.
The indirect, nested dependency between `myfriend/library!10` and `mycorp/example!100` shown in this example is not supported:
```mermaid
graph LR;
A[myfriend/library!10]-->|depends on| B[herfriend/another-lib!1]
B-->|depends on| C[mycorp/example!100]
```
<!-- This redirect file can be deleted after <2022-11-22>. -->
<!-- Redirects that point to other docs in the same project expire in three months. -->
<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->

View File

@ -0,0 +1,76 @@
#!/usr/bin/env bash
## Usage: scripts/rspec_check_order_dependence <files...>
#
# List of RSpec files to be checked for their order dependency.
#
# If the files pass the following checks it's likely they are not
# order-dependent and are removed from `spec/support/rspec_order_todo.yml`
# to make them run in random order.
#
# The following checks are available:
# * Run specs in _defined_ order
# * Run specs in _reverse_ order
# * Run specs in _random_ order
if [ $# -eq 0 ]; then
echo "Usage: $0 <files...>"
exit
fi
TODO_YAML='./spec/support/rspec_order_todo.yml'
RSPEC_ARGS=(--format progress)
abort() {
echo "$@"
echo "Aborting..."
exit 1
}
for file in "$@"
do
# Drop potential file prefix `./`
file=${file#./}
# Match only the prefix so we can specify a directory to match all the files
# under it. For example, `spec/rubocop` will match, test and remove all TODO
# entries starting with `./spec/rubocop`.
grep -E -- "- './$file" "$TODO_YAML" > /dev/null || abort "Could not find '$file' in '$TODO_YAML'"
done
set -xe
bin/rspec --order defined "${RSPEC_ARGS[@]}" "$@"
RSPEC_ORDER=reverse bin/rspec "${RSPEC_ARGS[@]}" "$@"
bin/rspec --order random "${RSPEC_ARGS[@]}" "$@"
set +xe
green='\033[0;32m'
clear='\033[0m' # No Color
echo -e "$green"
echo "
The files passed all checks!
They are likely not order-dependent and can be run in random order and thus
are being removed from 'spec/support/rspec_order_todo.yml':
"
for file in "$@"
do
# Drop potential file prefix `./`
file=${file#./}
echo " * Removing '$file'"
# Escape forward slashes to make it compatible with sed below
escaped_file=${file//\//\\/}
# We must use -i.bak to make sed work on Linux and MacOS.
# See https://riptutorial.com/sed/topic/9436/bsd-macos-sed-vs--gnu-sed-vs--the-posix-sed-specification
sed -i.bak "/- '.\/$escaped_file/d" "$TODO_YAML"
rm "$TODO_YAML.bak"
done
echo -e "$clear"

View File

@ -10,6 +10,7 @@ RSpec.describe GitlabSchema.types['Subscription'] do
issuable_title_updated
issuable_labels_updated
issuable_dates_updated
merge_request_reviewers_updated
]
expect(described_class).to have_graphql_fields(*expected_fields).only

View File

@ -24,8 +24,7 @@ RSpec.describe API::Ci::JobArtifacts do
let(:guest) { create(:project_member, :guest, project: project).user }
let!(:job) do
create(:ci_build, :success, :tags, pipeline: pipeline,
artifacts_expire_at: 1.day.since)
create(:ci_build, :success, :tags, pipeline: pipeline, artifacts_expire_at: 1.day.since)
end
before do
@ -535,8 +534,7 @@ RSpec.describe API::Ci::JobArtifacts do
context 'with regular branch' do
before do
pipeline.reload
pipeline.update!(ref: 'master',
sha: project.commit('master').sha)
pipeline.update!(ref: 'master', sha: project.commit('master').sha)
get_for_ref('master')
end
@ -579,8 +577,7 @@ RSpec.describe API::Ci::JobArtifacts do
stub_artifacts_object_storage
job.success
project.update!(visibility_level: visibility_level,
public_builds: public_builds)
project.update!(visibility_level: visibility_level, public_builds: public_builds)
get_artifact_file(artifact)
end
@ -676,8 +673,7 @@ RSpec.describe API::Ci::JobArtifacts do
context 'with branch name containing slash' do
before do
pipeline.reload
pipeline.update!(ref: 'improve/awesome',
sha: project.commit('improve/awesome').sha)
pipeline.update!(ref: 'improve/awesome', sha: project.commit('improve/awesome').sha)
end
it 'returns a specific artifact file for a valid path', :sidekiq_might_not_need_inline do

View File

@ -32,8 +32,7 @@ RSpec.describe API::Ci::Jobs do
end
let!(:job) do
create(:ci_build, :success, :tags, pipeline: pipeline,
artifacts_expire_at: 1.day.since)
create(:ci_build, :success, :tags, pipeline: pipeline, artifacts_expire_at: 1.day.since)
end
before do

View File

@ -546,9 +546,12 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
let!(:job) { create(:ci_build, :pending, :queued, :tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
let!(:job2) { create(:ci_build, :pending, :queued, :tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) }
let!(:test_job) do
create(:ci_build, :pending, :queued, pipeline: pipeline, name: 'deploy',
stage: 'deploy', stage_idx: 1,
options: { script: ['bash'], dependencies: [job2.name] })
create(:ci_build, :pending, :queued,
pipeline: pipeline,
name: 'deploy',
stage: 'deploy',
stage_idx: 1,
options: { script: ['bash'], dependencies: [job2.name] })
end
before do
@ -570,9 +573,12 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
let!(:job) { create(:ci_build, :pending, :queued, :tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
let!(:job2) { create(:ci_build, :pending, :queued, :tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) }
let!(:empty_dependencies_job) do
create(:ci_build, :pending, :queued, pipeline: pipeline, name: 'empty_dependencies_job',
stage: 'deploy', stage_idx: 1,
options: { script: ['bash'], dependencies: [] })
create(:ci_build, :pending, :queued,
pipeline: pipeline,
name: 'empty_dependencies_job',
stage: 'deploy',
stage_idx: 1,
options: { script: ['bash'], dependencies: [] })
end
before do
@ -889,9 +895,12 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
describe 'a job with excluded artifacts' do
context 'when excluded paths are defined' do
let(:job) do
create(:ci_build, :pending, :queued, pipeline: pipeline, name: 'test',
stage: 'deploy', stage_idx: 1,
options: { artifacts: { paths: ['abc'], exclude: ['cde'] } })
create(:ci_build, :pending, :queued,
pipeline: pipeline,
name: 'test',
stage: 'deploy',
stage_idx: 1,
options: { artifacts: { paths: ['abc'], exclude: ['cde'] } })
end
context 'when a runner supports this feature' do

View File

@ -365,8 +365,8 @@ RSpec.describe API::FeatureFlags do
describe 'PUT /projects/:id/feature_flags/:name' do
context 'with a version 2 feature flag' do
let!(:feature_flag) do
create(:operations_feature_flag, :new_version_flag, project: project, active: true,
name: 'feature1', description: 'old description')
create(:operations_feature_flag, :new_version_flag,
project: project, active: true, name: 'feature1', description: 'old description')
end
it 'returns a 404 if the feature flag does not exist' do
@ -591,8 +591,8 @@ RSpec.describe API::FeatureFlags do
it 'deletes a feature flag strategy' do
strategy_a = create(:operations_strategy, feature_flag: feature_flag, name: 'default', parameters: {})
strategy_b = create(:operations_strategy, feature_flag: feature_flag,
name: 'userWithId', parameters: { userIds: 'userA,userB' })
strategy_b = create(:operations_strategy,
feature_flag: feature_flag, name: 'userWithId', parameters: { userIds: 'userA,userB' })
params = {
strategies: [{
id: strategy_a.id,

View File

@ -173,7 +173,7 @@ RSpec.describe 'Query.ciConfig' do
{
"name" => "docker",
"size" => 1,
"jobs" =>
"jobs" =>
{
"nodes" => [
{
@ -206,7 +206,7 @@ RSpec.describe 'Query.ciConfig' do
{
"name" => "deploy_job",
"size" => 1,
"jobs" =>
"jobs" =>
{
"nodes" => [
{
@ -332,7 +332,7 @@ RSpec.describe 'Query.ciConfig' do
"only" => { "refs" => %w[branches tags] },
"when" => "on_success",
"tags" => [],
"needs" => { "nodes" => [] } }
"needs" => { "nodes" => [] } }
]
}
}

View File

@ -35,8 +35,14 @@ RSpec.describe 'Query.group(fullPath).ciVariables' do
end
it "returns the group's CI variables" do
variable = create(:ci_group_variable, group: group, key: 'TEST_VAR', value: 'test',
masked: false, protected: true, raw: true, environment_scope: 'staging')
variable = create(:ci_group_variable,
group: group,
key: 'TEST_VAR',
value: 'test',
masked: false,
protected: true,
raw: true,
environment_scope: 'staging')
post_graphql(query, current_user: user)

View File

@ -29,7 +29,7 @@ RSpec.describe 'Query.ciVariables' do
it "returns the instance's CI variables" do
variable = create(:ci_instance_variable, key: 'TEST_VAR', value: 'test',
masked: false, protected: true, raw: true)
masked: false, protected: true, raw: true)
post_graphql(query, current_user: user)

View File

@ -36,7 +36,7 @@ RSpec.describe 'Query.project(fullPath).ciVariables' do
it "returns the project's CI variables" do
variable = create(:ci_variable, project: project, key: 'TEST_VAR', value: 'test',
masked: false, protected: true, raw: true, environment_scope: 'production')
masked: false, protected: true, raw: true, environment_scope: 'production')
post_graphql(query, current_user: user)

View File

@ -9,21 +9,49 @@ RSpec.describe 'Query.runner(id)' do
let_it_be(:group) { create(:group) }
let_it_be(:active_instance_runner) do
create(:ci_runner, :instance, description: 'Runner 1', contacted_at: 2.hours.ago,
active: true, version: 'adfe156', revision: 'a', locked: true, ip_address: '127.0.0.1', maximum_timeout: 600,
access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true, executor_type: :custom,
maintenance_note: '**Test maintenance note**')
create(:ci_runner, :instance,
description: 'Runner 1',
contacted_at: 2.hours.ago,
active: true,
version: 'adfe156',
revision: 'a',
locked: true,
ip_address: '127.0.0.1',
maximum_timeout: 600,
access_level: 0,
tag_list: %w[tag1 tag2],
run_untagged: true,
executor_type: :custom,
maintenance_note: '**Test maintenance note**')
end
let_it_be(:inactive_instance_runner) do
create(:ci_runner, :instance, description: 'Runner 2', contacted_at: 1.day.ago, active: false,
version: 'adfe157', revision: 'b', ip_address: '10.10.10.10', access_level: 1, run_untagged: true)
create(:ci_runner, :instance,
description: 'Runner 2',
contacted_at: 1.day.ago,
active: false,
version: 'adfe157',
revision: 'b',
ip_address: '10.10.10.10',
access_level: 1,
run_untagged: true)
end
let_it_be(:active_group_runner) do
create(:ci_runner, :group, groups: [group], description: 'Group runner 1', contacted_at: 2.hours.ago,
active: true, version: 'adfe156', revision: 'a', locked: true, ip_address: '127.0.0.1', maximum_timeout: 600,
access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true, executor_type: :shell)
create(:ci_runner, :group,
groups: [group],
description: 'Group runner 1',
contacted_at: 2.hours.ago,
active: true,
version: 'adfe156',
revision: 'a',
locked: true,
ip_address: '127.0.0.1',
maximum_timeout: 600,
access_level: 0,
tag_list: %w[tag1 tag2],
run_untagged: true,
executor_type: :shell)
end
let_it_be(:active_project_runner) { create(:ci_runner, :project) }
@ -159,8 +187,16 @@ RSpec.describe 'Query.runner(id)' do
with_them do
let(:project_runner) do
create(:ci_runner, :project, description: 'Runner 3', contacted_at: 1.day.ago, active: false, locked: is_locked,
version: 'adfe157', revision: 'b', ip_address: '10.10.10.10', access_level: 1, run_untagged: true)
create(:ci_runner, :project,
description: 'Runner 3',
contacted_at: 1.day.ago,
active: false,
locked: is_locked,
version: 'adfe157',
revision: 'b',
ip_address: '10.10.10.10',
access_level: 1,
run_untagged: true)
end
let(:query) do

View File

@ -141,8 +141,13 @@ RSpec.describe 'Group.runners' do
describe 'edges' do
let_it_be(:runner) do
create(:ci_runner, :group, active: false, version: 'def', revision: '456',
description: 'Project runner', groups: [group], ip_address: '127.0.0.1')
create(:ci_runner, :group,
active: false,
version: 'def',
revision: '456',
description: 'Project runner',
groups: [group],
ip_address: '127.0.0.1')
end
let(:query) do

View File

@ -22,9 +22,14 @@ RSpec.describe 'Updating an existing release' do
let_it_be(:milestones) { [milestone_12_3, milestone_12_4] }
let_it_be(:release) do
create(:release, project: project, tag: tag_name, name: name,
description: description, released_at: Time.parse(released_at).utc,
created_at: Time.parse(created_at).utc, milestones: milestones)
create(:release,
project: project,
tag: tag_name,
name: name,
description: description,
released_at: Time.parse(released_at).utc,
created_at: Time.parse(created_at).utc,
milestones: milestones)
end
let(:mutation_name) { :release_update }

View File

@ -11,14 +11,14 @@ RSpec.describe 'Query.project(fullPath).issue(iid).designCollection.version(sha)
let_it_be(:developer) { create(:user) }
let_it_be(:stranger) { create(:user) }
let_it_be(:old_version) do
create(:design_version, issue: issue,
created_designs: create_list(:design, 3, issue: issue))
create(:design_version, issue: issue, created_designs: create_list(:design, 3, issue: issue))
end
let_it_be(:version) do
create(:design_version, issue: issue,
modified_designs: old_version.designs,
created_designs: create_list(:design, 2, issue: issue))
create(:design_version,
issue: issue,
modified_designs: old_version.designs,
created_designs: create_list(:design, 2, issue: issue))
end
let(:current_user) { developer }

View File

@ -60,17 +60,17 @@ RSpec.describe 'query a single terraform state' do
expect(data).to match a_graphql_entity_for(
terraform_state,
:name,
'lockedAt' => terraform_state.locked_at.iso8601,
'createdAt' => terraform_state.created_at.iso8601,
'updatedAt' => terraform_state.updated_at.iso8601,
'lockedByUser' => a_graphql_entity_for(terraform_state.locked_by_user),
'lockedAt' => terraform_state.locked_at.iso8601,
'createdAt' => terraform_state.created_at.iso8601,
'updatedAt' => terraform_state.updated_at.iso8601,
'lockedByUser' => a_graphql_entity_for(terraform_state.locked_by_user),
'latestVersion' => a_graphql_entity_for(
latest_version,
'serial' => eq(latest_version.version),
'createdAt' => eq(latest_version.created_at.iso8601),
'updatedAt' => eq(latest_version.updated_at.iso8601),
'serial' => eq(latest_version.version),
'createdAt' => eq(latest_version.created_at.iso8601),
'updatedAt' => eq(latest_version.updated_at.iso8601),
'createdByUser' => a_graphql_entity_for(latest_version.created_by_user),
'job' => { 'name' => eq(latest_version.build.name) }
'job' => { 'name' => eq(latest_version.build.name) }
)
)
end

View File

@ -64,18 +64,18 @@ RSpec.describe 'query terraform states' do
expect(data['nodes']).to contain_exactly a_graphql_entity_for(
terraform_state, :name,
'lockedAt' => terraform_state.locked_at.iso8601,
'createdAt' => terraform_state.created_at.iso8601,
'updatedAt' => terraform_state.updated_at.iso8601,
'lockedByUser' => a_graphql_entity_for(terraform_state.locked_by_user),
'lockedAt' => terraform_state.locked_at.iso8601,
'createdAt' => terraform_state.created_at.iso8601,
'updatedAt' => terraform_state.updated_at.iso8601,
'lockedByUser' => a_graphql_entity_for(terraform_state.locked_by_user),
'latestVersion' => a_graphql_entity_for(
latest_version,
'serial' => eq(latest_version.version),
'downloadPath' => eq(download_path),
'createdAt' => eq(latest_version.created_at.iso8601),
'updatedAt' => eq(latest_version.updated_at.iso8601),
'serial' => eq(latest_version.version),
'downloadPath' => eq(download_path),
'createdAt' => eq(latest_version.created_at.iso8601),
'updatedAt' => eq(latest_version.updated_at.iso8601),
'createdByUser' => a_graphql_entity_for(latest_version.created_by_user),
'job' => { 'name' => eq(latest_version.build.name) }
'job' => { 'name' => eq(latest_version.build.name) }
)
)
end

View File

@ -108,8 +108,8 @@ RSpec.describe 'Query' do
design_at_version,
'filename' => design_at_version.design.filename,
'version' => a_graphql_entity_for(version, :sha),
'design' => a_graphql_entity_for(design),
'issue' => { 'title' => issue.title, 'iid' => issue.iid.to_s },
'design' => a_graphql_entity_for(design),
'issue' => { 'title' => issue.title, 'iid' => issue.iid.to_s },
'project' => a_graphql_entity_for(project, :full_path)
)
end

View File

@ -540,9 +540,9 @@ RSpec.describe API::Groups do
# Returns a Hash of visibility_level => Project pairs
def add_projects_to_group(group, share_with: nil)
projects = {
public: create(:project, :public, namespace: group),
public: create(:project, :public, namespace: group),
internal: create(:project, :internal, namespace: group),
private: create(:project, :private, namespace: group)
private: create(:project, :private, namespace: group)
}
if share_with

View File

@ -188,7 +188,7 @@ RSpec.describe API::Internal::Base do
it 'returns an error message when expires_at contains an invalid date' do
post api('/internal/personal_access_token'),
params: {
key_id: key.id,
key_id: key.id,
name: 'newtoken',
scopes: ['api'],
expires_at: 'invalid-date'
@ -202,7 +202,7 @@ RSpec.describe API::Internal::Base do
it 'returns an error message when it receives an invalid scope' do
post api('/internal/personal_access_token'),
params: {
key_id: key.id,
key_id: key.id,
name: 'newtoken',
scopes: %w(read_api badscope read_repository)
},
@ -217,7 +217,7 @@ RSpec.describe API::Internal::Base do
post api('/internal/personal_access_token'),
params: {
key_id: key.id,
key_id: key.id,
name: 'newtoken',
scopes: %w(read_api read_repository)
},
@ -234,7 +234,7 @@ RSpec.describe API::Internal::Base do
post api('/internal/personal_access_token'),
params: {
key_id: key.id,
key_id: key.id,
name: 'newtoken',
scopes: %w(read_api read_repository),
expires_at: '9001-11-17'

View File

@ -465,10 +465,10 @@ RSpec.describe API::Issues do
context 'with archived projects' do
let_it_be(:archived_issue) do
create(
:issue, author: user, assignees: [user],
project: create(:project, :public, :archived, creator_id: user.id, namespace: group)
)
create(:issue,
author: user,
assignees: [user],
project: create(:project, :public, :archived, creator_id: user.id, namespace: group))
end
it 'returns only non archived projects issues' do

View File

@ -1249,9 +1249,10 @@ RSpec.describe API::Projects do
stub_application_setting(import_sources: nil)
endpoint_url = "#{url}/info/refs?service=git-upload-pack"
stub_full_request(endpoint_url, method: :get).to_return({ status: 200,
body: '001e# service=git-upload-pack',
headers: { 'Content-Type': 'application/x-git-upload-pack-advertisement' } })
stub_full_request(endpoint_url, method: :get).to_return(
{ status: 200,
body: '001e# service=git-upload-pack',
headers: { 'Content-Type': 'application/x-git-upload-pack-advertisement' } })
project_params = { import_url: url, path: 'path-project-Foo', name: 'Foo Project' }
expect { post api('/projects', user), params: project_params }

View File

@ -34,15 +34,14 @@ RSpec.describe API::Suggestions do
end
let(:diff_note2) do
create(:diff_note_on_merge_request, noteable: merge_request,
position: position2,
project: project)
create(:diff_note_on_merge_request, noteable: merge_request, position: position2, project: project)
end
let(:suggestion) do
create(:suggestion, note: diff_note,
from_content: " raise RuntimeError, \"System commands must be given as an array of strings\"\n",
to_content: " raise RuntimeError, 'Explosion'\n # explosion?")
create(:suggestion,
note: diff_note,
from_content: " raise RuntimeError, \"System commands must be given as an array of strings\"\n",
to_content: " raise RuntimeError, 'Explosion'\n # explosion?")
end
let(:unappliable_suggestion) do
@ -119,8 +118,8 @@ RSpec.describe API::Suggestions do
describe "PUT /suggestions/batch_apply" do
let(:suggestion2) do
create(:suggestion, note: diff_note2,
from_content: " \"PWD\" => path\n",
to_content: " *** FOO ***\n")
from_content: " \"PWD\" => path\n",
to_content: " *** FOO ***\n")
end
let(:url) { "/suggestions/batch_apply" }

View File

@ -218,8 +218,7 @@ RSpec.describe API::Unleash do
context 'with version 2 feature flags' do
it 'does not return a flag without any strategies' do
create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 2)
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
@ -228,10 +227,8 @@ RSpec.describe API::Unleash do
end
it 'returns a flag with a default strategy' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
feature_flag = create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag, name: 'default', parameters: {})
create(:operations_scope, strategy: strategy, environment_scope: 'production')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
@ -248,10 +245,9 @@ RSpec.describe API::Unleash do
end
it 'returns a flag with a userWithId strategy' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'userWithId', parameters: { userIds: 'user123,user456' })
feature_flag = create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy,
feature_flag: feature_flag, name: 'userWithId', parameters: { userIds: 'user123,user456' })
create(:operations_scope, strategy: strategy, environment_scope: 'production')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
@ -268,12 +264,13 @@ RSpec.describe API::Unleash do
end
it 'returns a flag with multiple strategies' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag,
name: 'userWithId', parameters: { userIds: 'user_a,user_b' })
strategy_b = create(:operations_strategy, feature_flag: feature_flag,
name: 'gradualRolloutUserId', parameters: { groupId: 'default', percentage: '45' })
feature_flag = create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy,
feature_flag: feature_flag, name: 'userWithId', parameters: { userIds: 'user_a,user_b' })
strategy_b = create(:operations_strategy,
feature_flag: feature_flag,
name: 'gradualRolloutUserId',
parameters: { groupId: 'default', percentage: '45' })
create(:operations_scope, strategy: strategy_a, environment_scope: 'production')
create(:operations_scope, strategy: strategy_b, environment_scope: 'production')
@ -298,12 +295,12 @@ RSpec.describe API::Unleash do
end
it 'returns only flags matching the environment scope' do
feature_flag_a = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
feature_flag_a = create(:operations_feature_flag,
project: project, name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag_a)
create(:operations_scope, strategy: strategy_a, environment_scope: 'production')
feature_flag_b = create(:operations_feature_flag, project: project,
name: 'feature2', active: true, version: 2)
feature_flag_b = create(:operations_feature_flag,
project: project, name: 'feature2', active: true, version: 2)
strategy_b = create(:operations_strategy, feature_flag: feature_flag_b)
create(:operations_scope, strategy: strategy_b, environment_scope: 'staging')
@ -322,13 +319,11 @@ RSpec.describe API::Unleash do
end
it 'returns only strategies matching the environment scope' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag,
name: 'userWithId', parameters: { userIds: 'user2,user8,user4' })
feature_flag = create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy,
feature_flag: feature_flag, name: 'userWithId', parameters: { userIds: 'user2,user8,user4' })
create(:operations_scope, strategy: strategy_a, environment_scope: 'production')
strategy_b = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
strategy_b = create(:operations_strategy, feature_flag: feature_flag, name: 'default', parameters: {})
create(:operations_scope, strategy: strategy_b, environment_scope: 'staging')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
@ -346,10 +341,12 @@ RSpec.describe API::Unleash do
it 'returns only flags for the given project' do
project_b = create(:project)
feature_flag_a = create(:operations_feature_flag, project: project, name: 'feature_a', active: true, version: 2)
feature_flag_a = create(:operations_feature_flag,
project: project, name: 'feature_a', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag_a)
create(:operations_scope, strategy: strategy_a, environment_scope: 'sandbox')
feature_flag_b = create(:operations_feature_flag, project: project_b, name: 'feature_b', active: true, version: 2)
feature_flag_b = create(:operations_feature_flag,
project: project_b, name: 'feature_b', active: true, version: 2)
strategy_b = create(:operations_strategy, feature_flag: feature_flag_b)
create(:operations_scope, strategy: strategy_b, environment_scope: 'sandbox')
@ -367,16 +364,16 @@ RSpec.describe API::Unleash do
end
it 'returns all strategies with a matching scope' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag,
name: 'userWithId', parameters: { userIds: 'user2,user8,user4' })
feature_flag = create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy,
feature_flag: feature_flag, name: 'userWithId', parameters: { userIds: 'user2,user8,user4' })
create(:operations_scope, strategy: strategy_a, environment_scope: '*')
strategy_b = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
strategy_b = create(:operations_strategy, feature_flag: feature_flag, name: 'default', parameters: {})
create(:operations_scope, strategy: strategy_b, environment_scope: 'review/*')
strategy_c = create(:operations_strategy, feature_flag: feature_flag,
name: 'gradualRolloutUserId', parameters: { groupId: 'default', percentage: '15' })
strategy_c = create(:operations_strategy,
feature_flag: feature_flag,
name: 'gradualRolloutUserId',
parameters: { groupId: 'default', percentage: '15' })
create(:operations_scope, strategy: strategy_c, environment_scope: 'review/patch-1')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'review/patch-1' }
@ -395,10 +392,8 @@ RSpec.describe API::Unleash do
end
it 'returns a strategy with more than one matching scope' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
feature_flag = create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag, name: 'default', parameters: {})
create(:operations_scope, strategy: strategy, environment_scope: 'production')
create(:operations_scope, strategy: strategy, environment_scope: '*')
@ -416,10 +411,9 @@ RSpec.describe API::Unleash do
end
it 'returns a disabled flag with a matching scope' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'myfeature', active: false, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
feature_flag = create(:operations_feature_flag,
project: project, name: 'myfeature', active: false, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag, name: 'default', parameters: {})
create(:operations_scope, strategy: strategy, environment_scope: 'production')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
@ -436,12 +430,12 @@ RSpec.describe API::Unleash do
end
it 'returns a userWithId strategy for a gitlabUserList strategy' do
feature_flag = create(:operations_feature_flag, :new_version_flag, project: project,
name: 'myfeature', active: true)
user_list = create(:operations_feature_flag_user_list, project: project,
name: 'My List', user_xids: 'user1,user2')
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'gitlabUserList', parameters: {}, user_list: user_list)
feature_flag = create(:operations_feature_flag, :new_version_flag,
project: project, name: 'myfeature', active: true)
user_list = create(:operations_feature_flag_user_list,
project: project, name: 'My List', user_xids: 'user1,user2')
strategy = create(:operations_strategy,
feature_flag: feature_flag, name: 'gitlabUserList', parameters: {}, user_list: user_list)
create(:operations_scope, strategy: strategy, environment_scope: 'production')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }

View File

@ -452,7 +452,7 @@ RSpec.describe 'Git HTTP requests' do
canonical_project.add_maintainer(user)
create(:merge_request,
source_project: project,
target_project: canonical_project,
target_project: canonical_project,
source_branch: 'fixes',
allow_collaboration: true)
end
@ -1105,7 +1105,7 @@ RSpec.describe 'Git HTTP requests' do
canonical_project.add_maintainer(user)
create(:merge_request,
source_project: project,
target_project: canonical_project,
target_project: canonical_project,
source_branch: 'fixes',
allow_collaboration: true)
end

View File

@ -78,11 +78,12 @@ RSpec.describe 'OAuth Tokens requests' do
context 'revoked refresh token' do
let!(:existing_token) do
create(:oauth_access_token, application: application,
resource_owner_id: user.id,
created_at: 2.hours.ago,
revoked_at: 1.hour.ago,
expires_in: 5)
create(:oauth_access_token,
application: application,
resource_owner_id: user.id,
created_at: 2.hours.ago,
revoked_at: 1.hour.ago,
expires_in: 5)
end
it 'does not issue a new token' do

View File

@ -23,24 +23,24 @@ RSpec.describe 'OpenID Connect requests' do
let(:id_token_claims) do
{
'sub' => user.id.to_s,
'sub' => user.id.to_s,
'sub_legacy' => hashed_subject
}
end
let(:user_info_claims) do
{
'name' => 'Alice',
'nickname' => 'alice',
'email' => 'public@example.com',
'name' => 'Alice',
'nickname' => 'alice',
'email' => 'public@example.com',
'email_verified' => true,
'website' => 'https://example.com',
'profile' => 'http://localhost/alice',
'picture' => "http://localhost/uploads/-/system/user/avatar/#{user.id}/dk.png",
'groups' => kind_of(Array),
'https://gitlab.org/claims/groups/owner' => kind_of(Array),
'website' => 'https://example.com',
'profile' => 'http://localhost/alice',
'picture' => "http://localhost/uploads/-/system/user/avatar/#{user.id}/dk.png",
'groups' => kind_of(Array),
'https://gitlab.org/claims/groups/owner' => kind_of(Array),
'https://gitlab.org/claims/groups/maintainer' => kind_of(Array),
'https://gitlab.org/claims/groups/developer' => kind_of(Array)
'https://gitlab.org/claims/groups/developer' => kind_of(Array)
}
end

View File

@ -30,7 +30,7 @@ RSpec.describe Projects::EnvironmentsController do
deployer = create(:user)
pipeline = create(:ci_pipeline, project: environment.project)
build = create(:ci_build, environment: environment.name, pipeline: pipeline, user: deployer)
create(:deployment, :success, environment: environment, deployable: build, user: deployer,
project: project, sha: commit.sha)
create(:deployment, :success,
environment: environment, deployable: build, user: deployer, project: project, sha: commit.sha)
end
end

View File

@ -37,12 +37,10 @@ RSpec.describe 'merge requests discussions' do
it 'avoids N+1 DB queries', :request_store do
send_request # warm up
create(:diff_note_on_merge_request, noteable: merge_request,
project: merge_request.project)
create(:diff_note_on_merge_request, noteable: merge_request, project: merge_request.project)
control = ActiveRecord::QueryRecorder.new { send_request }
create(:diff_note_on_merge_request, noteable: merge_request,
project: merge_request.project)
create(:diff_note_on_merge_request, noteable: merge_request, project: merge_request.project)
expect do
send_request
@ -51,8 +49,7 @@ RSpec.describe 'merge requests discussions' do
it 'limits Gitaly queries', :request_store do
Gitlab::GitalyClient.allow_n_plus_1_calls do
create_list(:diff_note_on_merge_request, 7, noteable: merge_request,
project: merge_request.project)
create_list(:diff_note_on_merge_request, 7, noteable: merge_request, project: merge_request.project)
end
# The creations above write into the Gitaly counts

View File

@ -1,5 +1,6 @@
# frozen_string_literal: true
require_relative "rspec_order"
require_relative "helpers/stub_configuration"
require_relative "helpers/stub_metrics"
require_relative "helpers/stub_object_storage"

View File

@ -0,0 +1,51 @@
# frozen_string_literal: true
module Support
module RspecOrder
TODO_YAML = File.join(__dir__, 'rspec_order_todo.yml')
module_function
def order_for(example_group)
order_from_env || random_order(example_group)
end
def order_from_env
return @order_from_env if defined?(@order_from_env)
# Passing custom defined order via `--order NAME` is not supported.
# For example, `--order reverse` does not work so we are passing it via
# environment variable RSPEC_ORDER.
@order_from_env = ENV['RSPEC_ORDER']
end
def random_order(example_group)
path = example_group.metadata.fetch(:file_path)
:random unless potential_order_dependent?(path)
end
def potential_order_dependent?(path)
@todo ||= YAML.load_file(TODO_YAML).to_set # rubocop:disable Gitlab/PredicateMemoization
@todo.include?(path)
end
end
end
RSpec.configure do |config|
# Useful to find order-dependent specs.
config.register_ordering(:reverse, &:reverse)
# Randomization can be reproduced across test runs.
Kernel.srand config.seed
config.on_example_group_definition do |example_group|
order = Support::RspecOrder.order_for(example_group)
if order
example_group.metadata[:order] = order.to_sym
example_group.metadata[:description] += " (order #{order})"
end
end
end

File diff suppressed because it is too large Load Diff