Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-05-04 15:09:38 +00:00
parent 72797f4a60
commit 39a548dd06
24 changed files with 202 additions and 97 deletions

View file

@ -31,6 +31,7 @@ export default class FilteredSearchManager {
isGroupDecendent = false, isGroupDecendent = false,
filteredSearchTokenKeys = IssuableFilteredSearchTokenKeys, filteredSearchTokenKeys = IssuableFilteredSearchTokenKeys,
stateFiltersSelector = '.issues-state-filters', stateFiltersSelector = '.issues-state-filters',
placeholder = __('Search or filter results...'),
}) { }) {
this.isGroup = isGroup; this.isGroup = isGroup;
this.isGroupAncestor = isGroupAncestor; this.isGroupAncestor = isGroupAncestor;
@ -45,6 +46,7 @@ export default class FilteredSearchManager {
this.tokensContainer = this.container.querySelector('.tokens-container'); this.tokensContainer = this.container.querySelector('.tokens-container');
this.filteredSearchTokenKeys = filteredSearchTokenKeys; this.filteredSearchTokenKeys = filteredSearchTokenKeys;
this.stateFiltersSelector = stateFiltersSelector; this.stateFiltersSelector = stateFiltersSelector;
this.placeholder = placeholder;
const { multipleAssignees } = this.filteredSearchInput.dataset; const { multipleAssignees } = this.filteredSearchInput.dataset;
if (multipleAssignees && this.filteredSearchTokenKeys.enableMultipleAssignees) { if (multipleAssignees && this.filteredSearchTokenKeys.enableMultipleAssignees) {
@ -395,11 +397,10 @@ export default class FilteredSearchManager {
handleInputPlaceholder() { handleInputPlaceholder() {
const query = DropdownUtils.getSearchQuery(); const query = DropdownUtils.getSearchQuery();
const placeholder = __('Search or filter results...');
const currentPlaceholder = this.filteredSearchInput.placeholder; const currentPlaceholder = this.filteredSearchInput.placeholder;
if (query.length === 0 && currentPlaceholder !== placeholder) { if (query.length === 0 && currentPlaceholder !== this.placeholder) {
this.filteredSearchInput.placeholder = placeholder; this.filteredSearchInput.placeholder = this.placeholder;
} else if (query.length > 0 && currentPlaceholder !== '') { } else if (query.length > 0 && currentPlaceholder !== '') {
this.filteredSearchInput.placeholder = ''; this.filteredSearchInput.placeholder = '';
} }

View file

@ -177,6 +177,13 @@ export default {
prometheus_metric_id: this.prometheusMetricId, prometheus_metric_id: this.prometheusMetricId,
}); });
}, },
handleShown() {
if (this.configuredAlert) {
this.selectQuery(this.configuredAlert);
} else if (this.relevantQueries.length === 1) {
this.selectQuery(this.relevantQueries[0].metricId);
}
},
resetAlertData() { resetAlertData() {
this.operator = null; this.operator = null;
this.threshold = null; this.threshold = null;
@ -212,7 +219,7 @@ export default {
:ok-disabled="formDisabled" :ok-disabled="formDisabled"
@ok="handleSubmit" @ok="handleSubmit"
@hidden="handleHidden" @hidden="handleHidden"
@shown="selectQuery(configuredAlert)" @shown="handleShown"
> >
<div v-if="errorMessage" class="alert-modal-message danger_message">{{ errorMessage }}</div> <div v-if="errorMessage" class="alert-modal-message danger_message">{{ errorMessage }}</div>
<div class="alert-form"> <div class="alert-form">

View file

@ -207,11 +207,11 @@ module SearchHelper
end end
end end
def search_filter_input_options(type) def search_filter_input_options(type, placeholder = _('Search or filter results...'))
opts = opts =
{ {
id: "filtered-search-#{type}", id: "filtered-search-#{type}",
placeholder: _('Search or filter results...'), placeholder: placeholder,
data: { data: {
'username-params' => UserSerializer.new.represent(@users) 'username-params' => UserSerializer.new.represent(@users)
}, },

View file

@ -16,7 +16,7 @@
.row .row
.form-group.col-md-9 .form-group.col-md-9
= f.label :tag_list, _('Topics'), class: 'label-bold' = f.label :tag_list, _('Topics (optional)'), class: 'label-bold'
= f.text_field :tag_list, value: @project.tag_list.join(', '), maxlength: 2000, class: "form-control" = f.text_field :tag_list, value: @project.tag_list.join(', '), maxlength: 2000, class: "form-control"
%p.form-text.text-muted= _('Separate topics with commas.') %p.form-text.text-muted= _('Separate topics with commas.')

View file

@ -1,6 +1,7 @@
- type = local_assigns.fetch(:type) - type = local_assigns.fetch(:type)
- board = local_assigns.fetch(:board, nil) - board = local_assigns.fetch(:board, nil)
- show_sorting_dropdown = local_assigns.fetch(:show_sorting_dropdown, true) - show_sorting_dropdown = local_assigns.fetch(:show_sorting_dropdown, true)
- placeholder = local_assigns[:placeholder] || _('Search or filter results...')
- is_not_boards_modal_or_productivity_analytics = type != :boards_modal && type != :productivity_analytics - is_not_boards_modal_or_productivity_analytics = type != :boards_modal && type != :productivity_analytics
- block_css_class = is_not_boards_modal_or_productivity_analytics ? 'row-content-block second-block' : '' - block_css_class = is_not_boards_modal_or_productivity_analytics ? 'row-content-block second-block' : ''
- user_can_admin_list = board && can?(current_user, :admin_list, board.resource_parent) - user_can_admin_list = board && can?(current_user, :admin_list, board.resource_parent)
@ -29,7 +30,7 @@
.scroll-container .scroll-container
%ul.tokens-container.list-unstyled %ul.tokens-container.list-unstyled
%li.input-token %li.input-token
%input.form-control.filtered-search{ search_filter_input_options(type) } %input.form-control.filtered-search{ search_filter_input_options(type, placeholder) }
#js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown #js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item{ data: {hint: "#{'{{hint}}'}", tag: "#{'{{tag}}'}", action: "#{'{{hint === \'search\' ? \'submit\' : \'\' }}'}" } } %li.filter-dropdown-item{ data: {hint: "#{'{{hint}}'}", tag: "#{'{{tag}}'}", action: "#{'{{hint === \'search\' ? \'submit\' : \'\' }}'}" } }

View file

@ -0,0 +1,5 @@
---
title: Select the first option if there is only one metric option on alerts dropdown.
merge_request: 29857
author: Gilang Gumilar
type: added

View file

@ -0,0 +1,5 @@
---
title: Change placeholder in search input for Analytics features.
merge_request: 29858
author: Gilang Gumilar
type: changed

View file

@ -0,0 +1,5 @@
---
title: Indicate topics are optional
merge_request: 30264
author: Ben Bodenmiller
type: changed

View file

@ -0,0 +1,5 @@
---
title: Remove deprecated Snippet `code` attribute from Project Snippets API
merge_request: 30739
author:
type: other

View file

@ -765,6 +765,14 @@ To specify a timeframe in UTC, run:
sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss -from 2020-01-02T00:00:00+00:00 -to 2020-01-02T00:02:00+00:00 sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dataloss -from 2020-01-02T00:00:00+00:00 -to 2020-01-02T00:02:00+00:00
``` ```
### Checking repository checksums
To check a project's checksums across all nodes, the Praefect replicas Rake task can be used:
```shell
sudo gitlab-rake "gitlab:praefect:replicas[project_id]"
```
## Backend Node Recovery ## Backend Node Recovery
When a Praefect backend node fails and is no longer able to When a Praefect backend node fails and is no longer able to

View file

@ -356,7 +356,11 @@ Changes to group or project settings are logged to this file. For example:
} }
``` ```
## `sidekiq.log` ## Sidekiq Logs
For Omnibus installations, some Sidekiq logs reside in `/var/log/gitlab/sidekiq/current` and as follows.
### `sidekiq.log`
This file lives in `/var/log/gitlab/gitlab-rails/sidekiq.log` for This file lives in `/var/log/gitlab/gitlab-rails/sidekiq.log` for
Omnibus GitLab packages or in `/home/git/gitlab/log/sidekiq.log` for Omnibus GitLab packages or in `/home/git/gitlab/log/sidekiq.log` for
@ -413,7 +417,7 @@ For source installations, edit the `gitlab.yml` and set the Sidekiq
log_format: json log_format: json
``` ```
## `sidekiq_client.log` ### `sidekiq_client.log`
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26586) in GitLab 12.9. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26586) in GitLab 12.9.
@ -517,15 +521,19 @@ I, [2015-02-13T06:17:00.679433 #9291] INFO -- : Moving existing hooks directory
User clone/fetch activity using SSH transport appears in this log as `executing git command <gitaly-upload-pack...`. User clone/fetch activity using SSH transport appears in this log as `executing git command <gitaly-upload-pack...`.
## `current` ## Gitaly Logs
This file lives in `/var/log/gitlab/gitaly/current` and is produced by [runit](http://smarden.org/runit/). `runit` is packaged with Omnibus and a brief explanation of its purpose is available [in the omnibus documentation](https://docs.gitlab.com/omnibus/architecture/#runit). [Log files are rotated](http://smarden.org/runit/svlogd.8.html), renamed in unix timestamp format and `gzip`-compressed (e.g. `@1584057562.s`). This file lives in `/var/log/gitlab/gitaly/current` and is produced by [runit](http://smarden.org/runit/). `runit` is packaged with Omnibus and a brief explanation of its purpose is available [in the omnibus documentation](https://docs.gitlab.com/omnibus/architecture/#runit). [Log files are rotated](http://smarden.org/runit/svlogd.8.html), renamed in unix timestamp format and `gzip`-compressed (e.g. `@1584057562.s`).
## `unicorn_stderr.log` ### `grpc.log`
This file lives in `/var/log/gitlab/unicorn/unicorn_stderr.log` for This file lives in `/var/log/gitlab/gitlab-rails/grpc.log` for Omnibus GitLab packages. Native [gRPC](https://grpc.io/) logging used by Gitaly.
Omnibus GitLab packages or in `/home/git/gitlab/log/unicorn_stderr.log` for
installations from source. ## `unicorn_stderr.log` & `unicorn_stdout.log`
This file lives in `/var/log/gitlab/unicorn/unicorn_stderr.log` and `/var/log/gitlab/unicorn/unicorn_stdout.log` for
Omnibus GitLab packages or in `/home/git/gitlab/log/unicorn_stderr.log` and `/home/git/gitlab/log/unicorn_stdout.log`
for installations from source.
Unicorn is a high-performance forking Web server which is used for Unicorn is a high-performance forking Web server which is used for
serving the GitLab application. You can look at this log if, for serving the GitLab application. You can look at this log if, for
@ -548,6 +556,12 @@ I, [2015-02-13T07:16:01.534501 #13379] INFO -- : worker=1 spawned pid=13379
I, [2015-02-13T07:16:01.534848 #13379] INFO -- : worker=1 ready I, [2015-02-13T07:16:01.534848 #13379] INFO -- : worker=1 ready
``` ```
## `puma_stderr.log` & `puma_stdout.log`
This file lives in `/var/log/gitlab/puma/puma_stderr.log` and `/var/log/gitlab/puma/puma_stdout.log` for
Omnibus GitLab packages or in `/home/git/gitlab/log/puma_stderr.log` and `/home/git/gitlab/log/puma_stdout.log`
for installations from source.
## `repocheck.log` ## `repocheck.log`
This file lives in `/var/log/gitlab/gitlab-rails/repocheck.log` for This file lives in `/var/log/gitlab/gitlab-rails/repocheck.log` for
@ -748,9 +762,60 @@ For Omnibus installations, NGINX logs reside in:
- `/var/log/gitlab/nginx/gitlab_pages_error.log` contains a log of NGINX errors for Pages static sites. - `/var/log/gitlab/nginx/gitlab_pages_error.log` contains a log of NGINX errors for Pages static sites.
- `/var/log/gitlab/nginx/gitlab_registry_access.log` contains a log of requests made to the Container Registry. - `/var/log/gitlab/nginx/gitlab_registry_access.log` contains a log of requests made to the Container Registry.
- `/var/log/gitlab/nginx/gitlab_registry_error.log` contains a log of NGINX errors for the Container Regsitry. - `/var/log/gitlab/nginx/gitlab_registry_error.log` contains a log of NGINX errors for the Container Regsitry.
- `/var/log/gitlab/nginx/gitlab_mattermost_access.log` contains a log of requests made to Mattermost.
- `/var/log/gitlab/nginx/gitlab_mattermost_error.log` contains a log of NGINX errors for Mattermost.
Below is the default GitLab NGINX access log format: Below is the default GitLab NGINX access log format:
```plaintext ```plaintext
$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"
``` ```
## Pages Logs
For Omnibus installations, Pages logs reside in `/var/log/gitlab/gitlab-pages/current`.
For example:
```json
{
"level": "info",
"msg": "GitLab Pages Daemon",
"revision": "52b2899",
"time": "2020-04-22T17:53:12Z",
"version": "1.17.0"
}
{
"level": "info",
"msg": "URL: https://gitlab.com/gitlab-org/gitlab-pages",
"time": "2020-04-22T17:53:12Z"
}
{
"gid": 998,
"in-place": false,
"level": "info",
"msg": "running the daemon as unprivileged user",
"time": "2020-04-22T17:53:12Z",
"uid": 998
}
```
## Workhorse Logs
For Omnibus installations, Workhorse logs reside in `/var/log/gitlab/gitlab-workhorse/current`.
## PostgreSQL Logs
For Omnibus installations, PostgreSQL logs reside in `/var/log/gitlab/postgresql/current`.
## Prometheus Logs
For Omnibus installations, Prometheus logs reside in `/var/log/gitlab/prometheus/current`.
## Redis Logs
For Omnibus installations, Redis logs reside in `/var/log/gitlab/redis/current`.
## Mattermost Logs
For Omnibus installations, Mattermost logs reside in `/var/log/gitlab/mattermost/mattermost.log`.

View file

@ -18,12 +18,17 @@ You can read more about the Docker Registry at
**Omnibus GitLab installations** **Omnibus GitLab installations**
If you are using the Omnibus GitLab built in [Let's Encrypt integration](https://docs.gitlab.com/omnibus/settings/ssl.html#lets-encrypt-integration), as of GitLab 12.5, the Container Registry will be automatically enabled on port 5050 of the default domain. If you are using the Omnibus GitLab built-in [Let's Encrypt integration](https://docs.gitlab.com/omnibus/settings/ssl.html#lets-encrypt-integration), as of GitLab 12.5, the Container Registry will be automatically enabled on port 5050 of the default domain.
If you would like to use a separate domain, all you have to do is configure the domain name under which the Container If you are not using GitLab 12.5 or later, or do not use GitLab's built-in Let's Encrypt
Registry will listen to. Read integration, the GitLab Container Registry must be enabled and
[#container-registry-domain-configuration](#container-registry-domain-configuration) [configured to use an external domain](#container-registry-domain-configuration).
and pick one of the two options that fits your case.
To enable the GitLab Container Registry on your *existing* GitLab domain, refer to the section on
[configuring Container Registry to use an existing domain](#configure-container-registry-under-an-existing-gitlab-domain).
To use a *separate* domain with your Container Registry, refer to the section on
[configuring Container Registry under its own domain](#configure-container-registry-under-its-own-domain).
NOTE: **Note:** NOTE: **Note:**
The container registry works under HTTPS by default. Using HTTP is possible The container registry works under HTTPS by default. Using HTTP is possible
@ -650,7 +655,7 @@ notifications:
NOTE: **Note:** NOTE: **Note:**
The garbage collection tools are only available when you've installed GitLab The garbage collection tools are only available when you've installed GitLab
via an Omnibus package or the cloud native chart. via an Omnibus package or the [cloud native chart](https://docs.gitlab.com/charts/charts/registry/#garbage-collection).
DANGER: **Danger:** DANGER: **Danger:**
By running the built-in garbage collection command, it will cause downtime to By running the built-in garbage collection command, it will cause downtime to

View file

@ -230,18 +230,20 @@ to those documents for details.
```shell ```shell
minikube start --cpus 3 --memory 8192 # minimum amount for GitLab to work minikube start --cpus 3 --memory 8192 # minimum amount for GitLab to work
minikube addons enable ingress minikube addons enable ingress
minikube addons enable kube-dns
``` ```
- Install Helm via Homebrew and initialize it: - Install Helm via Homebrew and initialize it:
```shell ```shell
brew install kubernetes-helm brew install helm
helm init --service-account tiller
``` ```
- Copy the [Minikube minimum values YAML file](https://gitlab.com/gitlab-org/charts/gitlab/raw/master/examples/values-minikube-minimum.yaml) - Copy the [Minikube minimum values YAML file](https://gitlab.com/gitlab-org/charts/gitlab/raw/master/examples/values-minikube-minimum.yaml)
to your workstation. to your workstation:
```shell
curl --output values.yaml "https://gitlab.com/gitlab-org/charts/gitlab/raw/master/examples/values-minikube-minimum.yaml"
```
- Find the IP address in the output of `minikube ip` and update the YAML file with - Find the IP address in the output of `minikube ip` and update the YAML file with
this IP address. this IP address.
@ -250,7 +252,7 @@ to those documents for details.
```shell ```shell
helm repo add gitlab https://charts.gitlab.io helm repo add gitlab https://charts.gitlab.io
helm install --name gitlab -f <path-to-yaml-file> gitlab/gitlab helm install gitlab -f <path-to-yaml-file> gitlab/gitlab
``` ```
If you want to modify some GitLab settings, you can use the above-mentioned config If you want to modify some GitLab settings, you can use the above-mentioned config

View file

@ -4,7 +4,7 @@ This document covers using the [OAuth2](https://oauth.net/2/) protocol to allow
other services to access GitLab resources on user's behalf. other services to access GitLab resources on user's behalf.
If you want GitLab to be an OAuth authentication service provider to sign into If you want GitLab to be an OAuth authentication service provider to sign into
other services, see the [OAuth2 provider](../integration/oauth_provider.md) other services, see the [OAuth2 authentication service provider](../integration/oauth_provider.md)
documentation. This functionality is based on the documentation. This functionality is based on the
[doorkeeper Ruby gem](https://github.com/doorkeeper-gem/doorkeeper). [doorkeeper Ruby gem](https://github.com/doorkeeper-gem/doorkeeper).

View file

@ -5,6 +5,8 @@ to sign in to other services.
If you want to use: If you want to use:
- The [OAuth2](https://oauth.net/2/) protocol to access GitLab resources on user's behalf,
see [OAuth2 provider](../api/oauth2.md)
- Other OAuth authentication service providers to sign in to - Other OAuth authentication service providers to sign in to
GitLab, see the [OAuth2 client documentation](omniauth.md). GitLab, see the [OAuth2 client documentation](omniauth.md).
- The related API, see [Applications API](../api/applications.md). - The related API, see [Applications API](../api/applications.md).

View file

@ -38,7 +38,7 @@ about your Ingress traffic:
If a significant percentage of traffic is anomalous, you should If a significant percentage of traffic is anomalous, you should
investigate it for potential threats by investigate it for potential threats by
[examining the application logs](../../clusters/applications.md#web-application-firewall-modsecurity). [examining the Web Application Firewall logs](../../clusters/applications.md#web-application-firewall-modsecurity).
## Container Network Policy ## Container Network Policy

View file

@ -89,7 +89,7 @@ or over the size limit, you can [reduce your repository size with Git](../projec
| Repository size including LFS | 10G | Unlimited | | Repository size including LFS | 10G | Unlimited |
NOTE: **Note:** NOTE: **Note:**
A single `git push` is limited to 5GB. LFS is not affected by this limit. `git push` and GitLab project imports are limited to 5GB per request. Git LFS and imports other than a file upload are not affected by this limit.
## IP range ## IP range

View file

@ -35,7 +35,7 @@ To use GitLab Status Page you first need to set up your account details for your
### Status Page project ### Status Page project
To deploy the status page to AWS S3 you need to add the Status Page project & configure the necessary CI variables. To deploy the Status Page to AWS S3 you need to add the Status Page project & configure the necessary CI variables.
1. Fork the [Status Page](https://gitlab.com/gitlab-org/status-page) project. This can also be done via [Repository Mirroring](https://gitlab.com/gitlab-org/status-page#repository-mirroring) which will ensure you get the up-to-date Status Page features. 1. Fork the [Status Page](https://gitlab.com/gitlab-org/status-page) project. This can also be done via [Repository Mirroring](https://gitlab.com/gitlab-org/status-page#repository-mirroring) which will ensure you get the up-to-date Status Page features.
1. Add the following variables in **Settings > CI/CD > Variables**. (To get these variables from Amazon, use your Amazon Console): 1. Add the following variables in **Settings > CI/CD > Variables**. (To get these variables from Amazon, use your Amazon Console):
@ -43,7 +43,7 @@ To deploy the status page to AWS S3 you need to add the Status Page project & co
- `AWS_DEFAULT_REGION` - the AWS region - `AWS_DEFAULT_REGION` - the AWS region
- `AWS_ACCESS_KEY_ID` - the AWS access key ID - `AWS_ACCESS_KEY_ID` - the AWS access key ID
- `AWS_SECRET_ACCESS_KEY` - the AWS secret - `AWS_SECRET_ACCESS_KEY` - the AWS secret
1. Run the pipeline to deploy the status page to S3. 1. Run the pipeline to deploy the Status Page to S3.
### Syncing incidents to the Status Page ### Syncing incidents to the Status Page
@ -55,7 +55,7 @@ Once the CI/CD variables are set, you'll need to set up the Project you want to
## Status Page UI ## Status Page UI
The Status page landing page shows you an overview of the recent incidents. Clicking on an incident will take you to the incident's detail page. The Status Page landing page shows you an overview of the recent incidents. Clicking on an incident will take you to the incident's detail page.
![Status Page landing page](../img/status_page_incidents_v12_10.png) ![Status Page landing page](../img/status_page_incidents_v12_10.png)
@ -76,7 +76,7 @@ The incident detail page shows detailed information about a particular incident.
To publish an Incident, you first need to create an issue in the Project you enabled the Status Page settings in. To publish an Incident, you first need to create an issue in the Project you enabled the Status Page settings in.
Once this issue is created, a background worker will publish the issue onto the status page using the credentials you provided during setup. Once this issue is created, a background worker will publish the issue onto the Status Page using the credentials you provided during setup.
NOTE: **Note:** NOTE: **Note:**
Confidential issues are not published. If a published issue is made confidential it will be unpublished. Confidential issues are not published. If a published issue is made confidential it will be unpublished.
@ -99,4 +99,4 @@ Anyone with access to view the Issue can add an Emoji Award to a comment, so you
### Changing the Incident status ### Changing the Incident status
To change the incident status from `open` to `closed`, close the incident issue within GitLab. This will then be updated shortly on the Status page website. To change the incident status from `open` to `closed`, close the incident issue within GitLab. This will then be updated shortly on the Status Page website.

View file

@ -57,18 +57,15 @@ module API
params do params do
requires :title, type: String, desc: 'The title of the snippet' requires :title, type: String, desc: 'The title of the snippet'
requires :file_name, type: String, desc: 'The file name of the snippet' requires :file_name, type: String, desc: 'The file name of the snippet'
optional :code, type: String, allow_blank: false, desc: 'The content of the snippet (deprecated in favor of "content")'
optional :content, type: String, allow_blank: false, desc: 'The content of the snippet' optional :content, type: String, allow_blank: false, desc: 'The content of the snippet'
optional :description, type: String, desc: 'The description of a snippet' optional :description, type: String, desc: 'The description of a snippet'
requires :visibility, type: String, requires :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values, values: Gitlab::VisibilityLevel.string_values,
desc: 'The visibility of the snippet' desc: 'The visibility of the snippet'
mutually_exclusive :code, :content
end end
post ":id/snippets" do post ":id/snippets" do
authorize! :create_snippet, user_project authorize! :create_snippet, user_project
snippet_params = declared_params(include_missing: false).merge(request: request, api: true) snippet_params = declared_params(include_missing: false).merge(request: request, api: true)
snippet_params[:content] = snippet_params.delete(:code) if snippet_params[:code].present?
service_response = ::Snippets::CreateService.new(user_project, current_user, snippet_params).execute service_response = ::Snippets::CreateService.new(user_project, current_user, snippet_params).execute
snippet = service_response.payload[:snippet] snippet = service_response.payload[:snippet]
@ -89,14 +86,12 @@ module API
requires :snippet_id, type: Integer, desc: 'The ID of a project snippet' requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
optional :title, type: String, desc: 'The title of the snippet' optional :title, type: String, desc: 'The title of the snippet'
optional :file_name, type: String, desc: 'The file name of the snippet' optional :file_name, type: String, desc: 'The file name of the snippet'
optional :code, type: String, allow_blank: false, desc: 'The content of the snippet (deprecated in favor of "content")'
optional :content, type: String, allow_blank: false, desc: 'The content of the snippet' optional :content, type: String, allow_blank: false, desc: 'The content of the snippet'
optional :description, type: String, desc: 'The description of a snippet' optional :description, type: String, desc: 'The description of a snippet'
optional :visibility, type: String, optional :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values, values: Gitlab::VisibilityLevel.string_values,
desc: 'The visibility of the snippet' desc: 'The visibility of the snippet'
at_least_one_of :title, :file_name, :code, :content, :visibility_level at_least_one_of :title, :file_name, :content, :visibility_level
mutually_exclusive :code, :content
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
put ":id/snippets/:snippet_id" do put ":id/snippets/:snippet_id" do
@ -108,8 +103,6 @@ module API
snippet_params = declared_params(include_missing: false) snippet_params = declared_params(include_missing: false)
.merge(request: request, api: true) .merge(request: request, api: true)
snippet_params[:content] = snippet_params.delete(:code) if snippet_params[:code].present?
service_response = ::Snippets::UpdateService.new(user_project, current_user, snippet_params).execute(snippet) service_response = ::Snippets::UpdateService.new(user_project, current_user, snippet_params).execute(snippet)
snippet = service_response.payload[:snippet] snippet = service_response.payload[:snippet]

View file

@ -9295,6 +9295,9 @@ msgstr ""
msgid "Filter results by project" msgid "Filter results by project"
msgstr "" msgstr ""
msgid "Filter results..."
msgstr ""
msgid "Filter your projects by name" msgid "Filter your projects by name"
msgstr "" msgstr ""
@ -22019,7 +22022,7 @@ msgstr ""
msgid "Too many projects enabled. You will need to manage them via the console or the API." msgid "Too many projects enabled. You will need to manage them via the console or the API."
msgstr "" msgstr ""
msgid "Topics" msgid "Topics (optional)"
msgstr "" msgstr ""
msgid "Total" msgid "Total"

View file

@ -39,8 +39,8 @@
"@babel/plugin-syntax-import-meta": "^7.8.3", "@babel/plugin-syntax-import-meta": "^7.8.3",
"@babel/preset-env": "^7.8.4", "@babel/preset-env": "^7.8.4",
"@gitlab/at.js": "1.5.5", "@gitlab/at.js": "1.5.5",
"@gitlab/svgs": "1.121.0", "@gitlab/svgs": "1.123.0",
"@gitlab/ui": "13.6.1", "@gitlab/ui": "13.9.0",
"@gitlab/visual-review-tools": "1.6.1", "@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "^6.0.2-2", "@rails/actioncable": "^6.0.2-2",
"@sentry/browser": "^5.10.2", "@sentry/browser": "^5.10.2",

View file

@ -127,6 +127,38 @@ describe('AlertWidgetForm', () => {
expect(wrapper.vm.selectedAlert).toEqual(propsWithAlertData.alertsToManage[alertPath]); expect(wrapper.vm.selectedAlert).toEqual(propsWithAlertData.alertsToManage[alertPath]);
}); });
it('sets selectedAlert to the first relevantQueries if there is only one option on modal show', () => {
createComponent({
...propsWithAlertData,
configuredAlert: '',
});
modal().vm.$emit('shown');
expect(wrapper.vm.selectedAlert).toEqual(propsWithAlertData.alertsToManage[alertPath]);
});
it('does not set selectedAlert to the first relevantQueries if there is more than one option on modal show', () => {
createComponent({
relevantQueries: [
{
metricId: '8',
alertPath: 'alert',
label: 'alert-label',
},
{
metricId: '9',
alertPath: 'alert',
label: 'alert-label',
},
],
});
modal().vm.$emit('shown');
expect(wrapper.vm.selectedAlert).toEqual({});
});
describe('with existing alert', () => { describe('with existing alert', () => {
beforeEach(() => { beforeEach(() => {
createComponent(propsWithAlertData); createComponent(propsWithAlertData);

View file

@ -119,7 +119,7 @@ describe API::ProjectSnippets do
title: 'Test Title', title: 'Test Title',
file_name: 'test.rb', file_name: 'test.rb',
description: 'test description', description: 'test description',
code: 'puts "hello world"', content: 'puts "hello world"',
visibility: 'public' visibility: 'public'
} }
end end
@ -138,7 +138,7 @@ describe API::ProjectSnippets do
blob = snippet.repository.blob_at('master', params[:file_name]) blob = snippet.repository.blob_at('master', params[:file_name])
expect(blob.data).to eq params[:code] expect(blob.data).to eq params[:content]
end end
end end
@ -180,7 +180,7 @@ describe API::ProjectSnippets do
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:created)
snippet = ProjectSnippet.find(json_response['id']) snippet = ProjectSnippet.find(json_response['id'])
expect(snippet.content).to eq(params[:code]) expect(snippet.content).to eq(params[:content])
expect(snippet.description).to eq(params[:description]) expect(snippet.description).to eq(params[:description])
expect(snippet.title).to eq(params[:title]) expect(snippet.title).to eq(params[:title])
expect(snippet.file_name).to eq(params[:file_name]) expect(snippet.file_name).to eq(params[:file_name])
@ -197,7 +197,7 @@ describe API::ProjectSnippets do
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:created)
snippet = ProjectSnippet.find(json_response['id']) snippet = ProjectSnippet.find(json_response['id'])
expect(snippet.content).to eq(params[:code]) expect(snippet.content).to eq(params[:content])
expect(snippet.description).to eq(params[:description]) expect(snippet.description).to eq(params[:description])
expect(snippet.title).to eq(params[:title]) expect(snippet.title).to eq(params[:title])
expect(snippet.file_name).to eq(params[:file_name]) expect(snippet.file_name).to eq(params[:file_name])
@ -208,29 +208,6 @@ describe API::ProjectSnippets do
subject { post api("/projects/#{project.id}/snippets/", admin), params: params } subject { post api("/projects/#{project.id}/snippets/", admin), params: params }
end end
it 'creates a new snippet with content parameter' do
params[:content] = params.delete(:code)
post api("/projects/#{project.id}/snippets/", admin), params: params
expect(response).to have_gitlab_http_status(:created)
snippet = ProjectSnippet.find(json_response['id'])
expect(snippet.content).to eq(params[:content])
expect(snippet.description).to eq(params[:description])
expect(snippet.title).to eq(params[:title])
expect(snippet.file_name).to eq(params[:file_name])
expect(snippet.visibility_level).to eq(Snippet::PUBLIC)
end
it 'returns 400 when both code and content parameters specified' do
params[:content] = params[:code]
post api("/projects/#{project.id}/snippets/", admin), params: params
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('code, content are mutually exclusive')
end
it 'returns 400 for missing parameters' do it 'returns 400 for missing parameters' do
params.delete(:title) params.delete(:title)
@ -239,8 +216,8 @@ describe API::ProjectSnippets do
expect(response).to have_gitlab_http_status(:bad_request) expect(response).to have_gitlab_http_status(:bad_request)
end end
it 'returns 400 for empty code field' do it 'returns 400 for empty content field' do
params[:code] = '' params[:content] = ''
post api("/projects/#{project.id}/snippets/", admin), params: params post api("/projects/#{project.id}/snippets/", admin), params: params
@ -298,7 +275,7 @@ describe API::ProjectSnippets do
new_content = 'New content' new_content = 'New content'
new_description = 'New description' new_description = 'New description'
update_snippet(params: { code: new_content, description: new_description, visibility: 'private' }) update_snippet(params: { content: new_content, description: new_description, visibility: 'private' })
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
snippet.reload snippet.reload
@ -319,13 +296,6 @@ describe API::ProjectSnippets do
expect(snippet.description).to eq(new_description) expect(snippet.description).to eq(new_description)
end end
it 'returns 400 when both code and content parameters specified' do
update_snippet(params: { code: 'some content', content: 'other content' })
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('code, content are mutually exclusive')
end
it 'returns 404 for invalid snippet id' do it 'returns 404 for invalid snippet id' do
update_snippet(snippet_id: non_existing_record_id, params: { title: 'foo' }) update_snippet(snippet_id: non_existing_record_id, params: { title: 'foo' })
@ -339,10 +309,8 @@ describe API::ProjectSnippets do
expect(response).to have_gitlab_http_status(:bad_request) expect(response).to have_gitlab_http_status(:bad_request)
end end
it 'returns 400 for empty code field' do it 'returns 400 for empty content field' do
new_content = '' update_snippet(params: { content: '' })
update_snippet(params: { code: new_content })
expect(response).to have_gitlab_http_status(:bad_request) expect(response).to have_gitlab_http_status(:bad_request)
end end

View file

@ -782,15 +782,15 @@
eslint-plugin-vue "^6.2.1" eslint-plugin-vue "^6.2.1"
vue-eslint-parser "^7.0.0" vue-eslint-parser "^7.0.0"
"@gitlab/svgs@1.121.0": "@gitlab/svgs@1.123.0":
version "1.121.0" version "1.123.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.121.0.tgz#77083a68f72e9aa0e294da7715f378eef13b839e" resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.123.0.tgz#465946ae7afc486d6769dc38685f71747fa2fec7"
integrity sha512-scz/6Y/eED7RMFLAlhT6PwXwe0Wj8ivnRsyulk9NXKoqUmAqZliNmBmzYsHy5bFf9NB6xVV/rOk1/92nbi/Yaw== integrity sha512-lBTNnh7sEgUX3LVj6tEis9dcDDc5gKhCSUInGzswZVy9KeDAXbY850pKGPRKg/O1nVDPIe9yh7ieieWy25bkuQ==
"@gitlab/ui@13.6.1": "@gitlab/ui@13.9.0":
version "13.6.1" version "13.9.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-13.6.1.tgz#dbf1941ed762381e83f557c5ee6cc860dacee03b" resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-13.9.0.tgz#c75c3c6adc92e71a5e7915fe6d1c9fa6e2d5f85d"
integrity sha512-r8R5O8xPQUxi0yrzT5svbFhtHiZkdaf+GcXALF5oRgDTut6qOqWZ7RllHPo7RNBlyBbP30FiFvXjZlvN3PZaWQ== integrity sha512-fpjjMXAyOGIITR/Jb7zmw7ul5EAwdSdivmJsiQnwb9eetjNgVlguYu0ZZM0YAdgRXeeIRyVaS8OCqTeyD02yFQ==
dependencies: dependencies:
"@babel/standalone" "^7.0.0" "@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0" "@gitlab/vue-toasted" "^1.3.0"
@ -803,8 +803,6 @@
portal-vue "^2.1.6" portal-vue "^2.1.6"
resize-observer-polyfill "^1.5.1" resize-observer-polyfill "^1.5.1"
url-search-params-polyfill "^5.0.0" url-search-params-polyfill "^5.0.0"
vue "^2.6.10"
vue-loader "^15.4.2"
vue-runtime-helpers "^1.1.2" vue-runtime-helpers "^1.1.2"
"@gitlab/visual-review-tools@1.6.1": "@gitlab/visual-review-tools@1.6.1":
@ -11862,7 +11860,7 @@ vue-jest@^4.0.0-beta.2:
source-map "^0.5.6" source-map "^0.5.6"
ts-jest "^23.10.5" ts-jest "^23.10.5"
vue-loader@^15.4.2, vue-loader@^15.9.0: vue-loader@^15.9.0:
version "15.9.0" version "15.9.0"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.0.tgz#5d4b0378a4606188fc83e587ed23c94bc3a10998" resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.0.tgz#5d4b0378a4606188fc83e587ed23c94bc3a10998"
integrity sha512-FeDHvTSpwyLeF7LIV1PYkvqUQgTJ8UmOxhSlCyRSxaXCKk+M6NF4tDQsLsPPNeDPyR7TfRQ8MLg6v+8PsDV9xQ== integrity sha512-FeDHvTSpwyLeF7LIV1PYkvqUQgTJ8UmOxhSlCyRSxaXCKk+M6NF4tDQsLsPPNeDPyR7TfRQ8MLg6v+8PsDV9xQ==