Commit bb65ff07 authored by Mike Greiling's avatar Mike Greiling

Merge branch 'ce-to-ee-2018-09-27' into 'master'

CE upstream - 2018-09-27 06:21 UTC

Closes gitlab-ce#51299

See merge request gitlab-org/gitlab-ee!7533
parents 939284f1 6cf2c4af
......@@ -92,7 +92,7 @@ gem 'gitlab-gollum-rugged_adapter', '~> 0.4.4', require: false
gem 'github-linguist', '~> 5.3.3', require: 'linguist'
# API
gem 'grape', '~> 1.0'
gem 'grape', '~> 1.1'
gem 'grape-entity', '~> 0.7.1'
gem 'rack-cors', '~> 1.0.0', require: 'rack/cors'
......
......@@ -368,7 +368,7 @@ GEM
signet (~> 0.7)
gpgme (2.0.13)
mini_portile2 (~> 2.1)
grape (1.0.3)
grape (1.1.0)
activesupport
builder
mustermann-grape (~> 1.0.0)
......@@ -529,7 +529,7 @@ GEM
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
mustermann (1.0.2)
mustermann (1.0.3)
mustermann-grape (1.0.0)
mustermann (~> 1.0.0)
mysql2 (0.4.10)
......@@ -1078,7 +1078,7 @@ DEPENDENCIES
google-api-client (~> 0.23)
google-protobuf (= 3.5.1)
gpgme
grape (~> 1.0)
grape (~> 1.1)
grape-entity (~> 0.7.1)
grape-path-helpers (~> 1.0)
grape_logging (~> 1.7)
......
......@@ -371,7 +371,7 @@ GEM
signet (~> 0.7)
gpgme (2.0.13)
mini_portile2 (~> 2.1)
grape (1.0.3)
grape (1.1.0)
activesupport
builder
mustermann-grape (~> 1.0.0)
......@@ -532,7 +532,7 @@ GEM
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
mustermann (1.0.2)
mustermann (1.0.3)
mustermann-grape (1.0.0)
mustermann (~> 1.0.0)
mysql2 (0.4.10)
......@@ -1087,7 +1087,7 @@ DEPENDENCIES
google-api-client (~> 0.23)
google-protobuf (= 3.5.1)
gpgme
grape (~> 1.0)
grape (~> 1.1)
grape-entity (~> 0.7.1)
grape-path-helpers (~> 1.0)
grape_logging (~> 1.7)
......
<script>
import Link from '@gitlab-org/gitlab-ui/dist/components/base/link';
import { Link } from '@gitlab-org/gitlab-ui';
import ModalStore from '../../stores/modal_store';
export default {
......
import Vue from 'vue';
import Pagination from '@gitlab-org/gitlab-ui/dist/components/base/pagination';
import progressBar from '@gitlab-org/gitlab-ui/dist/components/base/progress_bar';
import modal from '@gitlab-org/gitlab-ui/dist/components/base/modal';
import loadingIcon from '@gitlab-org/gitlab-ui/dist/components/base/loading_icon';
import dModal from '@gitlab-org/gitlab-ui/dist/directives/modal';
import dTooltip from '@gitlab-org/gitlab-ui/dist/directives/tooltip';
import {
Pagination,
ProgressBar,
Modal,
LoadingIcon,
ModalDirective,
TooltipDirective,
} from '@gitlab-org/gitlab-ui';
Vue.component('gl-pagination', Pagination);
Vue.component('gl-progress-bar', progressBar);
Vue.component('gl-ui-modal', modal);
Vue.component('gl-loading-icon', loadingIcon);
Vue.component('gl-progress-bar', ProgressBar);
Vue.component('gl-ui-modal', Modal);
Vue.component('gl-loading-icon', LoadingIcon);
Vue.directive('gl-modal', dModal);
Vue.directive('gl-tooltip', dTooltip);
Vue.directive('gl-modal', ModalDirective);
Vue.directive('gl-tooltip', TooltipDirective);
......@@ -7,6 +7,13 @@ const tokenKeys = [{
symbol: '',
icon: 'messages',
tag: 'status',
}, {
key: 'type',
type: 'string',
param: 'type',
symbol: '',
icon: 'cube',
tag: 'type',
}];
const AdminRunnersFilteredSearchTokenKeys = new FilteredSearchTokenKeys(tokenKeys);
......
......@@ -97,12 +97,19 @@ export default class FilteredSearchDropdownManager {
gl: NullDropdown,
element: this.container.querySelector('#js-dropdown-admin-runner-status'),
},
type: {
reference: null,
gl: NullDropdown,
element: this.container.querySelector('#js-dropdown-admin-runner-type'),
},
// EE-only start
weight: {
reference: null,
gl: DropdownWeight,
element: this.container.querySelector('#js-dropdown-weight'),
},
// EE-only end
};
supportedTokens.forEach(type => {
......
<script>
import { mapState, mapGetters } from 'vuex';
import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
import IdeTree from './ide_tree.vue';
import ResizablePanel from './resizable_panel.vue';
import ActivityBar from './activity_bar.vue';
......
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
import FileRow from '~/vue_shared/components/file_row.vue';
import NavDropdown from './nav_dropdown.vue';
import FileRowExtra from './file_row_extra.vue';
......
......@@ -16,7 +16,7 @@ import 'vendor/jquery.atwho';
import AjaxCache from '~/lib/utils/ajax_cache';
import Vue from 'vue';
import syntaxHighlight from '~/syntax_highlight';
import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
import axios from './lib/utils/axios_utils';
import { getLocationHash } from './lib/utils/url_utility';
import Flash from './flash';
......
......@@ -3,7 +3,7 @@ import { mapState, mapActions } from 'vuex';
import imageDiffHelper from '~/image_diff/helpers/index';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
import { trimFirstCharOfLineContent } from '~/diffs/store/utils';
export default {
......
......@@ -2,7 +2,7 @@
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
import $ from 'jquery';
import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
const { CancelToken } = axios;
let axiosSource;
......
<script>
import Link from '@gitlab-org/gitlab-ui/dist/components/base/link';
import { Link } from '@gitlab-org/gitlab-ui';
export default {
components: {
......
<script>
import SkeletonLoading from '@gitlab-org/gitlab-ui/dist/components/base/skeleton_loading';
import { SkeletonLoading } from '@gitlab-org/gitlab-ui';
export default {
name: 'SkeletonNote',
......
......@@ -286,7 +286,7 @@ body {
}
.page-title {
margin-top: $gl-padding;
margin: #{2 * $grid-size} 0;
line-height: 1.3;
font-size: 1.25em;
font-weight: $gl-font-weight-bold;
......
......@@ -10,6 +10,7 @@ class Admin::RunnersFinder < UnionFinder
def execute
search!
filter_by_status!
filter_by_runner_type!
sort!
paginate!
......@@ -36,10 +37,11 @@ class Admin::RunnersFinder < UnionFinder
end
def filter_by_status!
status = @params[:status_status]
if status.present? && Ci::Runner::AVAILABLE_STATUSES.include?(status)
@runners = @runners.public_send(status) # rubocop:disable GitlabSecurity/PublicSend
end
filter_by!(:status_status, Ci::Runner::AVAILABLE_STATUSES)
end
def filter_by_runner_type!
filter_by!(:type_type, Ci::Runner::AVAILABLE_TYPES)
end
def sort!
......@@ -49,4 +51,12 @@ class Admin::RunnersFinder < UnionFinder
def paginate!
@runners = @runners.page(@params[:page]).per(NUMBER_OF_RUNNERS_PER_PAGE)
end
def filter_by!(scope_name, available_scopes)
scope = @params[scope_name]
if scope.present? && available_scopes.include?(scope)
@runners = @runners.public_send(scope) # rubocop:disable GitlabSecurity/PublicSend
end
end
end
......@@ -10,12 +10,24 @@ module Ci
include FromUnion
prepend EE::Ci::Runner
enum access_level: {
not_protected: 0,
ref_protected: 1
}
enum runner_type: {
instance_type: 1,
group_type: 2,
project_type: 3
}
RUNNER_QUEUE_EXPIRY_TIME = 60.minutes
ONLINE_CONTACT_TIMEOUT = 1.hour
UPDATE_DB_RUNNER_INFO_EVERY = 40.minutes
AVAILABLE_TYPES = %w[specific shared].freeze
AVAILABLE_TYPES_LEGACY = %w[specific shared].freeze
AVAILABLE_TYPES = runner_types.keys.freeze
AVAILABLE_STATUSES = %w[active paused online offline].freeze
AVAILABLE_SCOPES = (AVAILABLE_TYPES + AVAILABLE_STATUSES).freeze
AVAILABLE_SCOPES = (AVAILABLE_TYPES_LEGACY + AVAILABLE_TYPES + AVAILABLE_STATUSES).freeze
FORM_EDITABLE = %i[description tag_list active run_untagged locked access_level maximum_timeout_human_readable].freeze
ignore_column :is_shared
......@@ -98,17 +110,6 @@ module Ci
after_destroy :cleanup_runner_queue
enum access_level: {
not_protected: 0,
ref_protected: 1
}
enum runner_type: {
instance_type: 1,
group_type: 2,
project_type: 3
}
cached_attr_reader :version, :revision, :platform, :architecture, :ip_address, :contacted_at
chronic_duration_attr :maximum_timeout_human_readable, :maximum_timeout
......
......@@ -83,12 +83,21 @@
{{hint}}
%span.js-filter-tag.dropdown-light-content
{{tag}}
#js-dropdown-admin-runner-status.filtered-search-input-dropdown-menu.dropdown-menu
%ul{ data: { dropdown: true } }
- Ci::Runner::AVAILABLE_STATUSES.each do |status|
%li.filter-dropdown-item{ data: { value: status } }
= button_tag class: %w[btn btn-link] do
= status.titleize
#js-dropdown-admin-runner-type.filtered-search-input-dropdown-menu.dropdown-menu
%ul{ data: { dropdown: true } }
- Ci::Runner::AVAILABLE_TYPES.each do |runner_type|
%li.filter-dropdown-item{ data: { value: runner_type } }
= button_tag class: %w[btn btn-link] do
= runner_type.titleize
= button_tag class: %w[clear-search hidden] do
= icon('times')
.filter-dropdown-container
......
......@@ -15,12 +15,12 @@
- new_project_label = _("New project")
- new_subgroup_label = _("New subgroup")
- if can_create_subgroups
.btn-group.new-project-subgroup.droplab-dropdown.js-new-project-subgroup{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } }
%input.btn.btn-success.dropdown-primary.js-new-group-child{ type: "button", value: new_project_label, data: { action: "new-project" } }
%button.btn.btn-success.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } }
.btn-group.new-project-subgroup.droplab-dropdown.js-new-project-subgroup.qa-new-project-or-subgroup-dropdown{ data: { project_path: new_project_path(namespace_id: @group.id), subgroup_path: new_group_path(parent_id: @group.id) } }
%input.btn.btn-success.dropdown-primary.js-new-group-child.qa-new-in-group-button{ type: "button", value: new_project_label, data: { action: "new-project" } }
%button.btn.btn-success.dropdown-toggle.js-dropdown-toggle.qa-new-project-or-subgroup-dropdown-toggle{ type: "button", data: { "dropdown-trigger" => "#new-project-or-subgroup-dropdown", 'display' => 'static' } }
= icon("caret-down", class: "dropdown-btn-icon")
%ul#new-project-or-subgroup-dropdown.dropdown-menu.dropdown-menu-right{ data: { dropdown: true } }
%li.droplab-item-selected{ role: "button", data: { value: "new-project", text: new_project_label } }
%li.droplab-item-selected.qa-new-project-option{ role: "button", data: { value: "new-project", text: new_project_label } }
.menu-item
.icon-container
= icon("check", class: "list-item-checkmark")
......@@ -28,7 +28,7 @@
%strong= new_project_label
%span= s_("GroupsTree|Create a project in this group.")
%li.divider.droplap-item-ignore
%li{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } }
%li.qa-new-subgroup-option{ role: "button", data: { value: "new-subgroup", text: new_subgroup_label } }
.menu-item
.icon-container
= icon("check", class: "list-item-checkmark")
......
......@@ -10,7 +10,7 @@
.row
.form-group.project-name.col-sm-12
= label_tag :name, _('Project name'), class: 'label-bold'
= text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control input-lg", autofocus: true, required: true
= text_field_tag :name, @name, placeholder: "My awesome project", class: "js-project-name form-control input-lg", autofocus: true
.form-group.col-12.col-sm-6
= label_tag :namespace_id, _('Project URL'), class: 'label-bold'
.form-group
......
......@@ -7,7 +7,7 @@
.form-group.project-name.col-sm-12
= f.label :name, class: 'label-bold' do
%span= _("Project name")
= f.text_field :name, placeholder: "My awesome project", class: "form-control input-lg", autofocus: true, required: true
= f.text_field :name, placeholder: "My awesome project", class: "form-control input-lg", autofocus: true
.form-group.project-path.col-sm-6
= f.label :namespace_id, class: 'label-bold' do
%span= s_("Project URL")
......
---
title: Removes the 'required' attribute from the 'project name' field
merge_request: 21770
author:
type: other
---
title: Add a type filter to the admin runners view
merge_request: 19649
author: Alexis Reigel
type: added
---
title: Change vertical margin of page titles to 16px
merge_request: 21888
author:
type: changed
......@@ -11,11 +11,15 @@ Get a list of specific runners available to the user.
```
GET /runners
GET /runners?scope=active
GET /runners?type=project_type
GET /runners?status=active
```
| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
| `scope` | string | no | The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided |
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/runners"
......@@ -56,11 +60,15 @@ is restricted to users with `admin` privileges.
```
GET /runners/all
GET /runners/all?scope=online
GET /runners/all?type=project_type
GET /runners/all?status=active
```
| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
| `scope` | string | no | The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online`, `offline`; showing all runners if none provided |
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online`, `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/runners/all"
......@@ -336,11 +344,17 @@ usage is enabled in the project's settings.
```
GET /projects/:id/runners
GET /projects/:id/runners?scope=active
GET /projects/:id/runners?type=project_type
GET /projects/:id/runners?status=active
```
| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
| Attribute | Type | Required | Description |
|-----------|----------------|----------|---------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/9/runners"
......
......@@ -139,5 +139,3 @@ your whole GitLab instance as well as in each project.
- [New CI job permissions model](../user/project/new_ci_build_permissions_model.md)
Read about what changed in GitLab 8.12 and how that affects your jobs.
There's a new way to access your Git submodules and LFS objects in jobs.
[gitlab-ci-templates]: https://gitlab.com/gitlab-org/gitlab-ci-yml
......@@ -178,8 +178,8 @@ runs of jobs for things like dependencies and commonly used libraries
so they don't have to be re-fetched from the public internet.
NOTE: **Note:**
For more examples, check the [GitLab CI Yml](https://gitlab.com/gitlab-org/gitlab-ci-yml)
project.
For more examples, check out our [GitLab CI/CD
templates](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates).
### Caching Nodejs dependencies
......@@ -190,7 +190,7 @@ Nodejs modules are installed in `node_modules/` and are cached per-branch:
```yaml
#
# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Nodejs.gitlab-ci.yml
# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
#
image: node:latest
......@@ -217,7 +217,7 @@ are cached per-branch:
```yaml
#
# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/PHP.gitlab-ci.yml
# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
#
image: php:7.2
......@@ -246,7 +246,7 @@ pip's cache is defined under `.cache/pip/` and both are cached per-branch:
```yaml
#
# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Python.gitlab-ci.yml
# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml
#
image: python:latest
......@@ -286,7 +286,7 @@ jobs inherit it. Gems are installed in `vendor/ruby/` and are cached per-branch:
```yaml
#
# https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Ruby.gitlab-ci.yml
# https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
#
image: ruby:2.5
......
......@@ -4,8 +4,8 @@ comments: false
# GitLab CI/CD Examples
A collection of `.gitlab-ci.yml` template files is maintained at the [GitLab CI/CD YAML project][gitlab-ci-templates]. When you create a new file via the UI,
GitLab will give you the option to choose one of the templates existent on this project.
A collection of [`.gitlab-ci.yml` template files][gitlab-ci-templates] is maintained in GitLab. When you create a new file via the UI,
GitLab will give you the option to choose one of these templates.
If your favorite programming language or framework are missing we would love your
help by sending a merge request with a new `.gitlab-ci.yml` to this project.
......@@ -95,4 +95,4 @@ language users and GitLab by sending a merge request with a guide for that langu
You may want to apply for the [GitLab Community Writers Program](https://about.gitlab.com/community-writers/)
to get paid for writing complete articles for GitLab.
[gitlab-ci-templates]: https://gitlab.com/gitlab-org/gitlab-ci-yml
[gitlab-ci-templates]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/lib/gitlab/ci/templates
......@@ -110,4 +110,4 @@ performance:
- sitespeed-results/
```
A complete example can be found in our [Auto DevOps CI YML](https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml).
A complete example can be found in our [Auto DevOps CI YML](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml).
......@@ -74,7 +74,7 @@ on making Review Apps automatically deployed by each pipeline, both in CE and EE
[review-apps-ee]: https://console.cloud.google.com/kubernetes/clusters/details/us-central1-b/review-apps-ee?project=gitlab-review-apps
[review-apps.sh]: https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/review_apps/review-apps.sh
[automated_cleanup.rb]: https://gitlab.com/gitlab-org/gitlab-ee/blob/master/scripts/review_apps/automated_cleanup.rb
[Auto-DevOps.gitlab-ci.yml]: https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml
[Auto-DevOps.gitlab-ci.yml]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
[gitlab-k8s-integration]: https://docs.gitlab.com/ee/user/project/clusters/index.html
---
......
......@@ -145,7 +145,7 @@ When using Auto DevOps, you may want to deploy different environments to
different Kubernetes clusters. This is possible due to the 1:1 connection that
[exists between them](../../user/project/clusters/index.md#multiple-kubernetes-clusters).
In the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml)
In the [Auto DevOps template](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml)
(used behind the scenes by Auto DevOps), there are currently 3 defined environment names that you need to know:
- `review/` (every environment starting with `review/`)
......@@ -832,6 +832,6 @@ curl --data "value=true" --header "PRIVATE-TOKEN: personal_access_token" https:/
[review-app]: ../../ci/review_apps/index.md
[container-registry]: ../../user/project/container_registry.md
[postgresql]: https://www.postgresql.org/
[Auto DevOps template]: https://gitlab.com/gitlab-org/gitlab-ci-yml/blob/master/Auto-DevOps.gitlab-ci.yml
[Auto DevOps template]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
[ee]: https://about.gitlab.com/pricing/
[ce-19507]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19507
......@@ -11,10 +11,18 @@ module API
params do
optional :scope, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
desc: 'The scope of specific runners to show'
optional :type, type: String, values: Ci::Runner::AVAILABLE_TYPES,
desc: 'The type of the runners to show'
optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
desc: 'The status of the runners to show'
use :pagination
end
get do
runners = filter_runners(current_user.ci_owned_runners, params[:scope], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
runners = current_user.ci_owned_runners
runners = filter_runners(runners, params[:scope], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES)
runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
present paginate(runners), with: Entities::Runner
end
......@@ -24,11 +32,20 @@ module API
params do
optional :scope, type: String, values: Ci::Runner::AVAILABLE_SCOPES,
desc: 'The scope of specific runners to show'
optional :type, type: String, values: Ci::Runner::AVAILABLE_TYPES,
desc: 'The type of the runners to show'
optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
desc: 'The status of the runners to show'
use :pagination
end
get 'all' do
authenticated_as_admin!
runners = filter_runners(Ci::Runner.all, params[:scope])
runners = Ci::Runner.all
runners = filter_runners(runners, params[:scope])
runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES)
runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
present paginate(runners), with: Entities::Runner
end
......@@ -116,10 +133,18 @@ module API
params do
optional :scope, type: String, values: Ci::Runner::AVAILABLE_SCOPES,
desc: 'The scope of specific runners to show'
optional :type, type: String, values: Ci::Runner::AVAILABLE_TYPES,
desc: 'The type of the runners to show'
optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
desc: 'The status of the runners to show'
use :pagination
end
get ':id/runners' do
runners = filter_runners(Ci::Runner.owned_or_instance_wide(user_project.id), params[:scope])
runners = Ci::Runner.owned_or_instance_wide(user_project.id)
runners = filter_runners(runners, params[:scope])
runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES)
runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
present paginate(runners), with: Entities::Runner
end
......
......@@ -20,7 +20,7 @@ module Gitlab
end
def base_dir
Rails.root.join('vendor/gitlab-ci-yml')
Rails.root.join('lib/gitlab/ci/templates')
end
def finder(project = nil)
......
......@@ -99,10 +99,6 @@ namespace :gitlab do
"https://github.com/github/gitignore.git",
/(\.{1,2}|LICENSE|Global|\.gitignore)\z/
),
Template.new(
"https://gitlab.com/gitlab-org/gitlab-ci-yml.git",
/(\.{1,2}|LICENSE|CONTRIBUTING.md|Pages|autodeploy|\.gitlab-ci.yml)\z/
),
Template.new(
"https://gitlab.com/gitlab-org/Dockerfile.git",
/(\.{1,2}|LICENSE|CONTRIBUTING.md|\.Dockerfile)\z/
......
......@@ -5,14 +5,11 @@ module QA
include Page::Component::GroupsFilter
view 'app/views/groups/show.html.haml' do
element :new_project_or_subgroup_dropdown, '.new-project-subgroup'
element :new_project_or_subgroup_dropdown_toggle, '.dropdown-toggle'
element :new_project_option, /%li.*data:.*value: "new-project"/
element :new_project_button, /%input.*data:.*action: "new-project"/
element :new_subgroup_option, /%li.*data:.*value: "new-subgroup"/
# data-value and data-action get modified by JS for subgroup
element :new_subgroup_button, /%input.*\.js-new-group-child/
element :new_project_or_subgroup_dropdown
element :new_project_or_subgroup_dropdown_toggle
element :new_project_option
element :new_subgroup_option
element :new_in_group_button
end
view 'app/assets/javascripts/groups/constants.js' do
......@@ -24,7 +21,7 @@ module QA
end
def has_new_project_or_subgroup_dropdown?
page.has_css?(element_selector_css(:new_project_or_subgroup_dropdown))
has_element?(:new_project_or_subgroup_dropdown)
end
def has_subgroup?(name)
......@@ -36,31 +33,29 @@ module QA
end
def go_to_new_subgroup
click_new('subgroup')
select_kind :new_subgroup_option
find("input[data-action='new-subgroup']").click
click_element :new_in_group_button
end
def go_to_new_project
click_new('project')
select_kind :new_project_option
find("input[data-action='new-project']").click
click_element :new_in_group_button
end
private
def click_new(kind)
within '.new-project-subgroup' do
css = "li[data-value='new-#{kind}']"
def select_kind(kind)
within_element(:new_project_or_subgroup_dropdown) do
# May need to click again because it is possible to click the button quicker than the JS is bound
wait(reload: false) do
find('.dropdown-toggle').click
click_element :new_project_or_subgroup_dropdown_toggle
page.has_css?(css)
has_element?(kind)
end
find(css).click
click_element kind
end
end
end
......
......@@ -73,24 +73,72 @@ describe "Admin Runners" do
expect(page).to have_text 'No runners found'
end
it 'shows correct runner when status is selected and search term is entered' do
create(:ci_runner, description: 'runner-a-1', active: true)
create(:ci_runner, description: 'runner-a-2', active: false)
create(:ci_runner, description: 'runner-b-1', active: true)
visit admin_runners_path
input_filtered_search_keys('status:active')
expect(page).to have_content 'runner-a-1'
expect(page).to have_content 'runner-b-1'
expect(page).not_to have_content 'runner-a-2'
input_filtered_search_keys('status:active runner-a')
expect(page).to have_content 'runner-a-1'
expect(page).not_to have_content 'runner-b-1'
expect(page).not_to have_content 'runner-a-2'
end
end
it 'shows correct runner when status is selected and search term is entered', :js do
create(:ci_runner, description: 'runner-a-1', active: true)
create(:ci_runner, description: 'runner-a-2', active: false)
create(:ci_runner, description: 'runner-b-1', active: true)
describe 'filter by type', :js do
it 'shows correct runner when type matches' do
create :ci_runner, :project, description: 'runner-project'
create :ci_runner, :group, description: 'runner-group'
visit admin_runners_path
visit admin_runners_path
expect(page).to have_content 'runner-project'
expect(page).to have_content 'runner-group'
input_filtered_search_keys('status:active')
expect(page).to have_content 'runner-a-1'
expect(page).to have_content 'runner-b-1'
expect(page).not_to have_content 'runner-a-2'
input_filtered_search_keys('type:project_type')
expect(page).to have_content 'runner-project'
expect(page).not_to have_content 'runner-group'
end
it 'shows no runner when type does not match' do
create :ci_runner, :project, description: 'runner-project'
create :ci_runner, :group, description: 'runner-group'
input_filtered_search_keys('status:active runner-a')
expect(page).to have_content 'runner-a-1'
expect(page).not_to have_content 'runner-b-1'
expect(page).not_to have_content 'runner-a-2'
visit admin_runners_path
input_filtered_search_keys('type:instance_type')
expect(page).not_to have_content 'runner-project'
expect(page).not_to have_content 'runner-group'
expect(page).to have_text 'No runners found'
end
it 'shows correct runner when type is selected and search term is entered' do
create :ci_runner, :project, description: 'runner-a-1'
create :ci_runner, :instance, description: 'runner-a-2'
create :ci_runner, :project, description: 'runner-b-1'
visit admin_runners_path
input_filtered_search_keys('type:project_type')
expect(page).to have_content 'runner-a-1'
expect(page).to have_content 'runner-b-1'
expect(page).not_to have_content 'runner-a-2'
input_filtered_search_keys('type:project_type runner-a')
expect(page).to have_content 'runner-a-1'
expect(page).not_to have_content 'runner-b-1'
expect(page).not_to have_content 'runner-a-2'
end
end
it 'sorts by last contact date', :js do
......
......@@ -29,6 +29,14 @@ describe Admin::RunnersFinder do
end
end
context 'filter by runner type' do
it 'calls the corresponding scope on Ci::Runner' do
expect(Ci::Runner).to receive(:project_type).and_call_original
described_class.new(params: { type_type: 'project_type' }).execute
end
end
context 'sort' do
context 'without sort param' do
it 'sorts by created_at' do
......
......@@ -8,7 +8,7 @@ describe Gitlab::Ci::External::File::Local do
describe '#valid?' do
context 'when is a valid local path' do
let(:location) { '/vendor/gitlab-ci-yml/existent-file.yml' }
let(:location) { '/lib/gitlab/ci/templates/existent-file.yml' }
before do
allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return("image: 'ruby2:2'")
......@@ -20,7 +20,7 @@ describe Gitlab::Ci::External::File::Local do
end
context 'when is not a valid local path' do
let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' }
let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
it 'should return false' do
expect(local_file.valid?).to be_falsy
......@@ -48,7 +48,7 @@ describe Gitlab::Ci::External::File::Local do
- bundle install --jobs $(nproc) "${FLAGS[@]}"
HEREDOC
end
let(:location) { '/vendor/gitlab-ci-yml/existent-file.yml' }
let(:location) { '/lib/gitlab/ci/templates/existent-file.yml' }
before do
allow_any_instance_of(described_class).to receive(:fetch_local_content).and_return(local_file_content)
......@@ -60,7 +60,7 @@ describe Gitlab::Ci::External::File::Local do
end
context 'with an invalid file' do
let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' }
let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
it 'should be nil' do
expect(local_file.content).to be_nil
......@@ -69,7 +69,7 @@ describe Gitlab::Ci::External::File::Local do
end
describe '#error_message' do
let(:location) { '/vendor/gitlab-ci-yml/non-existent-file.yml' }
let(:location) { '/lib/gitlab/ci/templates/non-existent-file.yml' }
it 'should return an error message' do
expect(local_file.error_message).to eq("Local file '#{location}' is not valid.")
......
......@@ -17,7 +17,7 @@ describe Gitlab::Ci::External::Mapper do
context 'when the string is a local file' do
let(:values) do
{
include: '/vendor/gitlab-ci-yml/non-existent-file.yml',
include: '/lib/gitlab/ci/templates/non-existent-file.yml',
image: 'ruby:2.2'
}
end
......@@ -61,7 +61,7 @@ describe Gitlab::Ci::External::Mapper do
include:
[
remote_url,
'/vendor/gitlab-ci-yml/template.yml'
'/lib/gitlab/ci/templates/template.yml'
],
image: 'ruby:2.2'
}
......
......@@ -16,12 +16,12 @@ describe Gitlab::Ci::External::Processor do
end
context 'when an invalid local file is defined' do
let(:values) { { include: '/vendor/gitlab-ci-yml/non-existent-file.yml', image: 'ruby:2.2' } }
let(:values) { { include: '/lib/gitlab/ci/templates/non-existent-file.yml', image: 'ruby:2.2' } }
it 'should raise an error' do
expect { processor.perform }.to raise_error(
described_class::FileError,
"Local file '/vendor/gitlab-ci-yml/non-existent-file.yml' is not valid."
"Local file '/lib/gitlab/ci/templates/non-existent-file.yml' is not valid."
)
end
end
......@@ -79,7 +79,7 @@ describe Gitlab::Ci::External::Processor do
end
context 'with a valid local external file is defined' do
let(:values) { { include: '/vendor/gitlab-ci-yml/template.yml', image: 'ruby:2.2' } }
let(:values) { { include: '/lib/gitlab/ci/templates/template.yml', image: 'ruby:2.2' } }
let(:local_file_content) do
<<-HEREDOC
before_script:
......@@ -145,7 +145,7 @@ describe Gitlab::Ci::External::Processor do
end
context 'when external files are defined but not valid' do
let(:values) { { include: '/vendor/gitlab-ci-yml/template.yml', image: 'ruby:2.2' } }
let(:values) { { include: '/lib/gitlab/ci/templates/template.yml', image: 'ruby:2.2' } }
let(:local_file_content) { 'invalid content file ////' }
......
# frozen_string_literal: true
require 'spec_helper'
describe "CI YML Templates" do
Gitlab::Template::GitlabCiYmlTemplate.all.each do |template|
it "#{template.name} should be valid" do
expect { Gitlab::Ci::YamlProcessor.new(template.content) }.not_to raise_error
end
end
end
......@@ -1371,18 +1371,6 @@ module Gitlab
end
end
describe "Validate configuration templates" do
templates = Dir.glob("#{Rails.root.join('vendor/gitlab-ci-yml')}/**/*.gitlab-ci.yml")
templates.each do |file|
it "does not return errors for #{file}" do
file = File.read(file)
expect { Gitlab::Ci::YamlProcessor.new(file) }.not_to raise_error
end
end
end
describe "#validation_message" do
subject { Gitlab::Ci::YamlProcessor.validation_message(content) }
......
......@@ -40,7 +40,7 @@ describe Gitlab::Template::GitlabCiYmlTemplate do
describe '#content' do
it 'loads the full file' do
gitignore = subject.new(Rails.root.join('vendor/gitlab-ci-yml/Ruby.gitlab-ci.yml'))
gitignore = subject.new(Rails.root.join('lib/gitlab/ci/templates/Ruby.gitlab-ci.yml'))
expect(gitignore.name).to eq 'Ruby'
expect(gitignore.content).to start_with('#')
......
......@@ -25,36 +25,71 @@ describe API::Runners do
describe 'GET /runners' do
context 'authorized user' do
it 'returns user available runners' do
it 'returns response status and headers' do
get api('/runners', user)
shared = json_response.any? { |r| r['is_shared'] }
descriptions = json_response.map { |runner| runner['description'] }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response[0]).to have_key('ip_address')
expect(descriptions).to contain_exactly(
'Project runner', 'Two projects runner', 'Group runner'
)
expect(shared).to be_falsey
end
it 'returns user available runners' do
get api('/runners', user)
expect(json_response).to match_array [
a_hash_including('description' => 'Project runner'),
a_hash_including('description' => 'Two projects runner'),
a_hash_including('description' => 'Group runner')
]
end
it 'filters runners by scope' do
get api('/runners?scope=active', user)
create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project])
get api('/runners?scope=paused', user)
shared = json_response.any? { |r| r['is_shared'] }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response[0]).to have_key('ip_address')
expect(shared).to be_falsey
expect(json_response).to match_array [
a_hash_including('description' => 'Inactive project runner')
]
end
it 'avoids filtering if scope is invalid' do
get api('/runners?scope=unknown', user)
expect(response).to have_gitlab_http_status(400)
end
it 'filters runners by type' do
get api('/runners?type=project_type', user)
expect(json_response).to match_array [
a_hash_including('description' => 'Project runner'),
a_hash_including('description' => 'Two projects runner')
]
end
it 'does not filter by invalid type' do
get api('/runners?type=bogus', user)
expect(response).to have_gitlab_http_status(400)
end
it 'filters runners by status' do
create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project])
get api('/runners?status=paused', user)
expect(json_response).to match_array [
a_hash_including('description' => 'Inactive project runner')
]
end
it 'does not filter by invalid status' do
get api('/runners?status=bogus', user)
expect(response).to have_gitlab_http_status(400)
end
end
context 'unauthorized user' do
......@@ -69,51 +104,91 @@ describe API::Runners do
describe 'GET /runners/all' do
context 'authorized user' do
context 'with admin privileges' do
it 'returns response status and headers' do
get api('/runners/all', admin)
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
end
it 'returns all runners' do
get api('/runners/all', admin)
shared = json_response.any? { |r| r['is_shared'] }
expect(json_response).to match_array [
a_hash_including('description' => 'Project runner'),
a_hash_including('description' => 'Two projects runner'),
a_hash_including('description' => 'Group runner'),
a_hash_including('description' => 'Shared runner')
]
end
it 'filters runners by scope' do
get api('/runners/all?scope=shared', admin)
shared = json_response.all? { |r| r['is_shared'] }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response[0]).to have_key('ip_address')
expect(shared).to be_truthy
end
end
context 'without admin privileges' do
it 'does not return runners list' do
get api('/runners/all', user)
it 'filters runners by scope' do
get api('/runners/all?scope=specific', admin)
expect(response).to have_gitlab_http_status(403)
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to match_array [
a_hash_including('description' => 'Project runner'),
a_hash_including('description' => 'Two projects runner'),
a_hash_including('description' => 'Group runner')
]
end
end
it 'filters runners by scope' do
get api('/runners/all?scope=shared', admin)
it 'avoids filtering if scope is invalid' do
get api('/runners/all?scope=unknown', admin)
expect(response).to have_gitlab_http_status(400)
end
shared = json_response.all? { |r| r['is_shared'] }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response[0]).to have_key('ip_address')
expect(shared).to be_truthy
end
it 'filters runners by type' do
get api('/runners/all?type=project_type', admin)
it 'filters runners by scope' do
get api('/runners/all?scope=specific', admin)
expect(json_response).to match_array [
a_hash_including('description' => 'Project runner'),
a_hash_including('description' => 'Two projects runner')
]
end
shared = json_response.any? { |r| r['is_shared'] }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response[0]).to have_key('ip_address')
expect(shared).to be_falsey
it 'does not filter by invalid type' do
get api('/runners/all?type=bogus', admin)
expect(response).to have_gitlab_http_status(400)
end
it 'filters runners by status' do
create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project])
get api('/runners/all?status=paused', admin)
expect(json_response).to match_array [
a_hash_including('description' => 'Inactive project runner')
]
end
it 'does not filter by invalid status' do
get api('/runners/all?status=bogus', admin)
expect(response).to have_gitlab_http_status(400)
end
end
it 'avoids filtering if scope is invalid' do
get api('/runners?scope=unknown', admin)
expect(response).to have_gitlab_http_status(400)
context 'without admin privileges' do
it 'does not return runners list' do
get api('/runners/all', user)
expect(response).to have_gitlab_http_status(403)
end
end
end
......@@ -577,15 +652,69 @@ describe API::Runners do
describe 'GET /projects/:id/runners' do
context 'authorized user with maintainer privileges' do
it "returns project's runners" do
it 'returns response status and headers' do
get api('/runners/all', admin)
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
end
it 'returns all runners' do
get api("/projects/#{project.id}/runners", user)
shared = json_response.any? { |r| r['is_shared'] }
expect(json_response).to match_array [
a_hash_including('description' => 'Project runner'),
a_hash_including('description' => 'Two projects runner'),
a_hash_including('description' => 'Shared runner')
]
end
it 'filters runners by scope' do
get api("/projects/#{project.id}/runners?scope=specific", user)
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response[0]).to have_key('ip_address')
expect(shared).to be_truthy
expect(json_response).to match_array [
a_hash_including('description' => 'Project runner'),
a_hash_including('description' => 'Two projects runner')
]
end
it 'avoids filtering if scope is invalid' do
get api("/projects/#{project.id}/runners?scope=unknown", user)
expect(response).to have_gitlab_http_status(400)
end
it 'filters runners by type' do
get api("/projects/#{project.id}/runners?type=project_type", user)
expect(json_response).to match_array [
a_hash_including('description' => 'Project runner'),
a_hash_including('description' => 'Two projects runner')
]
end
it 'does not filter by invalid type' do
get api("/projects/#{project.id}/runners?type=bogus", user)
expect(response).to have_gitlab_http_status(400)
end
it 'filters runners by status' do
create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project])
get api("/projects/#{project.id}/runners?status=paused", user)
expect(json_response).to match_array [
a_hash_including('description' => 'Inactive project runner')
]
end
it 'does not filter by invalid status' do
get api("/projects/#{project.id}/runners?status=bogus", user)
expect(response).to have_gitlab_http_status(400)
end
end
......
image: ruby:2.4-alpine
test:
script: ./verify_templates.rb
## Developer Certificate of Origin + License
By contributing to GitLab B.V., You accept and agree to the following terms and
conditions for Your present and future Contributions submitted to GitLab B.V.
Except for the license granted herein to GitLab B.V. and recipients of software
distributed by GitLab B.V., You reserve all right, title, and interest in and to
Your Contributions. All Contributions are subject to the following DCO + License
terms.
[DCO + License](https://gitlab.com/gitlab-org/dco/blob/master/README.md)
_This notice should stay as the first item in the CONTRIBUTING.md file._
## Code of conduct
As contributors and maintainers of this project, we pledge to respect all people
who contribute through reporting issues, posting feature requests, updating
documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual
language or imagery, derogatory comments or personal attacks, trolling, public
or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct. Project maintainers who do not follow the
Code of Conduct may be removed from the project team.
This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior can be
reported by emailing contact@gitlab.com.
This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant], version 1.1.0,
available at [http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/).
[contributor-covenant]: http://contributor-covenant.org
[individual-agreement]: https://docs.gitlab.com/ee/legal/individual_contributor_license_agreement.html
[corporate-agreement]: https://docs.gitlab.com/ee/legal/corporate_contributor_license_agreement.html
Copyright (c) 2011-2017 GitLab B.V.
With regard to the GitLab Software:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
For all third party components incorporated into the GitLab Software, those
components are licensed under the original license provided by the owner of the
applicable component.
......@@ -164,9 +164,9 @@
version "1.29.0"
resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-svgs/-/gitlab-svgs-1.29.0.tgz#03b65b513f9099bbda6ecf94d673a2952f8c6c70"
"@gitlab-org/gitlab-ui@^1.7.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.7.0.tgz#cf37b7262f90af42664d4d1600917271a8f8fb28"
"@gitlab-org/gitlab-ui@^1.7.1":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@gitlab-org/gitlab-ui/-/gitlab-ui-1.7.1.tgz#e9cce86cb7e34311405e705c1de674276b453f17"
dependencies:
"@gitlab-org/gitlab-svgs" "^1.23.0"
bootstrap-vue "^2.0.0-rc.11"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment