summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml19
-rw-r--r--.gitlab/ci/pages.gitlab-ci.yml3
-rw-r--r--.gitlab/ci/qa.gitlab-ci.yml2
-rw-r--r--.rubocop_todo.yml2
-rw-r--r--app/assets/javascripts/groups/components/app.vue7
-rw-r--r--app/assets/javascripts/groups/service/groups_service.js21
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue8
-rw-r--r--app/assets/javascripts/sidebar/services/sidebar_service.js23
-rw-r--r--app/assets/javascripts/sidebar/sidebar_mediator.js32
-rw-r--r--app/views/projects/settings/ci_cd/_autodevops_form.html.haml18
-rw-r--r--app/views/shared/empty_states/_priority_labels.html.haml4
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml2
-rw-r--r--changelogs/unreleased/change-prioritized-labels-empty-state-message.yml5
-rw-r--r--changelogs/unreleased/je-add-cluster-domain-warning.yml5
-rw-r--r--changelogs/unreleased/remove-vue-resource-from-group-service.yml5
-rw-r--r--changelogs/unreleased/remove-vue-resource-from-sidebar-service.yml5
-rw-r--r--config/gitlab.yml.example1
-rw-r--r--doc/administration/logs.md13
-rw-r--r--doc/ci/environments.md5
-rw-r--r--doc/ci/large_repositories/index.md2
-rw-r--r--doc/ci/variables/README.md2
-rw-r--r--doc/development/database_review.md3
-rw-r--r--doc/user/instance/clusters/index.md2
-rw-r--r--doc/user/project/operations/feature_flags.md6
-rw-r--r--lib/api/api.rb2
-rw-r--r--lib/api/internal.rb294
-rw-r--r--lib/api/internal/base.rb296
-rw-r--r--locale/gitlab.pot8
-rw-r--r--spec/javascripts/groups/components/app_spec.js3
-rw-r--r--spec/javascripts/groups/service/groups_service_spec.js17
-rw-r--r--spec/javascripts/sidebar/mock_data.js10
-rw-r--r--spec/javascripts/sidebar/sidebar_mediator_spec.js19
-rw-r--r--spec/javascripts/sidebar/sidebar_move_issue_spec.js13
-rw-r--r--spec/requests/api/internal/base_spec.rb (renamed from spec/requests/api/internal_spec.rb)2
-rw-r--r--spec/views/projects/settings/ci_cd/_autodevops_form.html.haml_spec.rb8
-rw-r--r--yarn.lock4
36 files changed, 452 insertions, 419 deletions
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index 0d73092cfba..0720ea3e056 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -233,22 +233,3 @@ qa-frontend-node:latest:
extends: .qa-frontend-node
image: node:latest
allow_failure: true
-
-jsdoc:
- extends:
- - .default-tags
- - .default-retry
- - .default-cache
- - .except-docs
- variables:
- SETUP_DB: "false"
- stage: post-test
- dependencies: ["compile-assets", "compile-assets pull-cache"]
- script:
- - date
- - yarn run jsdoc || true # ignore exit code
- artifacts:
- name: jsdoc
- expire_in: 31d
- paths:
- - jsdoc/
diff --git a/.gitlab/ci/pages.gitlab-ci.yml b/.gitlab/ci/pages.gitlab-ci.yml
index 5d13a72e224..2de09753cca 100644
--- a/.gitlab/ci/pages.gitlab-ci.yml
+++ b/.gitlab/ci/pages.gitlab-ci.yml
@@ -9,7 +9,7 @@ pages:
- master@gitlab-org/gitlab-ce
- master@gitlab-org/gitlab-ee
stage: pages
- dependencies: ["coverage", "karma", "gitlab:assets:compile", "jsdoc"]
+ dependencies: ["coverage", "karma", "gitlab:assets:compile"]
script:
- mv public/ .public/
- mkdir public/
@@ -18,7 +18,6 @@ pages:
- mv webpack-report/ public/webpack-report/ || true
- cp .public/assets/application-*.css public/application.css || true
- cp .public/assets/application-*.css.gz public/application.css.gz || true
- - mv jsdoc/ public/jsdoc/ || true
artifacts:
paths:
- public
diff --git a/.gitlab/ci/qa.gitlab-ci.yml b/.gitlab/ci/qa.gitlab-ci.yml
index 8628e1e0a14..9c021b23db6 100644
--- a/.gitlab/ci/qa.gitlab-ci.yml
+++ b/.gitlab/ci/qa.gitlab-ci.yml
@@ -19,6 +19,8 @@ package-and-qa-manual:
except:
refs:
- master
+ - /(^docs[\/-].+|.+-docs$)/
+ - /(^qa[\/-].*|.*-qa$)/
when: manual
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"]
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index be147d72f71..f1f8ff6e862 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -218,7 +218,7 @@ Lint/UriEscapeUnescape:
- 'app/models/project_services/drone_ci_service.rb'
- 'spec/lib/google_api/auth_spec.rb'
- 'spec/requests/api/files_spec.rb'
- - 'spec/requests/api/internal_spec.rb'
+ - 'spec/requests/api/internal/base_spec.rb'
# Offense count: 1
# Configuration parameters: CheckForMethodsWithNoSideEffects.
diff --git a/app/assets/javascripts/groups/components/app.vue b/app/assets/javascripts/groups/components/app.vue
index aa50fd8ff62..8d2dac47ff2 100644
--- a/app/assets/javascripts/groups/components/app.vue
+++ b/app/assets/javascripts/groups/components/app.vue
@@ -95,10 +95,8 @@ export default {
if (updatePagination) {
this.updatePagination(res.headers);
}
-
- return res;
+ return res.data;
})
- .then(res => res.json())
.catch(() => {
this.isLoading = false;
$.scrollTo(0);
@@ -190,11 +188,10 @@ export default {
this.targetGroup.isBeingRemoved = true;
this.service
.leaveGroup(this.targetGroup.leavePath)
- .then(res => res.json())
.then(res => {
$.scrollTo(0);
this.store.removeGroup(this.targetGroup, this.targetParentGroup);
- Flash(res.notice, 'notice');
+ Flash(res.data.notice, 'notice');
})
.catch(err => {
let message = COMMON_STR.FAILURE;
diff --git a/app/assets/javascripts/groups/service/groups_service.js b/app/assets/javascripts/groups/service/groups_service.js
index b79ba291463..790b581a7c0 100644
--- a/app/assets/javascripts/groups/service/groups_service.js
+++ b/app/assets/javascripts/groups/service/groups_service.js
@@ -1,40 +1,39 @@
-import Vue from 'vue';
-import '../../vue_shared/vue_resource_interceptor';
+import axios from '~/lib/utils/axios_utils';
export default class GroupsService {
constructor(endpoint) {
- this.groups = Vue.resource(endpoint);
+ this.endpoint = endpoint;
}
getGroups(parentId, page, filterGroups, sort, archived) {
- const data = {};
+ const params = {};
if (parentId) {
- data.parent_id = parentId;
+ params.parent_id = parentId;
} else {
// Do not send the following param for sub groups
if (page) {
- data.page = page;
+ params.page = page;
}
if (filterGroups) {
- data.filter = filterGroups;
+ params.filter = filterGroups;
}
if (sort) {
- data.sort = sort;
+ params.sort = sort;
}
if (archived) {
- data.archived = archived;
+ params.archived = archived;
}
}
- return this.groups.get(data);
+ return axios.get(this.endpoint, { params });
}
// eslint-disable-next-line class-methods-use-this
leaveGroup(endpoint) {
- return Vue.http.delete(endpoint);
+ return axios.delete(endpoint);
}
}
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
index ce592720531..c6cc04a139f 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
@@ -67,14 +67,18 @@ export default {
saveAssignees() {
this.loading = true;
+ function setLoadingFalse() {
+ this.loading = false;
+ }
+
this.mediator
.saveAssignees(this.field)
+ .then(setLoadingFalse.bind(this))
.then(() => {
- this.loading = false;
refreshUserMergeRequestCounts();
})
.catch(() => {
- this.loading = false;
+ setLoadingFalse();
return new Flash(__('Error occurred when saving assignees'));
});
},
diff --git a/app/assets/javascripts/sidebar/services/sidebar_service.js b/app/assets/javascripts/sidebar/services/sidebar_service.js
index feb08e3acaf..cbe20f761ff 100644
--- a/app/assets/javascripts/sidebar/services/sidebar_service.js
+++ b/app/assets/javascripts/sidebar/services/sidebar_service.js
@@ -1,4 +1,7 @@
-import axios from '~/lib/utils/axios_utils';
+import Vue from 'vue';
+import VueResource from 'vue-resource';
+
+Vue.use(VueResource);
export default class SidebarService {
constructor(endpointMap) {
@@ -15,15 +18,23 @@ export default class SidebarService {
}
get() {
- return axios.get(this.endpoint);
+ return Vue.http.get(this.endpoint);
}
update(key, data) {
- return axios.put(this.endpoint, { [key]: data });
+ return Vue.http.put(
+ this.endpoint,
+ {
+ [key]: data,
+ },
+ {
+ emulateJSON: true,
+ },
+ );
}
getProjectsAutocomplete(searchTerm) {
- return axios.get(this.projectsAutocompleteEndpoint, {
+ return Vue.http.get(this.projectsAutocompleteEndpoint, {
params: {
search: searchTerm,
},
@@ -31,11 +42,11 @@ export default class SidebarService {
}
toggleSubscription() {
- return axios.post(this.toggleSubscriptionEndpoint);
+ return Vue.http.post(this.toggleSubscriptionEndpoint);
}
moveIssue(moveToProjectId) {
- return axios.post(this.moveIssueEndpoint, {
+ return Vue.http.post(this.moveIssueEndpoint, {
move_to_project_id: moveToProjectId,
});
}
diff --git a/app/assets/javascripts/sidebar/sidebar_mediator.js b/app/assets/javascripts/sidebar/sidebar_mediator.js
index 4a7000cbbda..643fe6c00b6 100644
--- a/app/assets/javascripts/sidebar/sidebar_mediator.js
+++ b/app/assets/javascripts/sidebar/sidebar_mediator.js
@@ -32,10 +32,7 @@ export default class SidebarMediator {
// If there are no ids, that means we have to unassign (which is id = 0)
// And it only accepts an array, hence [0]
- const assignees = selected.length === 0 ? [0] : selected;
- const data = { assignee_ids: assignees };
-
- return this.service.update(field, data);
+ return this.service.update(field, selected.length === 0 ? [0] : selected);
}
setMoveToProjectId(projectId) {
@@ -45,7 +42,8 @@ export default class SidebarMediator {
fetch() {
return this.service
.get()
- .then(({ data }) => {
+ .then(response => response.json())
+ .then(data => {
this.processFetchedData(data);
})
.catch(() => new Flash(__('Error occurred when fetching sidebar data')));
@@ -73,17 +71,23 @@ export default class SidebarMediator {
}
fetchAutocompleteProjects(searchTerm) {
- return this.service.getProjectsAutocomplete(searchTerm).then(({ data }) => {
- this.store.setAutocompleteProjects(data);
- return this.store.autocompleteProjects;
- });
+ return this.service
+ .getProjectsAutocomplete(searchTerm)
+ .then(response => response.json())
+ .then(data => {
+ this.store.setAutocompleteProjects(data);
+ return this.store.autocompleteProjects;
+ });
}
moveIssue() {
- return this.service.moveIssue(this.store.moveToProjectId).then(({ data }) => {
- if (window.location.pathname !== data.web_url) {
- visitUrl(data.web_url);
- }
- });
+ return this.service
+ .moveIssue(this.store.moveToProjectId)
+ .then(response => response.json())
+ .then(data => {
+ if (window.location.pathname !== data.web_url) {
+ visitUrl(data.web_url);
+ }
+ });
}
}
diff --git a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
index 04b77fb987a..1d5d90593ae 100644
--- a/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_autodevops_form.html.haml
@@ -1,3 +1,14 @@
+- has_base_domain = @project.all_clusters.any? { |cluster| cluster.base_domain && !cluster.base_domain.empty? }
+
+- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe
+- link_end = '</a>'.html_safe
+
+- kubernetes_cluster_path = help_page_path('user/project/clusters/index')
+- kubernetes_cluster_link_start = link_start % { url: kubernetes_cluster_path }
+
+- base_domain_path = help_page_path('user/project/clusters/index', anchor: 'base-domain')
+- base_domain_link_start = link_start % { url: base_domain_path }
+
.row
.col-lg-12
= form_for @project, url: project_settings_ci_cd_path(@project, anchor: 'autodevops-settings') do |f|
@@ -19,9 +30,10 @@
.card-footer.js-extra-settings{ class: auto_devops_enabled || 'hidden' }
- if @project.all_clusters.empty?
%p.settings-message.text-center
- - kubernetes_cluster_link = help_page_path('user/project/clusters/index')
- - kubernetes_cluster_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: kubernetes_cluster_link }
- = s_('CICD|You must add a %{kubernetes_cluster_start}Kubernetes cluster integration%{kubernetes_cluster_end} to this project with a domain in order for your deployment strategy to work correctly.').html_safe % { kubernetes_cluster_start: kubernetes_cluster_start, kubernetes_cluster_end: '</a>'.html_safe }
+ = s_('CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly.').html_safe % { kubernetes_cluster_link_start: kubernetes_cluster_link_start, link_end: link_end }
+ - elsif !has_base_domain
+ %p.settings-message.text-center
+ = s_('CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work.').html_safe % { base_domain_link_start: base_domain_link_start, kubernetes_cluster_link_start: kubernetes_cluster_link_start, link_end: link_end }
%label.prepend-top-10
%strong= s_('CICD|Deployment strategy')
.form-check
diff --git a/app/views/shared/empty_states/_priority_labels.html.haml b/app/views/shared/empty_states/_priority_labels.html.haml
index bba3475d244..a93f6e4c795 100644
--- a/app/views/shared/empty_states/_priority_labels.html.haml
+++ b/app/views/shared/empty_states/_priority_labels.html.haml
@@ -1,4 +1,6 @@
.text-center
.svg-content.qa-label-svg
= image_tag 'illustrations/priority_labels.svg'
- %p Star labels to start sorting by priority
+ - if can?(current_user, :admin_label, @project)
+ %p
+ = _("Star labels to start sorting by priority")
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index dfb0e7ed297..1dc538826dc 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -1,7 +1,7 @@
- issuable_type = issuable_sidebar[:type]
- signed_in = !!issuable_sidebar.dig(:current_user, :id)
-#js-vue-sidebar-assignees{ data: { field: "#{issuable_type}", signed_in: signed_in } }
+#js-vue-sidebar-assignees{ data: { field: "#{issuable_type}[assignee_ids]", signed_in: signed_in } }
.title.hide-collapsed
= _('Assignee')
= icon('spinner spin')
diff --git a/changelogs/unreleased/change-prioritized-labels-empty-state-message.yml b/changelogs/unreleased/change-prioritized-labels-empty-state-message.yml
new file mode 100644
index 00000000000..d5df889d15c
--- /dev/null
+++ b/changelogs/unreleased/change-prioritized-labels-empty-state-message.yml
@@ -0,0 +1,5 @@
+---
+title: Change prioritized labels empty state message
+merge_request: 32338
+author: Lee Tickett
+type: other
diff --git a/changelogs/unreleased/je-add-cluster-domain-warning.yml b/changelogs/unreleased/je-add-cluster-domain-warning.yml
new file mode 100644
index 00000000000..e7d244f730f
--- /dev/null
+++ b/changelogs/unreleased/je-add-cluster-domain-warning.yml
@@ -0,0 +1,5 @@
+---
+title: Add cluster domain warning
+merge_request: 32260
+author:
+type: changed
diff --git a/changelogs/unreleased/remove-vue-resource-from-group-service.yml b/changelogs/unreleased/remove-vue-resource-from-group-service.yml
new file mode 100644
index 00000000000..771d301cabf
--- /dev/null
+++ b/changelogs/unreleased/remove-vue-resource-from-group-service.yml
@@ -0,0 +1,5 @@
+---
+title: Remove vue resource from group service
+merge_request:
+author: Lee Tickett
+type: other
diff --git a/changelogs/unreleased/remove-vue-resource-from-sidebar-service.yml b/changelogs/unreleased/remove-vue-resource-from-sidebar-service.yml
deleted file mode 100644
index f86e0a4259f..00000000000
--- a/changelogs/unreleased/remove-vue-resource-from-sidebar-service.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove vue resource from sidebar service
-merge_request: 32400
-author: Lee Tickett
-type: other
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 20b1020e025..6dcaefc05d5 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -431,6 +431,7 @@ production: &base
# key: config/registry.key
# path: shared/registry
# issuer: gitlab-issuer
+ # notification_secret: '' # only set it when you use Geo replication feature without built-in Registry
# Add notification settings if you plan to use Geo Replication for the registry
# notifications:
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index 9b1efb610f8..4c43a434817 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -341,9 +341,10 @@ installations from source.
## `database_load_balancing.log`
-Introduced in GitLab 12.3 for observability of [Database Load
-Balancing](https://docs.gitlab.com/ee/administration/database_load_balancing.html)
-when enabled. This file lives in
-`/var/log/gitlab/gitlab-rails/database_load_balancing.log` for Omnibus GitLab
-packages or in `/home/git/gitlab/log/database_load_balancing.log` for
-installations from source.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/15442) in GitLab 12.3.
+
+This log is used for observability of [Database Load Balancing](database_load_balancing.md).
+It is stored at:
+
+- `/var/log/gitlab/gitlab-rails/database_load_balancing.log` for Omnibus GitLab packages.
+- `/home/git/gitlab/log/database_load_balancing.log` for installations from source.
diff --git a/doc/ci/environments.md b/doc/ci/environments.md
index f6c47a99712..c2d444cb1d6 100644
--- a/doc/ci/environments.md
+++ b/doc/ci/environments.md
@@ -675,9 +675,10 @@ fetch line:
fetch = +refs/environments/*:refs/remotes/origin/environments/*
```
-### Scoping environments with specs **(PREMIUM)**
+### Scoping environments with specs
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2112) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.4.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2112) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.4.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/30779) to Core in Gitlab 12.2.
You can limit the environment scope of a variable by
defining which environments it can be available for.
diff --git a/doc/ci/large_repositories/index.md b/doc/ci/large_repositories/index.md
index 29d649ad717..b1359537fca 100644
--- a/doc/ci/large_repositories/index.md
+++ b/doc/ci/large_repositories/index.md
@@ -84,7 +84,7 @@ Fork workflow from GitLab Runner's perspective is stored as a separate repositor
with separate worktree. That means that GitLab Runner cannot optimize the usage
of worktrees and you might have to instruct GitLab Runner to use that.
-In such cases, ideally you want to make the GitLab Runner executor be used only used only
+In such cases, ideally you want to make the GitLab Runner executor be used only
for the given project and not shared across different projects to make this
process more efficient.
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index 5a15b907da0..438b7c03b51 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -401,7 +401,7 @@ Once you set them, they will be available for all subsequent pipelines.
You can limit the environment scope of a variable by
[defining which environments][envs] it can be available for.
-To learn more about about scoping environments, see [Scoping environments with specs](../environments.md#scoping-environments-with-specs-premium).
+To learn more about about scoping environments, see [Scoping environments with specs](../environments.md#scoping-environments-with-specs).
### Deployment environment variables
diff --git a/doc/development/database_review.md b/doc/development/database_review.md
index 367a481ee11..157c64b514c 100644
--- a/doc/development/database_review.md
+++ b/doc/development/database_review.md
@@ -38,6 +38,7 @@ A Merge Request author's role is to:
- If database review is needed, add the ~database label.
- Use the [database changes](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab/merge_request_templates/Database%20changes.md)
merge request template, or include the appropriate items in the MR description.
+- [Prepare the merge request for a database review](#how-to-prepare-the-merge-request-for-a-database-review).
A database **reviewer**'s role is to:
@@ -68,7 +69,7 @@ make sure you have applied the ~database label and rerun the
`danger-review` CI job, or pick someone from the
[`@gl-database` team](https://gitlab.com/groups/gl-database/-/group_members).
-### How to prepare for speedy database reviews
+### How to prepare the merge request for a database review
In order to make reviewing easier and therefore faster, please consider preparing a comment
and details for a database reviewer:
diff --git a/doc/user/instance/clusters/index.md b/doc/user/instance/clusters/index.md
index f557dcf4b3c..cb1bfc69826 100644
--- a/doc/user/instance/clusters/index.md
+++ b/doc/user/instance/clusters/index.md
@@ -19,4 +19,4 @@ GitLab will try match to clusters in the following order:
- Instance level
To be selected, the cluster must be enabled and
-match the [environment selector](../../../ci/environments.md#scoping-environments-with-specs-premium).
+match the [environment selector](../../../ci/environments.md#scoping-environments-with-specs).
diff --git a/doc/user/project/operations/feature_flags.md b/doc/user/project/operations/feature_flags.md
index 28248ad3696..39ca1bd0c77 100644
--- a/doc/user/project/operations/feature_flags.md
+++ b/doc/user/project/operations/feature_flags.md
@@ -63,15 +63,15 @@ For example, you may not want to enable a feature flag on production until your
first confirmed that the feature is working correctly on testing environments.
To handle these situations, you can enable a feature flag on a particular environment
-with [Environment specs](../../../ci/environments.md#scoping-environments-with-specs-premium).
+with [Environment specs](../../../ci/environments.md#scoping-environments-with-specs).
You can define multiple specs per flag so that you can control your feature flag more granularly.
To define specs for each environment:
1. Navigate to your project's **Operations > Feature Flags**.
1. Click on the **New Feature Flag** button or edit an existing flag.
-1. Set the status of the default [spec](../../../ci/environments.md#scoping-environments-with-specs-premium) (`*`). Choose a rollout strategy. This status and rollout strategy combination will be used for _all_ environments.
-1. If you want to enable/disable the feature on a specific environment, create a new [spec](../../../ci/environments.md#scoping-environments-with-specs-premium) and type the environment name.
+1. Set the status of the default [spec](../../../ci/environments.md#scoping-environments-with-specs) (`*`). Choose a rollout strategy. This status and rollout strategy combination will be used for _all_ environments.
+1. If you want to enable/disable the feature on a specific environment, create a new [spec](../../../ci/environments.md#scoping-environments-with-specs) and type the environment name.
1. Set the status and rollout strategy of the additional spec. This status and rollout strategy combination takes precedence over the default spec since we always use the most specific match available.
1. Click **Create feature flag** or **Update feature flag**.
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 219ed45eff6..aa6a67d817a 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -118,7 +118,7 @@ module API
mount ::API::GroupContainerRepositories
mount ::API::GroupVariables
mount ::API::ImportGithub
- mount ::API::Internal
+ mount ::API::Internal::Base
mount ::API::Issues
mount ::API::JobArtifacts
mount ::API::Jobs
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
deleted file mode 100644
index 088ea5bd79a..00000000000
--- a/lib/api/internal.rb
+++ /dev/null
@@ -1,294 +0,0 @@
-# frozen_string_literal: true
-
-module API
- # Internal access API
- class Internal < Grape::API
- before { authenticate_by_gitlab_shell_token! }
-
- helpers ::API::Helpers::InternalHelpers
- helpers ::Gitlab::Identifier
-
- UNKNOWN_CHECK_RESULT_ERROR = 'Unknown check result'.freeze
-
- helpers do
- def response_with_status(code: 200, success: true, message: nil, **extra_options)
- status code
- { status: success, message: message }.merge(extra_options).compact
- end
-
- def lfs_authentication_url(project)
- # This is a separate method so that EE can alter its behaviour more
- # easily.
- project.http_url_to_repo
- end
- end
-
- namespace 'internal' do
- # Check if git command is allowed for project
- #
- # Params:
- # key_id - ssh key id for Git over SSH
- # user_id - user id for Git over HTTP or over SSH in keyless SSH CERT mode
- # username - user name for Git over SSH in keyless SSH cert mode
- # protocol - Git access protocol being used, e.g. HTTP or SSH
- # project - project full_path (not path on disk)
- # action - git action (git-upload-pack or git-receive-pack)
- # changes - changes as "oldrev newrev ref", see Gitlab::ChangesList
- # rubocop: disable CodeReuse/ActiveRecord
- post "/allowed" do
- # Stores some Git-specific env thread-safely
- env = parse_env
- Gitlab::Git::HookEnv.set(gl_repository, env) if project
-
- actor =
- if params[:key_id]
- Key.find_by(id: params[:key_id])
- elsif params[:user_id]
- User.find_by(id: params[:user_id])
- elsif params[:username]
- UserFinder.new(params[:username]).find_by_username
- end
-
- protocol = params[:protocol]
-
- actor.update_last_used_at if actor.is_a?(Key)
- user =
- if actor.is_a?(Key)
- actor.user
- else
- actor
- end
-
- access_checker_klass = repo_type.access_checker_class
- access_checker = access_checker_klass.new(actor, project,
- protocol, authentication_abilities: ssh_authentication_abilities,
- namespace_path: namespace_path, project_path: project_path,
- redirected_path: redirected_path)
-
- check_result = begin
- result = access_checker.check(params[:action], params[:changes])
- @project ||= access_checker.project
- result
- rescue Gitlab::GitAccess::UnauthorizedError => e
- break response_with_status(code: 401, success: false, message: e.message)
- rescue Gitlab::GitAccess::TimeoutError => e
- break response_with_status(code: 503, success: false, message: e.message)
- rescue Gitlab::GitAccess::NotFoundError => e
- break response_with_status(code: 404, success: false, message: e.message)
- end
-
- log_user_activity(actor)
-
- case check_result
- when ::Gitlab::GitAccessResult::Success
- payload = {
- gl_repository: gl_repository,
- gl_project_path: gl_project_path,
- gl_id: Gitlab::GlId.gl_id(user),
- gl_username: user&.username,
- git_config_options: [],
- gitaly: gitaly_payload(params[:action]),
- gl_console_messages: check_result.console_messages
- }
-
- # Custom option for git-receive-pack command
- receive_max_input_size = Gitlab::CurrentSettings.receive_max_input_size.to_i
- if receive_max_input_size > 0
- payload[:git_config_options] << "receive.maxInputSize=#{receive_max_input_size.megabytes}"
- end
-
- response_with_status(**payload)
- when ::Gitlab::GitAccessResult::CustomAction
- response_with_status(code: 300, message: check_result.message, payload: check_result.payload)
- else
- response_with_status(code: 500, success: false, message: UNKNOWN_CHECK_RESULT_ERROR)
- end
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- # rubocop: disable CodeReuse/ActiveRecord
- post "/lfs_authenticate" do
- status 200
-
- if params[:key_id]
- actor = Key.find(params[:key_id])
- actor.update_last_used_at
- elsif params[:user_id]
- actor = User.find_by(id: params[:user_id])
- raise ActiveRecord::RecordNotFound.new("No such user id!") unless actor
- else
- raise ActiveRecord::RecordNotFound.new("No key_id or user_id passed!")
- end
-
- Gitlab::LfsToken
- .new(actor)
- .authentication_payload(lfs_authentication_url(project))
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- get "/merge_request_urls" do
- merge_request_urls
- end
-
- #
- # Get a ssh key using the fingerprint
- #
- # rubocop: disable CodeReuse/ActiveRecord
- get "/authorized_keys" do
- fingerprint = params.fetch(:fingerprint) do
- Gitlab::InsecureKeyFingerprint.new(params.fetch(:key)).fingerprint
- end
- key = Key.find_by(fingerprint: fingerprint)
- not_found!("Key") if key.nil?
- present key, with: Entities::SSHKey
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- #
- # Discover user by ssh key, user id or username
- #
- # rubocop: disable CodeReuse/ActiveRecord
- get "/discover" do
- if params[:key_id]
- key = Key.find(params[:key_id])
- user = key.user
- elsif params[:user_id]
- user = User.find_by(id: params[:user_id])
- elsif params[:username]
- user = UserFinder.new(params[:username]).find_by_username
- end
-
- present user, with: Entities::UserSafe
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- get "/check" do
- {
- api_version: API.version,
- gitlab_version: Gitlab::VERSION,
- gitlab_rev: Gitlab.revision,
- redis: redis_ping
- }
- end
-
- get "/broadcast_messages" do
- if messages = BroadcastMessage.current
- present messages, with: Entities::BroadcastMessage
- else
- []
- end
- end
-
- get "/broadcast_message" do
- if message = BroadcastMessage.current&.last
- present message, with: Entities::BroadcastMessage
- else
- {}
- end
- end
-
- # rubocop: disable CodeReuse/ActiveRecord
- post '/two_factor_recovery_codes' do
- status 200
-
- if params[:key_id]
- key = Key.find_by(id: params[:key_id])
-
- if key
- key.update_last_used_at
- else
- break { 'success' => false, 'message' => 'Could not find the given key' }
- end
-
- if key.is_a?(DeployKey)
- break { success: false, message: 'Deploy keys cannot be used to retrieve recovery codes' }
- end
-
- user = key.user
-
- unless user
- break { success: false, message: 'Could not find a user for the given key' }
- end
- elsif params[:user_id]
- user = User.find_by(id: params[:user_id])
-
- unless user
- break { success: false, message: 'Could not find the given user' }
- end
- end
-
- unless user.two_factor_enabled?
- break { success: false, message: 'Two-factor authentication is not enabled for this user' }
- end
-
- codes = nil
-
- ::Users::UpdateService.new(current_user, user: user).execute! do |user|
- codes = user.generate_otp_backup_codes!
- end
-
- { success: true, recovery_codes: codes }
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- post '/pre_receive' do
- status 200
-
- reference_counter_increased = Gitlab::ReferenceCounter.new(params[:gl_repository]).increase
-
- { reference_counter_increased: reference_counter_increased }
- end
-
- post "/notify_post_receive" do
- status 200
-
- # TODO: Re-enable when Gitaly is processing the post-receive notification
- # return unless Gitlab::GitalyClient.enabled?
- #
- # begin
- # repository = wiki? ? project.wiki.repository : project.repository
- # Gitlab::GitalyClient::NotificationService.new(repository.raw_repository).post_receive
- # rescue GRPC::Unavailable => e
- # render_api_error!(e, 500)
- # end
- end
-
- post '/post_receive' do
- status 200
-
- response = Gitlab::InternalPostReceive::Response.new
- user = identify(params[:identifier])
- project = Gitlab::GlRepository.parse(params[:gl_repository]).first
- push_options = Gitlab::PushOptions.new(params[:push_options])
-
- response.reference_counter_decreased = Gitlab::ReferenceCounter.new(params[:gl_repository]).decrease
-
- PostReceive.perform_async(params[:gl_repository], params[:identifier],
- params[:changes], push_options.as_json)
-
- mr_options = push_options.get(:merge_request)
- if mr_options.present?
- message = process_mr_push_options(mr_options, project, user, params[:changes])
- response.add_alert_message(message)
- end
-
- broadcast_message = BroadcastMessage.current&.last&.message
- response.add_alert_message(broadcast_message)
-
- response.add_merge_request_urls(merge_request_urls)
-
- # A user is not guaranteed to be returned; an orphaned write deploy
- # key could be used
- if user
- redirect_message = Gitlab::Checks::ProjectMoved.fetch_message(user.id, project.id)
- project_created_message = Gitlab::Checks::ProjectCreated.fetch_message(user.id, project.id)
-
- response.add_basic_message(redirect_message)
- response.add_basic_message(project_created_message)
- end
-
- present response, with: Entities::InternalPostReceive::Response
- end
- end
- end
-end
diff --git a/lib/api/internal/base.rb b/lib/api/internal/base.rb
new file mode 100644
index 00000000000..622032b8355
--- /dev/null
+++ b/lib/api/internal/base.rb
@@ -0,0 +1,296 @@
+# frozen_string_literal: true
+
+module API
+ # Internal access API
+ module Internal
+ class Base < Grape::API
+ before { authenticate_by_gitlab_shell_token! }
+
+ helpers ::API::Helpers::InternalHelpers
+ helpers ::Gitlab::Identifier
+
+ UNKNOWN_CHECK_RESULT_ERROR = 'Unknown check result'.freeze
+
+ helpers do
+ def response_with_status(code: 200, success: true, message: nil, **extra_options)
+ status code
+ { status: success, message: message }.merge(extra_options).compact
+ end
+
+ def lfs_authentication_url(project)
+ # This is a separate method so that EE can alter its behaviour more
+ # easily.
+ project.http_url_to_repo
+ end
+ end
+
+ namespace 'internal' do
+ # Check if git command is allowed for project
+ #
+ # Params:
+ # key_id - ssh key id for Git over SSH
+ # user_id - user id for Git over HTTP or over SSH in keyless SSH CERT mode
+ # username - user name for Git over SSH in keyless SSH cert mode
+ # protocol - Git access protocol being used, e.g. HTTP or SSH
+ # project - project full_path (not path on disk)
+ # action - git action (git-upload-pack or git-receive-pack)
+ # changes - changes as "oldrev newrev ref", see Gitlab::ChangesList
+ # rubocop: disable CodeReuse/ActiveRecord
+ post "/allowed" do
+ # Stores some Git-specific env thread-safely
+ env = parse_env
+ Gitlab::Git::HookEnv.set(gl_repository, env) if project
+
+ actor =
+ if params[:key_id]
+ Key.find_by(id: params[:key_id])
+ elsif params[:user_id]
+ User.find_by(id: params[:user_id])
+ elsif params[:username]
+ UserFinder.new(params[:username]).find_by_username
+ end
+
+ protocol = params[:protocol]
+
+ actor.update_last_used_at if actor.is_a?(Key)
+ user =
+ if actor.is_a?(Key)
+ actor.user
+ else
+ actor
+ end
+
+ access_checker_klass = repo_type.access_checker_class
+ access_checker = access_checker_klass.new(actor, project,
+ protocol, authentication_abilities: ssh_authentication_abilities,
+ namespace_path: namespace_path, project_path: project_path,
+ redirected_path: redirected_path)
+
+ check_result = begin
+ result = access_checker.check(params[:action], params[:changes])
+ @project ||= access_checker.project
+ result
+ rescue Gitlab::GitAccess::UnauthorizedError => e
+ break response_with_status(code: 401, success: false, message: e.message)
+ rescue Gitlab::GitAccess::TimeoutError => e
+ break response_with_status(code: 503, success: false, message: e.message)
+ rescue Gitlab::GitAccess::NotFoundError => e
+ break response_with_status(code: 404, success: false, message: e.message)
+ end
+
+ log_user_activity(actor)
+
+ case check_result
+ when ::Gitlab::GitAccessResult::Success
+ payload = {
+ gl_repository: gl_repository,
+ gl_project_path: gl_project_path,
+ gl_id: Gitlab::GlId.gl_id(user),
+ gl_username: user&.username,
+ git_config_options: [],
+ gitaly: gitaly_payload(params[:action]),
+ gl_console_messages: check_result.console_messages
+ }
+
+ # Custom option for git-receive-pack command
+ receive_max_input_size = Gitlab::CurrentSettings.receive_max_input_size.to_i
+ if receive_max_input_size > 0
+ payload[:git_config_options] << "receive.maxInputSize=#{receive_max_input_size.megabytes}"
+ end
+
+ response_with_status(**payload)
+ when ::Gitlab::GitAccessResult::CustomAction
+ response_with_status(code: 300, message: check_result.message, payload: check_result.payload)
+ else
+ response_with_status(code: 500, success: false, message: UNKNOWN_CHECK_RESULT_ERROR)
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ post "/lfs_authenticate" do
+ status 200
+
+ if params[:key_id]
+ actor = Key.find(params[:key_id])
+ actor.update_last_used_at
+ elsif params[:user_id]
+ actor = User.find_by(id: params[:user_id])
+ raise ActiveRecord::RecordNotFound.new("No such user id!") unless actor
+ else
+ raise ActiveRecord::RecordNotFound.new("No key_id or user_id passed!")
+ end
+
+ Gitlab::LfsToken
+ .new(actor)
+ .authentication_payload(lfs_authentication_url(project))
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ get "/merge_request_urls" do
+ merge_request_urls
+ end
+
+ #
+ # Get a ssh key using the fingerprint
+ #
+ # rubocop: disable CodeReuse/ActiveRecord
+ get "/authorized_keys" do
+ fingerprint = params.fetch(:fingerprint) do
+ Gitlab::InsecureKeyFingerprint.new(params.fetch(:key)).fingerprint
+ end
+ key = Key.find_by(fingerprint: fingerprint)
+ not_found!("Key") if key.nil?
+ present key, with: Entities::SSHKey
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ #
+ # Discover user by ssh key, user id or username
+ #
+ # rubocop: disable CodeReuse/ActiveRecord
+ get "/discover" do
+ if params[:key_id]
+ key = Key.find(params[:key_id])
+ user = key.user
+ elsif params[:user_id]
+ user = User.find_by(id: params[:user_id])
+ elsif params[:username]
+ user = UserFinder.new(params[:username]).find_by_username
+ end
+
+ present user, with: Entities::UserSafe
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ get "/check" do
+ {
+ api_version: API.version,
+ gitlab_version: Gitlab::VERSION,
+ gitlab_rev: Gitlab.revision,
+ redis: redis_ping
+ }
+ end
+
+ get "/broadcast_messages" do
+ if messages = BroadcastMessage.current
+ present messages, with: Entities::BroadcastMessage
+ else
+ []
+ end
+ end
+
+ get "/broadcast_message" do
+ if message = BroadcastMessage.current&.last
+ present message, with: Entities::BroadcastMessage
+ else
+ {}
+ end
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ post '/two_factor_recovery_codes' do
+ status 200
+
+ if params[:key_id]
+ key = Key.find_by(id: params[:key_id])
+
+ if key
+ key.update_last_used_at
+ else
+ break { 'success' => false, 'message' => 'Could not find the given key' }
+ end
+
+ if key.is_a?(DeployKey)
+ break { success: false, message: 'Deploy keys cannot be used to retrieve recovery codes' }
+ end
+
+ user = key.user
+
+ unless user
+ break { success: false, message: 'Could not find a user for the given key' }
+ end
+ elsif params[:user_id]
+ user = User.find_by(id: params[:user_id])
+
+ unless user
+ break { success: false, message: 'Could not find the given user' }
+ end
+ end
+
+ unless user.two_factor_enabled?
+ break { success: false, message: 'Two-factor authentication is not enabled for this user' }
+ end
+
+ codes = nil
+
+ ::Users::UpdateService.new(current_user, user: user).execute! do |user|
+ codes = user.generate_otp_backup_codes!
+ end
+
+ { success: true, recovery_codes: codes }
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ post '/pre_receive' do
+ status 200
+
+ reference_counter_increased = Gitlab::ReferenceCounter.new(params[:gl_repository]).increase
+
+ { reference_counter_increased: reference_counter_increased }
+ end
+
+ post "/notify_post_receive" do
+ status 200
+
+ # TODO: Re-enable when Gitaly is processing the post-receive notification
+ # return unless Gitlab::GitalyClient.enabled?
+ #
+ # begin
+ # repository = wiki? ? project.wiki.repository : project.repository
+ # Gitlab::GitalyClient::NotificationService.new(repository.raw_repository).post_receive
+ # rescue GRPC::Unavailable => e
+ # render_api_error!(e, 500)
+ # end
+ end
+
+ post '/post_receive' do
+ status 200
+
+ response = Gitlab::InternalPostReceive::Response.new
+ user = identify(params[:identifier])
+ project = Gitlab::GlRepository.parse(params[:gl_repository]).first
+ push_options = Gitlab::PushOptions.new(params[:push_options])
+
+ response.reference_counter_decreased = Gitlab::ReferenceCounter.new(params[:gl_repository]).decrease
+
+ PostReceive.perform_async(params[:gl_repository], params[:identifier],
+ params[:changes], push_options.as_json)
+
+ mr_options = push_options.get(:merge_request)
+ if mr_options.present?
+ message = process_mr_push_options(mr_options, project, user, params[:changes])
+ response.add_alert_message(message)
+ end
+
+ broadcast_message = BroadcastMessage.current&.last&.message
+ response.add_alert_message(broadcast_message)
+
+ response.add_merge_request_urls(merge_request_urls)
+
+ # A user is not guaranteed to be returned; an orphaned write deploy
+ # key could be used
+ if user
+ redirect_message = Gitlab::Checks::ProjectMoved.fetch_message(user.id, project.id)
+ project_created_message = Gitlab::Checks::ProjectCreated.fetch_message(user.id, project.id)
+
+ response.add_basic_message(redirect_message)
+ response.add_basic_message(project_created_message)
+ end
+
+ present response, with: Entities::InternalPostReceive::Response
+ end
+ end
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index a5619079988..629daccf006 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1960,7 +1960,10 @@ msgstr ""
msgid "CICD|The Auto DevOps pipeline will run if no alternative CI configuration file is found."
msgstr ""
-msgid "CICD|You must add a %{kubernetes_cluster_start}Kubernetes cluster integration%{kubernetes_cluster_end} to this project with a domain in order for your deployment strategy to work correctly."
+msgid "CICD|You must add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} in order for your deployment strategy to work."
+msgstr ""
+
+msgid "CICD|You must add a %{kubernetes_cluster_link_start}Kubernetes cluster integration%{link_end} to this project with a domain in order for your deployment strategy to work correctly."
msgstr ""
msgid "CICD|group enabled"
@@ -10879,6 +10882,9 @@ msgstr ""
msgid "Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging."
msgstr ""
+msgid "Star labels to start sorting by priority"
+msgstr ""
+
msgid "Star toggle failed. Try again later."
msgstr ""
diff --git a/spec/javascripts/groups/components/app_spec.js b/spec/javascripts/groups/components/app_spec.js
index 31873311e16..23b2564d3f9 100644
--- a/spec/javascripts/groups/components/app_spec.js
+++ b/spec/javascripts/groups/components/app_spec.js
@@ -1,3 +1,4 @@
+import '~/flash';
import $ from 'jquery';
import Vue from 'vue';
@@ -333,7 +334,7 @@ describe('AppComponent', () => {
it('hides modal confirmation leave group and remove group item from tree', done => {
const notice = `You left the "${childGroupItem.fullName}" group.`;
- spyOn(vm.service, 'leaveGroup').and.returnValue(returnServicePromise({ notice }));
+ spyOn(vm.service, 'leaveGroup').and.returnValue(Promise.resolve({ data: { notice } }));
spyOn(vm.store, 'removeGroup').and.callThrough();
spyOn(window, 'Flash');
spyOn($, 'scrollTo');
diff --git a/spec/javascripts/groups/service/groups_service_spec.js b/spec/javascripts/groups/service/groups_service_spec.js
index 339e5131615..45db962a1ef 100644
--- a/spec/javascripts/groups/service/groups_service_spec.js
+++ b/spec/javascripts/groups/service/groups_service_spec.js
@@ -1,11 +1,8 @@
-import Vue from 'vue';
-import VueResource from 'vue-resource';
+import axios from '~/lib/utils/axios_utils';
import GroupsService from '~/groups/service/groups_service';
import { mockEndpoint, mockParentGroupItem } from '../mock_data';
-Vue.use(VueResource);
-
describe('GroupsService', () => {
let service;
@@ -15,8 +12,8 @@ describe('GroupsService', () => {
describe('getGroups', () => {
it('should return promise for `GET` request on provided endpoint', () => {
- spyOn(service.groups, 'get').and.stub();
- const queryParams = {
+ spyOn(axios, 'get').and.stub();
+ const params = {
page: 2,
filter: 'git',
sort: 'created_asc',
@@ -25,21 +22,21 @@ describe('GroupsService', () => {
service.getGroups(55, 2, 'git', 'created_asc', true);
- expect(service.groups.get).toHaveBeenCalledWith({ parent_id: 55 });
+ expect(axios.get).toHaveBeenCalledWith(mockEndpoint, { params: { parent_id: 55 } });
service.getGroups(null, 2, 'git', 'created_asc', true);
- expect(service.groups.get).toHaveBeenCalledWith(queryParams);
+ expect(axios.get).toHaveBeenCalledWith(mockEndpoint, { params });
});
});
describe('leaveGroup', () => {
it('should return promise for `DELETE` request on provided endpoint', () => {
- spyOn(Vue.http, 'delete').and.stub();
+ spyOn(axios, 'delete').and.stub();
service.leaveGroup(mockParentGroupItem.leavePath);
- expect(Vue.http.delete).toHaveBeenCalledWith(mockParentGroupItem.leavePath);
+ expect(axios.delete).toHaveBeenCalledWith(mockParentGroupItem.leavePath);
});
});
});
diff --git a/spec/javascripts/sidebar/mock_data.js b/spec/javascripts/sidebar/mock_data.js
index 3ee97b978fd..7f20b0da991 100644
--- a/spec/javascripts/sidebar/mock_data.js
+++ b/spec/javascripts/sidebar/mock_data.js
@@ -210,4 +210,14 @@ const mockData = {
},
};
+mockData.sidebarMockInterceptor = function(request, next) {
+ const body = this.responseMap[request.method.toUpperCase()][request.url];
+
+ next(
+ request.respondWith(JSON.stringify(body), {
+ status: 200,
+ }),
+ );
+}.bind(mockData);
+
export default mockData;
diff --git a/spec/javascripts/sidebar/sidebar_mediator_spec.js b/spec/javascripts/sidebar/sidebar_mediator_spec.js
index 2e5845cd847..6c69c08e733 100644
--- a/spec/javascripts/sidebar/sidebar_mediator_spec.js
+++ b/spec/javascripts/sidebar/sidebar_mediator_spec.js
@@ -1,16 +1,13 @@
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
+import _ from 'underscore';
+import Vue from 'vue';
import SidebarMediator from '~/sidebar/sidebar_mediator';
import SidebarStore from '~/sidebar/stores/sidebar_store';
import SidebarService from '~/sidebar/services/sidebar_service';
import Mock from './mock_data';
describe('Sidebar mediator', function() {
- let mock;
-
beforeEach(() => {
- mock = new MockAdapter(axios);
-
+ Vue.http.interceptors.push(Mock.sidebarMockInterceptor);
this.mediator = new SidebarMediator(Mock.mediator);
});
@@ -18,7 +15,7 @@ describe('Sidebar mediator', function() {
SidebarService.singleton = null;
SidebarStore.singleton = null;
SidebarMediator.singleton = null;
- mock.restore();
+ Vue.http.interceptors = _.without(Vue.http.interceptors, Mock.sidebarMockInterceptor);
});
it('assigns yourself ', () => {
@@ -29,7 +26,6 @@ describe('Sidebar mediator', function() {
});
it('saves assignees', done => {
- mock.onPut('/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras').reply(200, {});
this.mediator
.saveAssignees('issue[assignee_ids]')
.then(resp => {
@@ -42,9 +38,6 @@ describe('Sidebar mediator', function() {
it('fetches the data', done => {
const mockData =
Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras'];
- mock
- .onGet('/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras')
- .reply(200, mockData);
spyOn(this.mediator, 'processFetchedData').and.callThrough();
this.mediator
@@ -81,7 +74,6 @@ describe('Sidebar mediator', function() {
it('fetches autocomplete projects', done => {
const searchTerm = 'foo';
- mock.onGet('/autocomplete/projects?project_id=15').reply(200, {});
spyOn(this.mediator.service, 'getProjectsAutocomplete').and.callThrough();
spyOn(this.mediator.store, 'setAutocompleteProjects').and.callThrough();
@@ -96,9 +88,7 @@ describe('Sidebar mediator', function() {
});
it('moves issue', done => {
- const mockData = Mock.responseMap.POST['/gitlab-org/gitlab-shell/issues/5/move'];
const moveToProjectId = 7;
- mock.onPost('/gitlab-org/gitlab-shell/issues/5/move').reply(200, mockData);
this.mediator.store.setMoveToProjectId(moveToProjectId);
spyOn(this.mediator.service, 'moveIssue').and.callThrough();
const visitUrl = spyOnDependency(SidebarMediator, 'visitUrl');
@@ -115,7 +105,6 @@ describe('Sidebar mediator', function() {
it('toggle subscription', done => {
this.mediator.store.setSubscribedState(false);
- mock.onPost('/gitlab-org/gitlab-shell/issues/5/toggle_subscription').reply(200, {});
spyOn(this.mediator.service, 'toggleSubscription').and.callThrough();
this.mediator
diff --git a/spec/javascripts/sidebar/sidebar_move_issue_spec.js b/spec/javascripts/sidebar/sidebar_move_issue_spec.js
index ec712450f2e..230e0a933a9 100644
--- a/spec/javascripts/sidebar/sidebar_move_issue_spec.js
+++ b/spec/javascripts/sidebar/sidebar_move_issue_spec.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
+import _ from 'underscore';
+import Vue from 'vue';
import SidebarMediator from '~/sidebar/sidebar_mediator';
import SidebarStore from '~/sidebar/stores/sidebar_store';
import SidebarService from '~/sidebar/services/sidebar_service';
@@ -8,12 +8,8 @@ import SidebarMoveIssue from '~/sidebar/lib/sidebar_move_issue';
import Mock from './mock_data';
describe('SidebarMoveIssue', function() {
- let mock;
-
beforeEach(() => {
- mock = new MockAdapter(axios);
- const mockData = Mock.responseMap.GET['/autocomplete/projects?project_id=15'];
- mock.onGet('/autocomplete/projects?project_id=15').reply(200, mockData);
+ Vue.http.interceptors.push(Mock.sidebarMockInterceptor);
this.mediator = new SidebarMediator(Mock.mediator);
this.$content = $(`
<div class="dropdown">
@@ -41,7 +37,8 @@ describe('SidebarMoveIssue', function() {
SidebarMediator.singleton = null;
this.sidebarMoveIssue.destroy();
- mock.restore();
+
+ Vue.http.interceptors = _.without(Vue.http.interceptors, Mock.sidebarMockInterceptor);
});
describe('init', () => {
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal/base_spec.rb
index c94f6d22e74..a56527073c7 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal/base_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe API::Internal do
+describe API::Internal::Base do
set(:user) { create(:user) }
let(:key) { create(:key, user: user) }
set(:project) { create(:project, :repository, :wiki_repo) }
diff --git a/spec/views/projects/settings/ci_cd/_autodevops_form.html.haml_spec.rb b/spec/views/projects/settings/ci_cd/_autodevops_form.html.haml_spec.rb
index ff2d491539b..697e44be065 100644
--- a/spec/views/projects/settings/ci_cd/_autodevops_form.html.haml_spec.rb
+++ b/spec/views/projects/settings/ci_cd/_autodevops_form.html.haml_spec.rb
@@ -17,10 +17,16 @@ describe 'projects/settings/ci_cd/_autodevops_form' do
context 'when the project has an available kubernetes cluster' do
let!(:cluster) { create(:cluster, cluster_type: :project_type, projects: [project]) }
- it 'does not show a warning message' do
+ it 'does not show a warning message about Kubernetes cluster' do
render
expect(rendered).not_to have_text('You must add a Kubernetes cluster')
end
+
+ it 'shows a warning message about base domain' do
+ render
+
+ expect(rendered).to have_text('You must add a base domain to your Kubernetes cluster in order for your deployment strategy to work.')
+ end
end
end
diff --git a/yarn.lock b/yarn.lock
index 4cf3a9584f1..bd8f9014131 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4909,7 +4909,7 @@ exports-loader@^0.7.0:
express@^4.16.2, express@^4.16.3:
version "4.16.3"
- resolved "http://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
+ resolved "https://registry.npmjs.org/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53"
integrity sha1-avilAjUNsyRuzEvs9rWjTSL37VM=
dependencies:
accepts "~1.3.5"
@@ -8304,7 +8304,7 @@ mixin-deep@^1.2.0:
mkdirp@0.5.x, mkdirp@0.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.1"
- resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+ resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"