Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-07-07 00:08:58 +00:00
parent 8bba6175aa
commit 7dc3246696
19 changed files with 219 additions and 111 deletions

View file

@ -45,7 +45,8 @@ export default {
isMakingRequest: false,
isMergingImmediately: false,
commitMessage: this.mr.commitMessage,
squashBeforeMerge: this.mr.squash,
squashBeforeMerge: this.mr.squashIsSelected,
isSquashReadOnly: this.mr.squashIsReadonly,
successSvg,
warningSvg,
squashCommitMessage: this.mr.squashCommitMessage,
@ -106,7 +107,12 @@ export default {
return this.isMergeButtonDisabled;
},
shouldShowSquashBeforeMerge() {
const { commitsCount, enableSquashBeforeMerge } = this.mr;
const { commitsCount, enableSquashBeforeMerge, squashIsReadonly, squashIsSelected } = this.mr;
if (squashIsReadonly && !squashIsSelected) {
return false;
}
return enableSquashBeforeMerge && commitsCount > 1;
},
shouldShowMergeControls() {
@ -344,7 +350,7 @@ export default {
v-if="shouldShowSquashBeforeMerge"
v-model="squashBeforeMerge"
:help-path="mr.squashBeforeMergeHelpPath"
:is-disabled="isMergeButtonDisabled"
:is-disabled="isSquashReadOnly"
/>
</template>
<template v-else>

View file

@ -30,7 +30,7 @@ export default {
<template>
<div class="inline">
<label>
<label :class="{ 'gl-text-gray-600': isDisabled }" data-testid="squashLabel">
<input
:checked="value"
:disabled="isDisabled"

View file

@ -22,7 +22,10 @@ export default class MergeRequestStore {
const pipelineStatus = data.pipeline ? data.pipeline.details.status : null;
this.squash = data.squash;
this.squashIsEnabledByDefault = data.squash_enabled_by_default;
this.squashIsReadonly = data.squash_readonly;
this.enableSquashBeforeMerge = this.enableSquashBeforeMerge || true;
this.squashIsSelected = data.squash_readonly ? data.squash_on_merge : data.squash;
this.iid = data.iid;
this.title = data.title;

View file

@ -19,6 +19,9 @@ class Projects::PipelinesController < Projects::ApplicationController
end
before_action :ensure_pipeline, only: [:show]
# Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596
before_action :redirect_for_legacy_scope_filter, only: [:index], if: -> { request.format.html? }
around_action :allow_gitaly_ref_name_caching, only: [:index, :show]
track_unique_visits :charts, target_id: 'p_analytics_pipelines'
@ -34,9 +37,6 @@ class Projects::PipelinesController < Projects::ApplicationController
.page(params[:page])
.per(30)
@running_count = limited_pipelines_count(project, 'running')
@pending_count = limited_pipelines_count(project, 'pending')
@finished_count = limited_pipelines_count(project, 'finished')
@pipelines_count = limited_pipelines_count(project)
respond_to do |format|
@ -47,10 +47,7 @@ class Projects::PipelinesController < Projects::ApplicationController
render json: {
pipelines: serialize_pipelines,
count: {
all: @pipelines_count,
running: @running_count,
pending: @pending_count,
finished: @finished_count
all: @pipelines_count
}
}
end
@ -229,6 +226,12 @@ class Projects::PipelinesController < Projects::ApplicationController
render_404 unless pipeline
end
def redirect_for_legacy_scope_filter
return unless %w[running pending].include?(params[:scope])
redirect_to url_for(safe_params.except(:scope).merge(status: safe_params[:scope])), status: :moved_permanently
end
# rubocop: disable CodeReuse/ActiveRecord
def pipeline
@pipeline ||= if params[:id].blank? && params[:latest]

View file

@ -0,0 +1,5 @@
---
title: Remove count for pending/running/finished pipelines in tabs
merge_request: 35693
author:
type: changed

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

View file

@ -103,7 +103,7 @@ GitLab](https://about.gitlab.com/install/).
You will need the IP/host address for each node.
1. `LOAD_BALANCER_SERVER_ADDRESS`: the IP/hots address of the load balancer
1. `LOAD_BALANCER_SERVER_ADDRESS`: the IP/host address of the load balancer
1. `POSTGRESQL_SERVER_ADDRESS`: the IP/host address of the PostgreSQL server
1. `PRAEFECT_HOST`: the IP/host address of the Praefect server
1. `GITALY_HOST`: the IP/host address of each Gitaly server
@ -281,9 +281,15 @@ application server, or a Gitaly node.
1. Configure the **Praefect** cluster to connect to each Gitaly node in the
cluster by editing `/etc/gitlab/gitlab.rb`.
In the example below we have configured one virtual storage (or shard) named
`storage-1`. This cluster has three Gitaly nodes `gitaly-1`, `gitaly-2`, and
`gitaly-3`, which will be replicas of each other.
The virtual storage's name must match the configured storage name in GitLab
configuration. In a later step, we configure the storage name as `default`
so we use `default` here as well. This cluster has three Gitaly nodes `gitaly-1`,
`gitaly-2`, and `gitaly-3`, which will be replicas of each other.
CAUTION: **CAUTION:** If you have data on an already existing storage called
`default`, you should configure the virtual storage with another name and
[migrate the data to the Praefect storage](#migrating-existing-repositories-to-praefect)
afterwards.
Replace `PRAEFECT_INTERNAL_TOKEN` with a strong secret, which will be used by
Praefect when communicating with Gitaly nodes in the cluster. This token is
@ -302,7 +308,7 @@ application server, or a Gitaly node.
# Name of storage hash must match storage name in git_data_dirs on GitLab
# server ('praefect') and in git_data_dirs on Gitaly nodes ('gitaly-1')
praefect['virtual_storages'] = {
'storage-1' => {
'default' => {
'gitaly-1' => {
'address' => 'tcp://GITALY_HOST:8075',
'token' => 'PRAEFECT_INTERNAL_TOKEN',
@ -555,6 +561,16 @@ Particular attention should be shown to:
external_url 'GITLAB_SERVER_URL'
```
1. Disable the default Gitaly service running on the GitLab host. It won't be needed
as GitLab will connect to the configured cluster.
CAUTION: **CAUTION** If you have existing data stored on the default Gitaly storage,
you should [migrate the data your Praefect storage first](#migrating-existing-repositories-to-praefect).
```ruby
gitaly['enable'] = false
```
1. Add the Praefect cluster as a storage location by editing
`/etc/gitlab/gitlab.rb`.
@ -562,28 +578,17 @@ Particular attention should be shown to:
- `LOAD_BALANCER_SERVER_ADDRESS` with the IP address or hostname of the load
balancer.
- `GITLAB_HOST` with the IP address or hostname of the GitLab server
- `PRAEFECT_EXTERNAL_TOKEN` with the real secret
```ruby
git_data_dirs({
"default" => {
"gitaly_address" => "tcp://GITLAB_HOST:8075"
},
"storage-1" => {
"gitaly_address" => "tcp://LOAD_BALANCER_SERVER_ADDRESS:2305",
"gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
}
})
```
1. Allow Gitaly to listen on a TCP port by editing
`/etc/gitlab/gitlab.rb`
```ruby
gitaly['listen_addr'] = '0.0.0.0:8075'
```
1. Configure the `gitlab_shell['secret_token']` so that callbacks from Gitaly
nodes during a `git push` are properly authenticated by editing
`/etc/gitlab/gitlab.rb`:
@ -632,14 +637,6 @@ Particular attention should be shown to:
gitlab-ctl reconfigure
```
1. To ensure that Gitaly [has updated its Prometheus listen
address](https://gitlab.com/gitlab-org/gitaly/-/issues/2734), [restart
Gitaly](../restart_gitlab.md#omnibus-gitlab-restart):
```shell
gitlab-ctl restart gitaly
```
1. Verify each `gitlab-shell` on each Gitaly instance can reach GitLab. On each Gitaly instance run:
```shell
@ -652,16 +649,11 @@ Particular attention should be shown to:
gitlab-rake gitlab:gitaly:check
```
1. Update the **Repository storage** settings from **Admin Area > Settings >
Repository > Repository storage** to make the newly configured Praefect
cluster the storage location for new Git repositories.
1. Check in **Admin Area > Settings > Repository > Repository storage** that the Praefect storage
is configured to store new repositories. Following this guide, the `default` storage should have
weight 100 to store all new repositories.
- The default weight is 0.
- The Praefect weight is 100.
![Update repository storage](img/praefect_storage_v13_1.png)
1. Verify everything is still working by creating a new project. Check the
1. Verify everything is working by creating a new project. Check the
"Initialize repository with a README" box so that there is content in the
repository that viewed. If the project is created, and you can see the
README file, it works!
@ -790,12 +782,15 @@ The Praefect `dataloss` sub-command helps identify lost writes by checking for u
```shell
sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss [-virtual-storage <virtual-storage>]
```
If the virtual storage is not specified, every configured virtual storage is checked for data loss.
```shell
sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss
```
```shell
Virtual storage: default
Current read-only primary: gitaly-2
Previous write-enabled primary: gitaly-1

View file

@ -1052,7 +1052,7 @@ POST /projects
| `show_default_award_emojis` | boolean | no | Show default award emojis |
| `resolve_outdated_diff_discussions` | boolean | no | Automatically resolve merge request diffs discussions on lines changed with a push |
| `container_registry_enabled` | boolean | no | Enable container registry for this project |
| `container_expiration_policy_attributes` | hash | no | Update the image expiration policy for this project. Accepts: `cadence` (string), `keep_n` (string), `older_than` (string), `name_regex` (string), `name_regex_delete` (string), `name_regex_keep` (string), `enabled` (boolean) |
| `container_expiration_policy_attributes` | hash | no | Update the image cleanup policy for this project. Accepts: `cadence` (string), `keep_n` (string), `older_than` (string), `name_regex` (string), `name_regex_delete` (string), `name_regex_keep` (string), `enabled` (boolean) |
| `shared_runners_enabled` | boolean | no | Enable shared runners for this project |
| `visibility` | string | no | See [project visibility level](#project-visibility-level) |
| `import_url` | string | no | URL to import repository from |
@ -1193,7 +1193,7 @@ PUT /projects/:id
| `show_default_award_emojis` | boolean | no | Show default award emojis |
| `resolve_outdated_diff_discussions` | boolean | no | Automatically resolve merge request diffs discussions on lines changed with a push |
| `container_registry_enabled` | boolean | no | Enable container registry for this project |
| `container_expiration_policy_attributes` | hash | no | Update the image expiration policy for this project. Accepts: `cadence` (string), `keep_n` (string), `older_than` (string), `name_regex` (string), `name_regex_delete` (string), `name_regex_keep` (string), `enabled` (boolean) |
| `container_expiration_policy_attributes` | hash | no | Update the image cleanup policy for this project. Accepts: `cadence` (string), `keep_n` (string), `older_than` (string), `name_regex` (string), `name_regex_delete` (string), `name_regex_keep` (string), `enabled` (boolean) |
| `shared_runners_enabled` | boolean | no | Enable shared runners for this project |
| `visibility` | string | no | See [project visibility level](#project-visibility-level) |
| `import_url` | string | no | URL to import repository from |

View file

@ -105,6 +105,7 @@ are very appreciative of the work done by translators and proofreaders!
- Proofreaders needed.
- Turkish
- Ali Demirtaş - [GitLab](https://gitlab.com/alidemirtas), [CrowdIn](https://crowdin.com/profile/alidemirtas)
- Rıfat Ünalmış (Rifat Unalmis) - [GitLab](https://gitlab.com/runalmis), [CrowdIn](https://crowdin.com/profile/runalmis)
- Ukrainian
- Volodymyr Sobotovych - [GitLab](https://gitlab.com/wheleph), [CrowdIn](https://crowdin.com/profile/wheleph)
- Andrew Vityuk - [GitLab](https://gitlab.com/3_1_3_u), [CrowdIn](https://crowdin.com/profile/andruwa13)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

View file

@ -71,7 +71,7 @@ This view will:
- Allow you to [delete](#delete-images-from-within-gitlab) one or more image repository.
- Allow you to navigate to the image repository details page.
- Show a **Quick start** dropdown with the most common commands to log in, build and push
- Optionally, a banner will be visible if the [expiration policy](#expiration-policy) is enabled for this project.
- Optionally, a banner will be visible if the [cleanup policy](#cleanup-policy) is enabled for this project.
### Control Container Registry for your group
@ -486,29 +486,33 @@ You can download the latest `reg` release from
the code example by changing the `REG_SHA256` and `REG_VERSION` variables
defined in the `delete_image` job.
### Delete images using an expiration policy
### Delete images by using a cleanup policy
You can create a per-project [expiration policy](#expiration-policy) to ensure
older tags and images are regularly removed from the Container Registry.
You can create a per-project [cleanup policy](#cleanup-policy) to ensure older tags and images are regularly removed from the
Container Registry.
## Expiration policy
## Cleanup policy
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15398) in GitLab 12.8.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15398) in GitLab 12.8.
> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/218737) from "expiration policy" to "cleanup policy" in GitLab 13.2.
For a specific project, if you want to remove tags you no longer need,
you can create an expiration policy. When the policy is applied, tags matching the regex pattern are removed.
you can create a cleanup policy. When the policy is applied, tags matching the regex pattern are removed.
The underlying layers and images remain.
To delete the underlying layers and images no longer associated with any tags, Instance Administrators can use
[garbage collection](../../../administration/packages/container_registry.md#removing-unused-layers-not-referenced-by-manifests) with the `-m` switch.
NOTE: **Note:**
For GitLab.com, expiration policies are not available for projects created before GitLab 12.8.
For self-managed instances, expiration policies may be enabled by an admin in the
For GitLab.com, cleanup policies are not available for projects created
before this feature was deployed to production (February 2020).
Support for pre-existing projects on GitLab.com
[is planned](https://gitlab.com/gitlab-org/gitlab/-/issues/196124).
For self-managed instances, cleanup policies may be enabled by an admin in the
[CI/CD Package Registry settings](./../../admin_area/settings/index.md#cicd).
Note the inherent [risks involved](./index.md#use-with-external-container-registries).
The expiration policy algorithm starts by collecting all the tags for a given repository in a list,
The cleanup policy algorithm starts by collecting all the tags for a given repository in a list,
then goes through a process of excluding tags from it until only the ones to be deleted remain:
1. Collect all the tags for a given repository in a list.
@ -517,43 +521,41 @@ then goes through a process of excluding tags from it until only the ones to be
1. Excludes any tags that do not have a manifest (not part of the options).
1. Orders the remaining tags by `created_date`.
1. Excludes from the list the N tags based on the `keep_n` value (Number of tags to retain).
1. Excludes from the list the tags more recent than the `older_than` value (Expiration interval).
1. Excludes from the list the tags more recent than the `older_than` value (Cleanup interval).
1. Excludes from the list any tags matching the `name_regex_keep` value (Images to preserve).
1. Finally, the remaining tags in the list are deleted from the Container Registry.
### Managing project expiration policy through the UI
### Managing project cleanup policy through the UI
To manage project expiration policy, navigate to **{settings}** **Settings > CI/CD > Container Registry tag expiration policy**.
![Expiration Policy App](img/expiration_policy_app_v13_0.png)
To manage project cleanup policy, navigate to **{settings}** **Settings > CI/CD > Container Registry tag cleanup policy**.
The UI allows you to configure the following:
- **Expiration policy:** enable or disable the expiration policy.
- **Expiration interval:** how long tags are exempt from being deleted.
- **Expiration schedule:** how often the cron job checking the tags should run.
- **Cleanup policy:** enable or disable the cleanup policy.
- **Cleanup interval:** how long tags are exempt from being deleted.
- **Cleanup schedule:** how often the cron job checking the tags should run.
- **Number of tags to retain:** how many tags to _always_ keep for each image.
- **Docker tags with names matching this regex pattern will expire:** the regex used to determine what tags should be expired. To qualify all tags for expiration, use the default value of `.*`.
- **Docker tags with names matching this regex pattern will expire:** the regex used to determine what tags should be cleaned up. To qualify all tags for cleanup, use the default value of `.*`.
- **Docker tags with names matching this regex pattern will be preserved:** the regex used to determine what tags should be preserved. To preserve all tags, use the default value of `.*`.
#### Troubleshooting expiration policies
#### Troubleshooting cleanup policies
If you see the following message:
"Something went wrong while updating the expiration policy."
"Something went wrong while updating the cleanup policy."
Check the regex patterns to ensure they are valid.
You can use [Rubular](https://rubular.com/) to check your regex.
View some common [regex pattern examples](#regex-pattern-examples).
### Managing project expiration policy through the API
### Managing project cleanup policy through the API
You can set, update, and disable the expiration policies using the GitLab API.
You can set, update, and disable the cleanup policies using the GitLab API.
Examples:
- Select all tags, keep at least 1 tag per image, expire any tag older than 14 days, run once a month, preserve any images with the name `master` and the policy is enabled:
- Select all tags, keep at least 1 tag per image, clean up any tag older than 14 days, run once a month, preserve any images with the name `master` and the policy is enabled:
```shell
curl --request PUT --header 'Content-Type: application/json;charset=UTF-8' --header "PRIVATE-TOKEN: <your_access_token>" --data-binary '{"container_expiration_policy_attributes":{"cadence":"1month","enabled":true,"keep_n":1,"older_than":"14d","name_regex":"","name_regex_delete":".*","name_regex_keep":".*-master"}}' 'https://gitlab.example.com/api/v4/projects/2'
@ -564,15 +566,15 @@ See the API documentation for further details: [Edit project](../../../api/proje
### Use with external container registries
When using an [external container registry](./../../../administration/packages/container_registry.md#use-an-external-container-registry-with-gitlab-as-an-auth-endpoint),
running an expiration policy on a project may have some performance risks. If a project is going to run
running a cleanup policy on a project may have some performance risks. If a project is going to run
a policy that will remove large quantities of tags (in the thousands), the GitLab background jobs that
run the policy may get backed up or fail completely. It is recommended you only enable container expiration
run the policy may get backed up or fail completely. It is recommended you only enable container cleanup
policies for projects that were created before GitLab 12.8 if you are confident the amount of tags
being cleaned up will be minimal.
### Regex pattern examples
Expiration policies use regex patterns to determine which tags should be preserved or removed, both in the UI and the API.
Cleanup policies use regex patterns to determine which tags should be preserved or removed, both in the UI and the API.
Here are examples of regex patterns you may want to use:
@ -616,7 +618,7 @@ once you have pushed images, because the images are signed, and the
signature includes the repository name. To move or rename a repository with a
Container Registry, you will have to delete all existing images.
- Prior to GitLab 12.10, any tags that use the same image ID as the `latest` tag
will not be deleted by the expiration policy.
will not be deleted by the cleanup policy.
## Troubleshooting the GitLab Container Registry

View file

@ -2,7 +2,7 @@
module Gitlab
module BackgroundMigration
# Base class for cleaning up concurrent schema changes.
# Base class for background migration for rename/type changes.
class CleanupConcurrentSchemaChange
include Database::MigrationHelpers
@ -10,7 +10,7 @@ module Gitlab
# old_column - The name of the old (to drop) column.
# new_column - The name of the new column.
def perform(table, old_column, new_column)
return unless column_exists?(table, new_column)
return unless column_exists?(table, new_column) && column_exists?(table, old_column)
rows_to_migrate = define_model_for(table)
.where(new_column => nil)
@ -28,6 +28,10 @@ module Gitlab
end
end
def cleanup_concurrent_schema_change(_table, _old_column, _new_column)
raise NotImplementedError
end
# These methods are necessary so we can re-use the migration helpers in
# this class.
def connection

View file

@ -2,7 +2,7 @@
module QA
context 'Create' do
describe 'Changing Gitaly repository storage', :orchestrated, :requires_admin do
describe 'Changing Gitaly repository storage', :requires_admin do
shared_examples 'repository storage move' do
it 'confirms a `finished` status after moving project repository storage' do
expect(project).to have_file('README.md')
@ -24,7 +24,7 @@ module QA
end
end
context 'when moving from one Gitaly storage to another', :repository_storage do
context 'when moving from one Gitaly storage to another', :orchestrated, :repository_storage do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'repo-storage-move-status'
@ -36,6 +36,8 @@ module QA
it_behaves_like 'repository storage move'
end
# Note: This test doesn't have the :orchestrated tag because it runs in the Test::Integration::Praefect
# scenario with other tests that aren't considered orchestrated.
context 'when moving from Gitaly to Gitaly Cluster', :requires_praefect do
let(:project) do
Resource::Project.fabricate_via_api! do |project|

View file

@ -37,9 +37,6 @@ RSpec.describe Projects::PipelinesController do
expect(json_response).to include('pipelines')
expect(json_response['pipelines'].count).to eq 6
expect(json_response['count']['all']).to eq '6'
expect(json_response['count']['running']).to eq '2'
expect(json_response['count']['pending']).to eq '1'
expect(json_response['count']['finished']).to eq '3'
json_response.dig('pipelines', 0, 'details', 'stages').tap do |stages|
expect(stages.count).to eq 3
@ -122,13 +119,15 @@ RSpec.describe Projects::PipelinesController do
end
end
context 'filter by scope' do
it 'returns matched pipelines' do
get_pipelines_index_json(scope: 'running')
context 'when user tries to access legacy scope via URL' do
it 'redirects to all pipelines with that status instead' do
get_pipelines_index_html(scope: 'running')
check_pipeline_response(returned: 2, all: 6, running: 2, pending: 1, finished: 3)
expect(response).to redirect_to(project_pipelines_path(project, status: 'running', format: :html))
end
end
context 'filter by scope' do
context 'scope is branches or tags' do
before do
create(:ci_pipeline, :failed, project: project, ref: 'v1.0.0', tag: true)
@ -140,7 +139,7 @@ RSpec.describe Projects::PipelinesController do
it 'returns matched pipelines' do
get_pipelines_index_json(scope: 'branches')
check_pipeline_response(returned: 2, all: 9, running: 2, pending: 1, finished: 6)
check_pipeline_response(returned: 2, all: 9)
end
end
@ -148,7 +147,7 @@ RSpec.describe Projects::PipelinesController do
it 'returns matched pipelines' do
get_pipelines_index_json(scope: 'tags')
check_pipeline_response(returned: 1, all: 9, running: 2, pending: 1, finished: 6)
check_pipeline_response(returned: 1, all: 9)
end
end
end
@ -161,7 +160,7 @@ RSpec.describe Projects::PipelinesController do
it 'returns matched pipelines' do
get_pipelines_index_json(username: user.username)
check_pipeline_response(returned: 1, all: 1, running: 1, pending: 0, finished: 0)
check_pipeline_response(returned: 1, all: 1)
end
end
@ -169,7 +168,7 @@ RSpec.describe Projects::PipelinesController do
it 'returns empty' do
get_pipelines_index_json(username: 'invalid-username')
check_pipeline_response(returned: 0, all: 0, running: 0, pending: 0, finished: 0)
check_pipeline_response(returned: 0, all: 0)
end
end
end
@ -181,7 +180,7 @@ RSpec.describe Projects::PipelinesController do
it 'returns matched pipelines' do
get_pipelines_index_json(ref: 'branch-1')
check_pipeline_response(returned: 1, all: 1, running: 1, pending: 0, finished: 0)
check_pipeline_response(returned: 1, all: 1)
end
end
@ -189,7 +188,7 @@ RSpec.describe Projects::PipelinesController do
it 'returns empty list' do
get_pipelines_index_json(ref: 'invalid-ref')
check_pipeline_response(returned: 0, all: 0, running: 0, pending: 0, finished: 0)
check_pipeline_response(returned: 0, all: 0)
end
end
end
@ -199,15 +198,7 @@ RSpec.describe Projects::PipelinesController do
it 'returns matched pipelines' do
get_pipelines_index_json(status: 'success')
check_pipeline_response(returned: 1, all: 1, running: 0, pending: 0, finished: 1)
end
context 'when filter by unrelated scope' do
it 'returns empty list' do
get_pipelines_index_json(status: 'success', scope: 'running')
check_pipeline_response(returned: 0, all: 1, running: 0, pending: 0, finished: 1)
end
check_pipeline_response(returned: 1, all: 1)
end
end
@ -215,7 +206,7 @@ RSpec.describe Projects::PipelinesController do
it 'returns empty list' do
get_pipelines_index_json(status: 'manual')
check_pipeline_response(returned: 0, all: 0, running: 0, pending: 0, finished: 0)
check_pipeline_response(returned: 0, all: 0)
end
end
@ -223,11 +214,19 @@ RSpec.describe Projects::PipelinesController do
it 'returns all list' do
get_pipelines_index_json(status: 'invalid-status')
check_pipeline_response(returned: 6, all: 6, running: 2, pending: 1, finished: 3)
check_pipeline_response(returned: 6, all: 6)
end
end
end
def get_pipelines_index_html(params = {})
get :index, params: {
namespace_id: project.namespace,
project_id: project
}.merge(params),
format: :html
end
def get_pipelines_index_json(params = {})
get :index, params: {
namespace_id: project.namespace,
@ -284,15 +283,12 @@ RSpec.describe Projects::PipelinesController do
)
end
def check_pipeline_response(returned:, all:, running:, pending:, finished:)
def check_pipeline_response(returned:, all:)
aggregate_failures do
expect(response).to match_response_schema('pipeline')
expect(json_response['pipelines'].count).to eq returned
expect(json_response['count']['all'].to_i).to eq all
expect(json_response['count']['running'].to_i).to eq running
expect(json_response['count']['pending'].to_i).to eq pending
expect(json_response['count']['finished'].to_i).to eq finished
end
end
end

View file

@ -34,6 +34,9 @@ const createTestMr = customConfig => {
ciStatus: null,
sha: '12345678',
squash: false,
squashIsEnabledByDefault: false,
squashIsReadonly: false,
squashIsSelected: false,
commitMessage,
squashCommitMessage,
commitMessageWithDescription,
@ -694,6 +697,37 @@ describe('ReadyToMerge', () => {
expect(findCheckboxElement().exists()).toBeFalsy();
});
describe('squash options', () => {
it.each`
squashState | state | prop | expectation
${'squashIsReadonly'} | ${'enabled'} | ${'isDisabled'} | ${false}
${'squashIsSelected'} | ${'selected'} | ${'value'} | ${false}
${'squashIsSelected'} | ${'unselected'} | ${'value'} | ${false}
`(
'is $state when squashIsReadonly returns $expectation ',
({ squashState, prop, expectation }) => {
createLocalComponent({
mr: { commitsCount: 2, enableSquashBeforeMerge: true, [squashState]: expectation },
});
expect(findCheckboxElement().props(prop)).toBe(expectation);
},
);
it('is not rendered for "Do not allow" option', () => {
createLocalComponent({
mr: {
commitsCount: 2,
enableSquashBeforeMerge: true,
squashIsReadonly: true,
squashIsSelected: false,
},
});
expect(findCheckboxElement().exists()).toBe(false);
});
});
});
describe('commits count collapsible header', () => {
@ -709,7 +743,7 @@ describe('ReadyToMerge', () => {
mr: {
ffOnlyEnabled: true,
enableSquashBeforeMerge: true,
squash: true,
squashIsSelected: true,
commitsCount: 2,
},
});
@ -803,7 +837,7 @@ describe('ReadyToMerge', () => {
createLocalComponent({
mr: {
ffOnlyEnabled: true,
squash: true,
squashIsSelected: true,
enableSquashBeforeMerge: true,
commitsCount: 2,
},
@ -824,7 +858,7 @@ describe('ReadyToMerge', () => {
createLocalComponent({
mr: {
commitsCount: 2,
squash: true,
squashIsSelected: true,
enableSquashBeforeMerge: true,
},
});
@ -854,7 +888,7 @@ describe('ReadyToMerge', () => {
createLocalComponent({
mr: {
commitsCount: 2,
squash: true,
squashIsSelected: true,
enableSquashBeforeMerge: true,
},
});
@ -872,7 +906,7 @@ describe('ReadyToMerge', () => {
it('should be rendered if squash is enabled and there is more than 1 commit', () => {
createLocalComponent({
mr: { enableSquashBeforeMerge: true, squash: true, commitsCount: 2 },
mr: { enableSquashBeforeMerge: true, squashIsSelected: true, commitsCount: 2 },
});
expect(findCommitDropdownElement().exists()).toBeTruthy();

View file

@ -63,6 +63,27 @@ describe('Squash before merge component', () => {
});
});
describe('label', () => {
const findLabel = () => wrapper.find('[data-testid="squashLabel"]');
describe.each`
isDisabled | expectation
${true} | ${'grays out text if it is true'}
${false} | ${'does not gray out text if it is false'}
`('isDisabled prop', ({ isDisabled, expectation }) => {
beforeEach(() => {
createComponent({
value: false,
isDisabled,
});
});
it(expectation, () => {
expect(findLabel().classes('gl-text-gray-600')).toBe(isDisabled);
});
});
});
describe('about link', () => {
it('is not rendered if no help path is passed', () => {
createComponent({

View file

@ -0,0 +1,28 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::CleanupConcurrentSchemaChange do
describe '#perform' do
it 'new column does not exist' do
expect(subject).to receive(:column_exists?).with(:issues, :closed_at_timestamp).and_return(false)
expect(subject).not_to receive(:column_exists?).with(:issues, :closed_at)
expect(subject).not_to receive(:define_model_for)
expect(subject.perform(:issues, :closed_at, :closed_at_timestamp)).to be_nil
end
it 'old column does not exist' do
expect(subject).to receive(:column_exists?).with(:issues, :closed_at_timestamp).and_return(true)
expect(subject).to receive(:column_exists?).with(:issues, :closed_at).and_return(false)
expect(subject).not_to receive(:define_model_for)
expect(subject.perform(:issues, :closed_at, :closed_at_timestamp)).to be_nil
end
it 'has both old and new columns' do
expect(subject).to receive(:column_exists?).twice.and_return(true)
expect { subject.perform('issues', :closed_at, :created_at) }.to raise_error(NotImplementedError)
end
end
end

View file

@ -198,6 +198,10 @@ RSpec.describe API::ImportBitbucketServer do
end
end
after do
Grape::Endpoint.before_each nil
end
it 'raises a connection error' do
post api("/import/bitbucket_server", user), params: {
bitbucket_server_url: base_uri,

View file

@ -26,6 +26,10 @@ RSpec.describe API::ImportGithub do
end
end
after do
Grape::Endpoint.before_each nil
end
it 'rejects requests when Github Importer is disabled' do
stub_application_setting(import_sources: nil)