Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
8bba6175aa
commit
7dc3246696
19 changed files with 219 additions and 111 deletions
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]
|
||||
|
|
5
changelogs/unreleased/lm-remove-counts-and-redirect.yml
Normal file
5
changelogs/unreleased/lm-remove-counts-and-redirect.yml
Normal 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 |
|
@ -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
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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 |
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue