summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClement Ho <ClemMakesApps@gmail.com>2018-11-16 09:38:58 -0600
committerClement Ho <ClemMakesApps@gmail.com>2018-11-16 09:38:58 -0600
commite5d4f7ff277289af8fbffd392bc216ffb2d1d873 (patch)
tree102f0a450c2476da80fa39649aed522c732b72f2
parent17d53e2bf5f9ec44d56bf92daf972007fc5f9bff (diff)
parent624ec62238c1d26ef2745c1147edffde67a2b4e6 (diff)
downloadgitlab-ce-npm-namespace.tar.gz
Merge branch 'master' into npm-namespacenpm-namespace
-rw-r--r--app/assets/javascripts/diffs/store/actions.js2
-rw-r--r--app/assets/javascripts/diffs/store/getters.js2
-rw-r--r--app/assets/javascripts/ide/stores/modules/pipelines/actions.js2
-rw-r--r--app/assets/stylesheets/framework/files.scss1
-rw-r--r--app/assets/stylesheets/pages/diff.scss14
-rw-r--r--app/assets/stylesheets/pages/issuable.scss4
-rw-r--r--app/assets/stylesheets/pages/notes.scss8
-rw-r--r--app/models/ci/pipeline.rb19
-rw-r--r--app/models/ci/pipeline_enums.rb28
-rw-r--r--app/models/clusters/concerns/application_status.rb7
-rw-r--r--app/models/commit_status.rb15
-rw-r--r--app/models/commit_status_enums.rb20
-rw-r--r--app/models/hooks/service_hook.rb4
-rw-r--r--app/models/merge_request.rb1
-rw-r--r--app/models/user_callout.rb8
-rw-r--r--app/models/user_callout_enums.rb16
-rw-r--r--app/policies/ci/pipeline_policy.rb4
-rw-r--r--app/presenters/ci/pipeline_presenter.rb10
-rw-r--r--app/services/ci/destroy_pipeline_service.rb13
-rw-r--r--changelogs/unreleased/28682-can-merge-branch-before-build-is-started.yml5
-rw-r--r--changelogs/unreleased/41875-allow-pipelines-to-be-deleted-by-project-owners.yml5
-rw-r--r--changelogs/unreleased/49726-upgrade-helm-to-2-11.yml5
-rw-r--r--changelogs/unreleased/added-glob-for-ci-changes-detection.yml5
-rw-r--r--changelogs/unreleased/gt-fix-typos-in-lib.yml5
-rw-r--r--changelogs/unreleased/gt-rename-diffs-store-variable.yml5
-rw-r--r--changelogs/unreleased/sh-use-nokogiri-xml-backend.yml5
-rw-r--r--changelogs/unreleased/validate-foreign-keys-being-indexed.yml5
-rw-r--r--config/application.rb3
-rw-r--r--db/migrate/20181030154446_add_missing_indexes_for_foreign_keys.rb65
-rw-r--r--db/schema.rb22
-rw-r--r--doc/administration/git_protocol.md10
-rw-r--r--doc/administration/monitoring/prometheus/index.md2
-rw-r--r--doc/administration/uploads.md7
-rw-r--r--doc/api/avatar.md2
-rw-r--r--doc/api/commits.md2
-rw-r--r--doc/api/pipelines.md17
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_checkbox.pngbin4730 -> 0 bytes
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/index.md4
-rw-r--r--doc/ci/yaml/README.md2
-rw-r--r--doc/development/architecture.md189
-rw-r--r--doc/development/changelog.md18
-rw-r--r--doc/development/migration_style_guide.md7
-rw-r--r--doc/install/requirements.md8
-rw-r--r--doc/university/training/topics/tags.md2
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/img/new_project.pngbin7813 -> 0 bytes
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/img/rbac.pngbin49712 -> 15960 bytes
-rw-r--r--doc/user/project/clusters/eks_and_gitlab/index.md271
-rw-r--r--doc/user/project/clusters/index.md36
-rw-r--r--doc/user/project/clusters/serverless/img/deploy-stage.pngbin0 -> 12029 bytes
-rw-r--r--doc/user/project/clusters/serverless/img/dns-entry.pngbin0 -> 56600 bytes
-rw-r--r--doc/user/project/clusters/serverless/img/install-knative.pngbin0 -> 102861 bytes
-rw-r--r--doc/user/project/clusters/serverless/img/knative-app.pngbin0 -> 28998 bytes
-rw-r--r--doc/user/project/clusters/serverless/index.md137
-rw-r--r--doc/user/project/merge_requests/img/comment-on-any-diff-line.pngbin0 -> 177323 bytes
-rw-r--r--doc/user/project/merge_requests/index.md9
-rw-r--r--doc/user/project/settings/index.md2
-rw-r--r--lib/api/commits.rb2
-rw-r--r--lib/api/pipelines.rb15
-rw-r--r--lib/gitlab/checks/commit_check.rb4
-rw-r--r--lib/gitlab/ci/build/policy/changes.rb2
-rw-r--r--lib/gitlab/ci/parsers/test/junit.rb2
-rw-r--r--lib/gitlab/file_detector.rb2
-rw-r--r--lib/gitlab/gitaly_client.rb2
-rw-r--r--lib/gitlab/http_io.rb12
-rw-r--r--lib/gitlab/kubernetes/helm.rb2
-rw-r--r--lib/gitlab/kubernetes/helm/client_command.rb26
-rw-r--r--lib/gitlab/kubernetes/helm/install_command.rb10
-rw-r--r--lib/gitlab/kubernetes/helm/upgrade_command.rb10
-rw-r--r--lib/gitlab/view/presenter/base.rb4
-rw-r--r--locale/ar_SA/gitlab.po2
-rw-r--r--locale/bg/gitlab.po2
-rw-r--r--locale/ca_ES/gitlab.po2
-rw-r--r--locale/cs_CZ/gitlab.po2
-rw-r--r--locale/da_DK/gitlab.po2
-rw-r--r--locale/de/gitlab.po2
-rw-r--r--locale/eo/gitlab.po2
-rw-r--r--locale/es/gitlab.po2
-rw-r--r--locale/et_EE/gitlab.po2
-rw-r--r--locale/fil_PH/gitlab.po2
-rw-r--r--locale/fr/gitlab.po2
-rw-r--r--locale/gitlab.pot2
-rw-r--r--locale/gl_ES/gitlab.po2
-rw-r--r--locale/he_IL/gitlab.po2
-rw-r--r--locale/id_ID/gitlab.po2
-rw-r--r--locale/it/gitlab.po2
-rw-r--r--locale/ja/gitlab.po2
-rw-r--r--locale/ko/gitlab.po2
-rw-r--r--locale/mn_MN/gitlab.po2
-rw-r--r--locale/nb_NO/gitlab.po2
-rw-r--r--locale/nl_NL/gitlab.po2
-rw-r--r--locale/pl_PL/gitlab.po2
-rw-r--r--locale/pt_BR/gitlab.po2
-rw-r--r--locale/ro_RO/gitlab.po2
-rw-r--r--locale/ru/gitlab.po2
-rw-r--r--locale/sq_AL/gitlab.po2
-rw-r--r--locale/tr_TR/gitlab.po2
-rw-r--r--locale/uk/gitlab.po2
-rw-r--r--locale/zh_CN/gitlab.po2
-rw-r--r--locale/zh_HK/gitlab.po2
-rw-r--r--locale/zh_TW/gitlab.po2
-rw-r--r--spec/controllers/registrations_controller_spec.rb2
-rw-r--r--spec/controllers/sessions_controller_spec.rb2
-rw-r--r--spec/db/schema_spec.rb96
-rw-r--r--spec/fast_spec_helper.rb1
-rw-r--r--spec/features/issues/form_spec.rb2
-rw-r--r--spec/features/issues/user_creates_branch_and_merge_request_spec.rb4
-rw-r--r--spec/features/projects/jobs_spec.rb4
-rw-r--r--spec/finders/pipelines_finder_spec.rb2
-rw-r--r--spec/fixtures/trace/sample_trace24
-rw-r--r--spec/javascripts/diffs/store/actions_spec.js6
-rw-r--r--spec/javascripts/diffs/store/getters_spec.js8
-rw-r--r--spec/javascripts/ide/stores/modules/pipelines/actions_spec.js2
-rw-r--r--spec/lib/gitlab/ci/build/policy/changes_spec.rb12
-rw-r--r--spec/lib/gitlab/ci/build/policy/refs_spec.rb6
-rw-r--r--spec/lib/gitlab/ci/config/entry/artifacts_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/policy_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/reports_spec.rb2
-rw-r--r--spec/lib/gitlab/file_detector_spec.rb14
-rw-r--r--spec/lib/gitlab/git/commit_spec.rb2
-rw-r--r--spec/lib/gitlab/git/tag_spec.rb2
-rw-r--r--spec/lib/gitlab/kubernetes/helm/install_command_spec.rb21
-rw-r--r--spec/lib/gitlab/kubernetes/helm/pod_spec.rb2
-rw-r--r--spec/lib/gitlab/kubernetes/helm/upgrade_command_spec.rb12
-rw-r--r--spec/models/clusters/applications/prometheus_spec.rb2
-rw-r--r--spec/models/merge_request_spec.rb2
-rw-r--r--spec/policies/ci/pipeline_policy_spec.rb18
-rw-r--r--spec/requests/api/pipelines_spec.rb61
-rw-r--r--spec/services/ci/destroy_pipeline_service_spec.rb60
-rw-r--r--spec/services/system_hooks_service_spec.rb2
-rw-r--r--spec/support/shared_examples/models/cluster_application_status_shared_examples.rb32
-rw-r--r--spec/workers/emails_on_push_worker_spec.rb2
131 files changed, 1263 insertions, 334 deletions
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index fb648527450..6354d3ce1e6 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -167,7 +167,7 @@ export const expandAllFiles = ({ commit }) => {
export const toggleFileDiscussions = ({ getters, dispatch }, diff) => {
const discussions = getters.getDiffFileDiscussions(diff);
const shouldCloseAll = getters.diffHasAllExpandedDiscussions(diff);
- const shouldExpandAll = getters.diffHasAllCollpasedDiscussions(diff);
+ const shouldExpandAll = getters.diffHasAllCollapsedDiscussions(diff);
discussions.forEach(discussion => {
const data = { discussionId: discussion.id };
diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js
index 7f02c67a64e..05e32e3c1f1 100644
--- a/app/assets/javascripts/diffs/store/getters.js
+++ b/app/assets/javascripts/diffs/store/getters.js
@@ -27,7 +27,7 @@ export const diffHasAllExpandedDiscussions = (state, getters) => diff => {
* @param {Object} diff
* @returns {Boolean}
*/
-export const diffHasAllCollpasedDiscussions = (state, getters) => diff => {
+export const diffHasAllCollapsedDiscussions = (state, getters) => diff => {
const discussions = getters.getDiffFileDiscussions(diff);
return (
diff --git a/app/assets/javascripts/ide/stores/modules/pipelines/actions.js b/app/assets/javascripts/ide/stores/modules/pipelines/actions.js
index 8fa86995ef0..ea2525a2f0e 100644
--- a/app/assets/javascripts/ide/stores/modules/pipelines/actions.js
+++ b/app/assets/javascripts/ide/stores/modules/pipelines/actions.js
@@ -28,7 +28,7 @@ export const receiveLatestPipelineError = ({ commit, dispatch }, err) => {
dispatch(
'setErrorMessage',
{
- text: __('An error occured whilst fetching the latest pipline.'),
+ text: __('An error occured whilst fetching the latest pipeline.'),
action: () =>
dispatch('forcePipelineRequest').then(() =>
dispatch('setErrorMessage', null, { root: true }),
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index 6bdcb20210b..037a5adfb7e 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -415,7 +415,6 @@ span.idiff {
}
.preview-container {
- height: 100%;
overflow: auto;
.file-container {
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index 6d998fa1e07..3c7bf0b0e46 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -842,11 +842,15 @@
background-repeat: repeat;
}
- .diff-file-discussions + .discussion-form::before {
- width: auto;
- margin-left: -16px;
- margin-right: -16px;
- margin-bottom: 16px;
+ .diff-file-discussions + .discussion-form {
+ padding: $gl-padding;
+
+ &::before {
+ width: auto;
+ margin-left: -$gl-padding;
+ margin-right: -$gl-padding;
+ margin-bottom: $gl-padding;
+ }
}
.notes {
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 3aa79bf2466..38851de6401 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -727,6 +727,10 @@
.issuable-main-info {
flex: 1 auto;
margin-right: 10px;
+
+ .issue-weight-icon {
+ vertical-align: sub;
+ }
}
.issuable-meta {
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 1f34537d856..085ff27e6ef 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -433,14 +433,8 @@ $note-form-margin-left: 72px;
}
.discussion-notes {
- &:not(:first-child) {
- border-top: 1px solid $white-normal;
- margin-top: 20px;
- }
-
&:not(:last-child) {
- border-bottom: 1px solid $white-normal;
- margin-bottom: 20px;
+ margin-bottom: 0;
}
.system-note {
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 56010e899a4..9512ba42f67 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -58,15 +58,9 @@ module Ci
after_create :keep_around_commits, unless: :importing?
- enum_with_nil source: {
- unknown: nil,
- push: 1,
- web: 2,
- trigger: 3,
- schedule: 4,
- api: 5,
- external: 6
- }
+ # We use `Ci::PipelineEnums.sources` here so that EE can more easily extend
+ # this `Hash` with new values.
+ enum_with_nil source: ::Ci::PipelineEnums.sources
enum_with_nil config_source: {
unknown_source: nil,
@@ -74,10 +68,9 @@ module Ci
auto_devops_source: 2
}
- enum failure_reason: {
- unknown_failure: 0,
- config_error: 1
- }
+ # We use `Ci::PipelineEnums.failure_reasons` here so that EE can more easily
+ # extend this `Hash` with new values.
+ enum failure_reason: ::Ci::PipelineEnums.failure_reasons
state_machine :status, initial: :created do
event :enqueue do
diff --git a/app/models/ci/pipeline_enums.rb b/app/models/ci/pipeline_enums.rb
new file mode 100644
index 00000000000..8d8d16e2ec1
--- /dev/null
+++ b/app/models/ci/pipeline_enums.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Ci
+ module PipelineEnums
+ # Returns the `Hash` to use for creating the `failure_reason` enum for
+ # `Ci::Pipeline`.
+ def self.failure_reasons
+ {
+ unknown_failure: 0,
+ config_error: 1
+ }
+ end
+
+ # Returns the `Hash` to use for creating the `sources` enum for
+ # `Ci::Pipeline`.
+ def self.sources
+ {
+ unknown: nil,
+ push: 1,
+ web: 2,
+ trigger: 3,
+ schedule: 4,
+ api: 5,
+ external: 6
+ }
+ end
+ end
+end
diff --git a/app/models/clusters/concerns/application_status.rb b/app/models/clusters/concerns/application_status.rb
index 93bdf9c223d..0e74cce29b7 100644
--- a/app/models/clusters/concerns/application_status.rb
+++ b/app/models/clusters/concerns/application_status.rb
@@ -64,6 +64,13 @@ module Clusters
status_reason = transition.args.first
app_status.status_reason = status_reason if status_reason
end
+
+ before_transition any => [:installed, :updated] do |app_status, _|
+ # When installing any application we are also performing an update
+ # of tiller (see Gitlab::Kubernetes::Helm::ClientCommand) so
+ # therefore we need to reflect that in the database.
+ app_status.cluster.application_helm.update!(version: Gitlab::Kubernetes::Helm::HELM_VERSION)
+ end
end
end
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 755f8bd4d06..0f50bd39131 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -42,18 +42,9 @@ class CommitStatus < ActiveRecord::Base
scope :retried_ordered, -> { retried.ordered.includes(project: :namespace) }
scope :after_stage, -> (index) { where('stage_idx > ?', index) }
- enum_with_nil failure_reason: {
- unknown_failure: nil,
- script_failure: 1,
- api_failure: 2,
- stuck_or_timeout_failure: 3,
- runner_system_failure: 4,
- missing_dependency_failure: 5,
- runner_unsupported: 6,
- stale_schedule: 7,
- job_execution_timeout: 8,
- archived_failure: 9
- }
+ # We use `CommitStatusEnums.failure_reasons` here so that EE can more easily
+ # extend this `Hash` with new values.
+ enum_with_nil failure_reason: ::CommitStatusEnums.failure_reasons
##
# We still create some CommitStatuses outside of CreatePipelineService.
diff --git a/app/models/commit_status_enums.rb b/app/models/commit_status_enums.rb
new file mode 100644
index 00000000000..152105d9429
--- /dev/null
+++ b/app/models/commit_status_enums.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module CommitStatusEnums
+ # Returns the Hash to use for creating the `failure_reason` enum for
+ # `CommitStatus`.
+ def self.failure_reasons
+ {
+ unknown_failure: nil,
+ script_failure: 1,
+ api_failure: 2,
+ stuck_or_timeout_failure: 3,
+ runner_system_failure: 4,
+ missing_dependency_failure: 5,
+ runner_unsupported: 6,
+ stale_schedule: 7,
+ job_execution_timeout: 8,
+ archived_failure: 9
+ }
+ end
+end
diff --git a/app/models/hooks/service_hook.rb b/app/models/hooks/service_hook.rb
index 7d9f6d89d44..8f305dd7c22 100644
--- a/app/models/hooks/service_hook.rb
+++ b/app/models/hooks/service_hook.rb
@@ -5,8 +5,8 @@ class ServiceHook < WebHook
validates :service, presence: true
# rubocop: disable CodeReuse/ServiceClass
- def execute(data)
- WebHookService.new(self, data, 'service_hook').execute
+ def execute(data, hook_name = 'service_hook')
+ WebHookService.new(self, data, hook_name).execute
end
# rubocop: enable CodeReuse/ServiceClass
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index df5678ec2f1..92add079a02 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -966,7 +966,6 @@ class MergeRequest < ActiveRecord::Base
def mergeable_ci_state?
return true unless project.only_allow_merge_if_pipeline_succeeds?
- return true unless head_pipeline
actual_head_pipeline&.success? || actual_head_pipeline&.skipped?
end
diff --git a/app/models/user_callout.rb b/app/models/user_callout.rb
index 1cd05cf3aac..76e7bc06b4e 100644
--- a/app/models/user_callout.rb
+++ b/app/models/user_callout.rb
@@ -3,11 +3,9 @@
class UserCallout < ActiveRecord::Base
belongs_to :user
- enum feature_name: {
- gke_cluster_integration: 1,
- gcp_signup_offer: 2,
- cluster_security_warning: 3
- }
+ # We use `UserCalloutEnums.feature_names` here so that EE can more easily
+ # extend this `Hash` with new values.
+ enum feature_name: ::UserCalloutEnums.feature_names
validates :user, presence: true
validates :feature_name,
diff --git a/app/models/user_callout_enums.rb b/app/models/user_callout_enums.rb
new file mode 100644
index 00000000000..b9373ae6166
--- /dev/null
+++ b/app/models/user_callout_enums.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module UserCalloutEnums
+ # Returns the `Hash` to use for the `feature_name` enum in the `UserCallout`
+ # model.
+ #
+ # This method is separate from the `UserCallout` model so that it can be
+ # extended by EE.
+ def self.feature_names
+ {
+ gke_cluster_integration: 1,
+ gcp_signup_offer: 2,
+ cluster_security_warning: 3
+ }
+ end
+end
diff --git a/app/policies/ci/pipeline_policy.rb b/app/policies/ci/pipeline_policy.rb
index f9623587957..e42d78f47c5 100644
--- a/app/policies/ci/pipeline_policy.rb
+++ b/app/policies/ci/pipeline_policy.rb
@@ -16,6 +16,10 @@ module Ci
enable :update_pipeline
end
+ rule { can?(:owner_access) }.policy do
+ enable :destroy_pipeline
+ end
+
def ref_protected?(user, project, tag, ref)
access = ::Gitlab::UserAccess.new(user, project: project)
diff --git a/app/presenters/ci/pipeline_presenter.rb b/app/presenters/ci/pipeline_presenter.rb
index 93a38f92073..57daf04efc6 100644
--- a/app/presenters/ci/pipeline_presenter.rb
+++ b/app/presenters/ci/pipeline_presenter.rb
@@ -4,9 +4,11 @@ module Ci
class PipelinePresenter < Gitlab::View::Presenter::Delegated
include Gitlab::Utils::StrongMemoize
- FAILURE_REASONS = {
- config_error: 'CI/CD YAML configuration error!'
- }.freeze
+ # We use a class method here instead of a constant, allowing EE to redefine
+ # the returned `Hash` more easily.
+ def self.failure_reasons
+ { config_error: 'CI/CD YAML configuration error!' }
+ end
presents :pipeline
@@ -21,7 +23,7 @@ module Ci
def failure_reason
return unless pipeline.failure_reason?
- FAILURE_REASONS[pipeline.failure_reason.to_sym] ||
+ self.class.failure_reasons[pipeline.failure_reason.to_sym] ||
pipeline.failure_reason
end
diff --git a/app/services/ci/destroy_pipeline_service.rb b/app/services/ci/destroy_pipeline_service.rb
new file mode 100644
index 00000000000..13f892aabb8
--- /dev/null
+++ b/app/services/ci/destroy_pipeline_service.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Ci
+ class DestroyPipelineService < BaseService
+ def execute(pipeline)
+ raise Gitlab::Access::AccessDeniedError unless can?(current_user, :destroy_pipeline, pipeline)
+
+ AuditEventService.new(current_user, pipeline).security_event
+
+ pipeline.destroy!
+ end
+ end
+end
diff --git a/changelogs/unreleased/28682-can-merge-branch-before-build-is-started.yml b/changelogs/unreleased/28682-can-merge-branch-before-build-is-started.yml
new file mode 100644
index 00000000000..5ffd93e098f
--- /dev/null
+++ b/changelogs/unreleased/28682-can-merge-branch-before-build-is-started.yml
@@ -0,0 +1,5 @@
+---
+title: Strictly require a pipeline to merge.
+merge_request: 22911
+author:
+type: changed
diff --git a/changelogs/unreleased/41875-allow-pipelines-to-be-deleted-by-project-owners.yml b/changelogs/unreleased/41875-allow-pipelines-to-be-deleted-by-project-owners.yml
new file mode 100644
index 00000000000..0662ff6f523
--- /dev/null
+++ b/changelogs/unreleased/41875-allow-pipelines-to-be-deleted-by-project-owners.yml
@@ -0,0 +1,5 @@
+---
+title: Allow deleting a Pipeline via the API.
+merge_request: 22988
+author:
+type: added
diff --git a/changelogs/unreleased/49726-upgrade-helm-to-2-11.yml b/changelogs/unreleased/49726-upgrade-helm-to-2-11.yml
new file mode 100644
index 00000000000..dd26af875f5
--- /dev/null
+++ b/changelogs/unreleased/49726-upgrade-helm-to-2-11.yml
@@ -0,0 +1,5 @@
+---
+title: Upgrade helm to 2.11.0 and upgrade on every install
+merge_request: 22693
+author:
+type: added
diff --git a/changelogs/unreleased/added-glob-for-ci-changes-detection.yml b/changelogs/unreleased/added-glob-for-ci-changes-detection.yml
new file mode 100644
index 00000000000..887c6ef0346
--- /dev/null
+++ b/changelogs/unreleased/added-glob-for-ci-changes-detection.yml
@@ -0,0 +1,5 @@
+---
+title: Added glob for CI changes detection
+merge_request: 23128
+author: Kirill Zaitsev
+type: added
diff --git a/changelogs/unreleased/gt-fix-typos-in-lib.yml b/changelogs/unreleased/gt-fix-typos-in-lib.yml
new file mode 100644
index 00000000000..32ccd03b063
--- /dev/null
+++ b/changelogs/unreleased/gt-fix-typos-in-lib.yml
@@ -0,0 +1,5 @@
+---
+title: Fix typos in lib
+merge_request: 23106
+author: George Tsiolis
+type: other
diff --git a/changelogs/unreleased/gt-rename-diffs-store-variable.yml b/changelogs/unreleased/gt-rename-diffs-store-variable.yml
new file mode 100644
index 00000000000..0aed49f3d60
--- /dev/null
+++ b/changelogs/unreleased/gt-rename-diffs-store-variable.yml
@@ -0,0 +1,5 @@
+---
+title: Rename diffs store variable
+merge_request: 23123
+author: George Tsiolis
+type: other
diff --git a/changelogs/unreleased/sh-use-nokogiri-xml-backend.yml b/changelogs/unreleased/sh-use-nokogiri-xml-backend.yml
new file mode 100644
index 00000000000..6a82e32c416
--- /dev/null
+++ b/changelogs/unreleased/sh-use-nokogiri-xml-backend.yml
@@ -0,0 +1,5 @@
+---
+title: Use Nokogiri as the ActiveSupport XML backend
+merge_request: 23136
+author:
+type: performance
diff --git a/changelogs/unreleased/validate-foreign-keys-being-indexed.yml b/changelogs/unreleased/validate-foreign-keys-being-indexed.yml
new file mode 100644
index 00000000000..6608a93c08f
--- /dev/null
+++ b/changelogs/unreleased/validate-foreign-keys-being-indexed.yml
@@ -0,0 +1,5 @@
+---
+title: Validate foreign keys being created and indexed for column with _id
+merge_request: 22808
+author:
+type: performance
diff --git a/config/application.rb b/config/application.rb
index 1b084e91cfb..921baa5d617 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -158,6 +158,9 @@ module Gitlab
config.action_view.sanitized_allowed_protocols = %w(smb)
+ # Nokogiri is significantly faster and uses less memory than REXML
+ ActiveSupport::XmlMini.backend = 'Nokogiri'
+
# This middleware needs to precede ActiveRecord::QueryCache and other middlewares that
# connect to the database.
config.middleware.insert_after Rails::Rack::Logger, ::Gitlab::Middleware::BasicHealthCheck
diff --git a/db/migrate/20181030154446_add_missing_indexes_for_foreign_keys.rb b/db/migrate/20181030154446_add_missing_indexes_for_foreign_keys.rb
new file mode 100644
index 00000000000..176d55565d8
--- /dev/null
+++ b/db/migrate/20181030154446_add_missing_indexes_for_foreign_keys.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+class AddMissingIndexesForForeignKeys < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index(:application_settings, :usage_stats_set_by_user_id)
+ add_concurrent_index(:ci_pipeline_schedules, :owner_id)
+ add_concurrent_index(:ci_trigger_requests, :trigger_id)
+ add_concurrent_index(:ci_triggers, :owner_id)
+ add_concurrent_index(:clusters_applications_helm, :cluster_id, unique: true)
+ add_concurrent_index(:clusters_applications_ingress, :cluster_id, unique: true)
+ add_concurrent_index(:clusters_applications_jupyter, :cluster_id, unique: true)
+ add_concurrent_index(:clusters_applications_jupyter, :oauth_application_id)
+ add_concurrent_index(:clusters_applications_knative, :cluster_id, unique: true)
+ add_concurrent_index(:clusters_applications_prometheus, :cluster_id, unique: true)
+ add_concurrent_index(:fork_network_members, :forked_from_project_id)
+ add_concurrent_index(:internal_ids, :namespace_id)
+ add_concurrent_index(:internal_ids, :project_id)
+ add_concurrent_index(:issues, :closed_by_id)
+ add_concurrent_index(:label_priorities, :label_id)
+ add_concurrent_index(:merge_request_metrics, :merged_by_id)
+ add_concurrent_index(:merge_request_metrics, :latest_closed_by_id)
+ add_concurrent_index(:oauth_openid_requests, :access_grant_id)
+ add_concurrent_index(:project_deploy_tokens, :deploy_token_id)
+ add_concurrent_index(:protected_tag_create_access_levels, :group_id)
+ add_concurrent_index(:subscriptions, :project_id)
+ add_concurrent_index(:user_statuses, :user_id)
+ add_concurrent_index(:users, :accepted_term_id)
+ end
+
+ def down
+ # MySQL requires index for FK,
+ # thus removal of indexes does fail
+ return if Gitlab::Database.mysql?
+
+ remove_concurrent_index(:application_settings, :usage_stats_set_by_user_id)
+ remove_concurrent_index(:ci_pipeline_schedules, :owner_id)
+ remove_concurrent_index(:ci_trigger_requests, :trigger_id)
+ remove_concurrent_index(:ci_triggers, :owner_id)
+ remove_concurrent_index(:clusters_applications_helm, :cluster_id, unique: true)
+ remove_concurrent_index(:clusters_applications_ingress, :cluster_id, unique: true)
+ remove_concurrent_index(:clusters_applications_jupyter, :cluster_id, unique: true)
+ remove_concurrent_index(:clusters_applications_jupyter, :oauth_application_id)
+ remove_concurrent_index(:clusters_applications_knative, :cluster_id, unique: true)
+ remove_concurrent_index(:clusters_applications_prometheus, :cluster_id, unique: true)
+ remove_concurrent_index(:fork_network_members, :forked_from_project_id)
+ remove_concurrent_index(:internal_ids, :namespace_id)
+ remove_concurrent_index(:internal_ids, :project_id)
+ remove_concurrent_index(:issues, :closed_by_id)
+ remove_concurrent_index(:label_priorities, :label_id)
+ remove_concurrent_index(:merge_request_metrics, :merged_by_id)
+ remove_concurrent_index(:merge_request_metrics, :latest_closed_by_id)
+ remove_concurrent_index(:oauth_openid_requests, :access_grant_id)
+ remove_concurrent_index(:project_deploy_tokens, :deploy_token_id)
+ remove_concurrent_index(:protected_tag_create_access_levels, :group_id)
+ remove_concurrent_index(:subscriptions, :project_id)
+ remove_concurrent_index(:user_statuses, :user_id)
+ remove_concurrent_index(:users, :accepted_term_id)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index deaa2d30b26..8e02f43f702 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -166,6 +166,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.integer "diff_max_patch_bytes", default: 102400, null: false
t.integer "archive_builds_in_seconds"
t.string "commit_email_hostname"
+ t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id", using: :btree
end
create_table "audit_events", force: :cascade do |t|
@@ -435,6 +436,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.datetime "created_at"
t.datetime "updated_at"
t.index ["next_run_at", "active"], name: "index_ci_pipeline_schedules_on_next_run_at_and_active", using: :btree
+ t.index ["owner_id"], name: "index_ci_pipeline_schedules_on_owner_id", using: :btree
t.index ["project_id"], name: "index_ci_pipeline_schedules_on_project_id", using: :btree
end
@@ -547,6 +549,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.datetime "updated_at"
t.integer "commit_id"
t.index ["commit_id"], name: "index_ci_trigger_requests_on_commit_id", using: :btree
+ t.index ["trigger_id"], name: "index_ci_trigger_requests_on_trigger_id", using: :btree
end
create_table "ci_triggers", force: :cascade do |t|
@@ -557,6 +560,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.integer "owner_id"
t.string "description"
t.string "ref"
+ t.index ["owner_id"], name: "index_ci_triggers_on_owner_id", using: :btree
t.index ["project_id"], name: "index_ci_triggers_on_project_id", using: :btree
end
@@ -646,6 +650,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.text "encrypted_ca_key"
t.text "encrypted_ca_key_iv"
t.text "ca_cert"
+ t.index ["cluster_id"], name: "index_clusters_applications_helm_on_cluster_id", unique: true, using: :btree
end
create_table "clusters_applications_ingress", force: :cascade do |t|
@@ -658,6 +663,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.string "cluster_ip"
t.text "status_reason"
t.string "external_ip"
+ t.index ["cluster_id"], name: "index_clusters_applications_ingress_on_cluster_id", unique: true, using: :btree
end
create_table "clusters_applications_jupyter", force: :cascade do |t|
@@ -669,6 +675,8 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
t.text "status_reason"
+ t.index ["cluster_id"], name: "index_clusters_applications_jupyter_on_cluster_id", unique: true, using: :btree
+ t.index ["oauth_application_id"], name: "index_clusters_applications_jupyter_on_oauth_application_id", using: :btree
end
create_table "clusters_applications_knative", force: :cascade do |t|
@@ -679,6 +687,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.string "version", null: false
t.string "hostname"
t.text "status_reason"
+ t.index ["cluster_id"], name: "index_clusters_applications_knative_on_cluster_id", unique: true, using: :btree
end
create_table "clusters_applications_prometheus", force: :cascade do |t|
@@ -688,6 +697,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.text "status_reason"
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
+ t.index ["cluster_id"], name: "index_clusters_applications_prometheus_on_cluster_id", unique: true, using: :btree
end
create_table "clusters_applications_runners", force: :cascade do |t|
@@ -871,6 +881,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.integer "project_id", null: false
t.integer "forked_from_project_id"
t.index ["fork_network_id"], name: "index_fork_network_members_on_fork_network_id", using: :btree
+ t.index ["forked_from_project_id"], name: "index_fork_network_members_on_forked_from_project_id", using: :btree
t.index ["project_id"], name: "index_fork_network_members_on_project_id", unique: true, using: :btree
end
@@ -960,6 +971,8 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.integer "usage", null: false
t.integer "last_value", null: false
t.integer "namespace_id"
+ t.index ["namespace_id"], name: "index_internal_ids_on_namespace_id", using: :btree
+ t.index ["project_id"], name: "index_internal_ids_on_project_id", using: :btree
t.index ["usage", "namespace_id"], name: "index_internal_ids_on_usage_and_namespace_id", unique: true, where: "(namespace_id IS NOT NULL)", using: :btree
t.index ["usage", "project_id"], name: "index_internal_ids_on_usage_and_project_id", unique: true, where: "(project_id IS NOT NULL)", using: :btree
end
@@ -1007,6 +1020,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.datetime_with_timezone "closed_at"
t.integer "closed_by_id"
t.index ["author_id"], name: "index_issues_on_author_id", using: :btree
+ t.index ["closed_by_id"], name: "index_issues_on_closed_by_id", using: :btree
t.index ["confidential"], name: "index_issues_on_confidential", using: :btree
t.index ["description"], name: "index_issues_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"}
t.index ["milestone_id"], name: "index_issues_on_milestone_id", using: :btree
@@ -1052,6 +1066,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.integer "priority", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.index ["label_id"], name: "index_label_priorities_on_label_id", using: :btree
t.index ["priority"], name: "index_label_priorities_on_priority", using: :btree
t.index ["project_id", "label_id"], name: "index_label_priorities_on_project_id_and_label_id", unique: true, using: :btree
end
@@ -1194,7 +1209,9 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.integer "latest_closed_by_id"
t.datetime_with_timezone "latest_closed_at"
t.index ["first_deployed_to_production_at"], name: "index_merge_request_metrics_on_first_deployed_to_production_at", using: :btree
+ t.index ["latest_closed_by_id"], name: "index_merge_request_metrics_on_latest_closed_by_id", using: :btree
t.index ["merge_request_id"], name: "index_merge_request_metrics", using: :btree
+ t.index ["merged_by_id"], name: "index_merge_request_metrics_on_merged_by_id", using: :btree
t.index ["pipeline_id"], name: "index_merge_request_metrics_on_pipeline_id", using: :btree
end
@@ -1436,6 +1453,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
create_table "oauth_openid_requests", force: :cascade do |t|
t.integer "access_grant_id", null: false
t.string "nonce", null: false
+ t.index ["access_grant_id"], name: "index_oauth_openid_requests_on_access_grant_id", using: :btree
end
create_table "pages_domains", force: :cascade do |t|
@@ -1700,6 +1718,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.integer "group_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.index ["group_id"], name: "index_protected_tag_create_access_levels_on_group_id", using: :btree
t.index ["protected_tag_id"], name: "index_protected_tag_create_access", using: :btree
t.index ["user_id"], name: "index_protected_tag_create_access_levels_on_user_id", using: :btree
end
@@ -1903,6 +1922,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "project_id"
+ t.index ["project_id"], name: "index_subscriptions_on_project_id", using: :btree
t.index ["subscribable_id", "subscribable_type", "user_id", "project_id"], name: "index_subscriptions_on_subscribable_and_user_id_and_project_id", unique: true, using: :btree
end
@@ -2067,6 +2087,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.string "emoji", default: "speech_balloon", null: false
t.string "message", limit: 100
t.string "message_html"
+ t.index ["user_id"], name: "index_user_statuses_on_user_id", using: :btree
end
create_table "user_synced_attributes_metadata", force: :cascade do |t|
@@ -2147,6 +2168,7 @@ ActiveRecord::Schema.define(version: 20181107054254) do
t.boolean "private_profile"
t.boolean "include_private_contributions"
t.string "commit_email"
+ t.index ["accepted_term_id"], name: "index_users_on_accepted_term_id", using: :btree
t.index ["admin"], name: "index_users_on_admin", using: :btree
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
t.index ["created_at"], name: "index_users_on_created_at", using: :btree
diff --git a/doc/administration/git_protocol.md b/doc/administration/git_protocol.md
index b1be078d672..341a00009e5 100644
--- a/doc/administration/git_protocol.md
+++ b/doc/administration/git_protocol.md
@@ -19,7 +19,15 @@ and the [protocol documentation](https://github.com/git/git/blob/master/Document
From the client side, `git` `v2.18.0` or newer must be installed.
From the server side, if we want to configure SSH we need to set the `sshd`
-server to accept the `GIT_PROTOCOL` environment,
+server to accept the `GIT_PROTOCOL` environment.
+
+In installations using [GitLab Helm Charts](../install/kubernetes/gitlab_chart.md)
+and [All-in-one docker image](https://docs.gitlab.com/omnibus/docker/), the SSH
+service is already configured to accept the `GIT_PROTOCOL` environment and users
+need not do anything more.
+
+For Omnibus GitLab and installations from source, you have to manually update
+the SSH configuration of your server:
```
# /etc/ssh/sshd_config
diff --git a/doc/administration/monitoring/prometheus/index.md b/doc/administration/monitoring/prometheus/index.md
index 33611c5efc3..2d9fdedcbeb 100644
--- a/doc/administration/monitoring/prometheus/index.md
+++ b/doc/administration/monitoring/prometheus/index.md
@@ -27,7 +27,7 @@ dashboard tool like [Grafana].
NOTE: **Note:**
For installations from source you'll have to install and configure it yourself.
-Prometheus and it's exporters are on by default, starting with GitLab 9.0.
+Prometheus and its exporters are on by default, starting with GitLab 9.0.
Prometheus will run as the `gitlab-prometheus` user and listen on
`http://localhost:9090`. By default Prometheus is only accessible from the GitLab server itself.
Each exporter will be automatically set up as a
diff --git a/doc/administration/uploads.md b/doc/administration/uploads.md
index aec9a359ada..f85a1f791f9 100644
--- a/doc/administration/uploads.md
+++ b/doc/administration/uploads.md
@@ -48,11 +48,12 @@ _The uploads are stored by default in
1. Save the file and [restart GitLab][] for the changes to take effect.
-### Using object storage
+### Using object storage **[CORE ONLY]**
> **Notes:**
>
-> - [Introduced][ee-3867] in [GitLab Enterprise Edition Premium][eep] 10.5.
+> - [Introduced][ee-3867] in [GitLab Premium][eep] 10.5.
+> - [Introduced][ce17358] in [GitLab Core][ce] 10.7.
> - Since version 11.1, we support direct_upload to S3.
If you don't want to use the local disk where GitLab is installed to store the
@@ -197,4 +198,6 @@ _The uploads are stored by default in
[reconfigure gitlab]: restart_gitlab.md#omnibus-gitlab-reconfigure "How to reconfigure Omnibus GitLab"
[restart gitlab]: restart_gitlab.md#installations-from-source "How to restart GitLab"
[eep]: https://about.gitlab.com/gitlab-ee/ "GitLab Enterprise Edition Premium"
+[ce]: https://about.gitlab.com/gitlab-ce/ "GitLab Community Edition"
[ee-3867]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3867
+[ce-17358]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/17358
diff --git a/doc/api/avatar.md b/doc/api/avatar.md
index 7faed893066..aa6f7c185ae 100644
--- a/doc/api/avatar.md
+++ b/doc/api/avatar.md
@@ -4,7 +4,7 @@
## Get a single avatar URL
-Get a single avatar URL for a given email addres. If user with matching public
+Get a single avatar URL for a given email address. If user with matching public
email address is not found, results from external avatar services are returned.
This endpoint can be accessed without authentication. In case public visibility
is restricted, response will be `403 Forbidden` when unauthenticated.
diff --git a/doc/api/commits.md b/doc/api/commits.md
index 994eefa423f..7d9b52ec24f 100644
--- a/doc/api/commits.md
+++ b/doc/api/commits.md
@@ -290,7 +290,7 @@ Example response:
## Revert a commit
-> [Introduced][ce-22919] in GitLab 11.6.
+> [Introduced][ce-22919] in GitLab 11.5.
Reverts a commit in a given branch.
diff --git a/doc/api/pipelines.md b/doc/api/pipelines.md
index 574be52801c..7b4c9a8fbb3 100644
--- a/doc/api/pipelines.md
+++ b/doc/api/pipelines.md
@@ -235,5 +235,22 @@ Response:
}
```
+## Delete a pipeline
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22988) in GitLab 11.6.
+
+```
+DELETE /projects/:id/pipelines/:pipeline_id
+```
+
+| 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 |
+| `pipeline_id` | integer | yes | The ID of a pipeline |
+
+```
+curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --request "DELETE" "https://gitlab.example.com/api/v4/projects/1/pipelines/46"
+```
+
[ce-5837]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5837
[ce-7209]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/7209
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_checkbox.png b/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_checkbox.png
deleted file mode 100644
index a56c07a0da7..00000000000
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/img/container_registry_checkbox.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
index b6989d229d1..b090ea014dc 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
@@ -444,9 +444,7 @@ On your GitLab project repository navigate to the **Registry** tab.
![container registry page empty image](img/container_registry_page_empty_image.png)
-You may need to [enable Container Registry](../../../user/project/container_registry.md#enable-the-container-registry-for-your-project) to your project to see this tab. You'll find it under your project's **Settings > General > Sharing and permissions**.
-
-![container registry checkbox](img/container_registry_checkbox.png)
+You may need to [enable Container Registry](../../../user/project/container_registry.md#enable-the-container-registry-for-your-project) to your project to see this tab. You'll find it under your project's **Settings > General > Permissions**.
To start using Container Registry on our machine, we first need to login to the GitLab registry using our GitLab username and password:
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index aab5f268ef9..2a667c985da 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -476,6 +476,7 @@ docker build:
- Dockerfile
- docker/scripts/*
- dockerfiles/**/*
+ - more_scripts/*.{rb,py,sh}
```
In the scenario above, if you are pushing multiple commits to GitLab to an
@@ -485,6 +486,7 @@ one of the commits contains changes to either:
- The `Dockerfile` file.
- Any of the files inside `docker/scripts/` directory.
- Any of the files and subfolders inside `dockerfiles` directory.
+- Any of the files with `rb`, `py`, `sh` extensions inside `more_scripts` directory.
CAUTION: **Warning:**
There are some caveats when using this feature with new branches and tags. See
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 66d8a4f2f6e..01d99c46f89 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -10,39 +10,182 @@ For information, see the [GitLab Release Process](https://gitlab.com/gitlab-org/
Both EE and CE require some add-on components called gitlab-shell and Gitaly. These components are available from the [gitlab-shell](https://gitlab.com/gitlab-org/gitlab-shell/tree/master) and [gitaly](https://gitlab.com/gitlab-org/gitaly/tree/master) repositories respectively. New versions are usually tags but staying on the master branch will give you the latest stable version. New releases are generally around the same time as GitLab CE releases with exception for informal security updates deemed critical.
-## Physical office analogy
+## GitLab Omnibus Component by Component
-You can imagine GitLab as a physical office.
+This document is designed to be consumed by systems adminstrators and GitLab Support Engineers who want to understand more about the internals of GitLab and how they work together.
-**The repositories** are the goods GitLab handles.
-They can be stored in a warehouse.
-This can be either a hard disk, or something more complex, such as a NFS filesystem;
+When deployed, GitLab should be considered the amalgamation of the below processes. When troubleshooting or debugging, be as specific as possible as to which component you are referencing. That should increase clarity and reduce confusion.
-**Nginx** acts like the front-desk.
-Users come to Nginx and request actions to be done by workers in the office;
+### GitLab Process Descriptions
-**The database** is a series of metal file cabinets with information on:
- - The goods in the warehouse (metadata, issues, merge requests etc);
- - The users coming to the front desk (permissions)
+As of this writing, a fresh GitLab 11.3.0 install will show the following processes with `gitlab-ctl status`:
-**Redis** is a communication board with “cubby holes” that can contain tasks for office workers;
+```
+run: alertmanager: (pid 30829) 14207s; run: log: (pid 13906) 2432044s
+run: gitaly: (pid 30771) 14210s; run: log: (pid 13843) 2432046s
+run: gitlab-monitor: (pid 30788) 14209s; run: log: (pid 13868) 2432045s
+run: gitlab-workhorse: (pid 30758) 14210s; run: log: (pid 13855) 2432046s
+run: logrotate: (pid 30246) 3407s; run: log: (pid 13825) 2432047s
+run: nginx: (pid 30849) 14207s; run: log: (pid 13856) 2432046s
+run: node-exporter: (pid 30929) 14206s; run: log: (pid 13877) 2432045s
+run: postgres-exporter: (pid 30935) 14206s; run: log: (pid 13931) 2432044s
+run: postgresql: (pid 13133) 2432214s; run: log: (pid 13848) 2432046s
+run: prometheus: (pid 30807) 14209s; run: log: (pid 13884) 2432045s
+run: redis: (pid 30560) 14274s; run: log: (pid 13807) 2432047s
+run: redis-exporter: (pid 30946) 14205s; run: log: (pid 13869) 2432045s
+run: sidekiq: (pid 30953) 14205s; run: log: (pid 13810) 2432047s
+run: unicorn: (pid 30960) 14204s; run: log: (pid 13809) 2432047s
+```
+
+### Layers
+
+GitLab can be considered to have two layers from a process perspective:
+
+- **Monitoring**: Anything from this layer is not required to deliver GitLab the application, but will allow administrators more insight into their infrastructure and what the service as a whole is doing.
+- **Core**: Any process that is vital for the delivery of GitLab as as platform. If any of these processes halt there will be a GitLab outage. For the Core layer, you can further divide into:
+ - **Processors**: These processes are responsible for actually performing operations and presenting the service.
+ - **Data**: These services store/expose structured data for the GitLab service.
+
+### alertmanager
+
+- Omnibus configuration options
+- Layer: Monitoring
+
+[Alert manager](https://prometheus.io/docs/alerting/alertmanager/) is a tool provided by prometheus that _"handles alerts sent by client applications such as the Prometheus server. It takes care of deduplicating, grouping, and routing them to the correct receiver integration such as email, PagerDuty, or OpsGenie. It also takes care of silencing and inhibition of alerts."_ You can read more in [issue gitlab-ce#45740](https://gitlab.com/gitlab-org/gitlab-ce/issues/45740) about what we will be alerting on.
+
+### gitaly
+
+- [Omnibus confiugration options](https://gitlab.com/gitlab-org/gitaly/tree/master/doc/configuration)
+- Layer: Core Service (Data)
+
+Gitaly is a service designed by GitLab to remove our need for NFS for Git storage in distributed deployments of GitLab. (Think GitLab.com or High Availablity Deployments) As of 11.3.0, This service handles all Git level access in GitLab. You can read more about the project [in the project's readme](https://gitlab.com/gitlab-org/gitaly).
+
+### gitlab-monitor
+
+- Omnibus configuration options
+- Layer: Monitoring
+
+GitLab Monitor is a process disigned in house that allows us to export metrics about GitLab application internals to prometheus. You can read more [in the project's readme](https://gitlab.com/gitlab-org/gitlab-monitor)
+
+### gitlab-workhorse
+
+- Omnibus configuration options
+- Layer: Core Service (Processor)
+
+[GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) is a program designed at GitLab to help alieviate pressure from unicorn. You can read more about the [historical reasons for developing](https://about.gitlab.com/2016/04/12/a-brief-history-of-gitlab-workhorse/). It's designed to act as a smart reverse proxy to help speed up GitLab as a whole.
+
+### logrotate
+
+- [Omnibus configuration options](https://docs.gitlab.com/omnibus/settings/logs.html#logrotate)
+- Layer: Core Service
+
+GitLab is comprised of a large number of services that all log. We started bundling our own logrotate as of 7.4 to make sure we were logging responsibly. This is just a packaged version of the common opensource offering.
+
+### nginx
+
+- [Omnibus configuration options](https://docs.gitlab.com/omnibus/settings/nginx.html)
+- Layer: Core Service (Processor)
+
+Nginx as as an ingress port for all HTTP requests and routes them to the approriate sub-systems within GitLab. We are bundling an unmodified version of the popular open source webserver.
+
+### node-exporter
+
+- [Omnibus configuration options](https://docs.gitlab.com/ee/administration/monitoring/prometheus/node_exporter.html)
+- Layer: Monitoring
+
+[Node Exporter](https://github.com/prometheus/node_exporter) is a Prometheus tool that gives us metrics on the underlying machine. (Think CPU/Disk/Load) It's just a packaged version of the common open source offering from the Prometheus project.
+
+### postgres-exporter
+
+- [Omnibus configuration options](https://docs.gitlab.com/ee/administration/monitoring/prometheus/postgres_exporter.html)
+- Layer: Monitoring
+
+[Postgres-exporter](https://github.com/wrouesnel/postgres_exporter) is the community provided Prometheus exporter that will deliver data about Postgres to prometheus for use in Grafana Dashboards.
+
+### postgresql
+
+- [Omnibus configuration options](https://docs.gitlab.com/omnibus/settings/database.html)
+- Layer: Core Service (Data)
+
+GitLab packages the popular Database to provide storage for Application meta data and user information.
+
+### prometheus
+
+- [Omnibus configuration options](https://docs.gitlab.com/ee/administration/monitoring/prometheus/)
+- Layer: Monitoring
+
+Prometheus is a time-series tool that helps GitLab administrators expose metrics about the individual processes used to provide GitLab the service.
+
+### redis
+
+- [Omnibus configuration options](https://docs.gitlab.com/omnibus/settings/redis.html)
+- Layer: Core Service (Data)
+
+Redis is packaged to provide a place to store:
+
+- session data
+- temporary cache information
+- background job queues.
+
+### redis-exporter
+
+- [Omnibus configuration options](https://docs.gitlab.com/ee/administration/monitoring/prometheus/redis_exporter.html)
+- Layer: Monitoring
+
+[Redis Exporter](https://github.com/oliver006/redis_exporter) is designed to give specific metrics about the Redis process to Prometheus so that we can graph these metrics in Graphana.
+
+### sidekiq
+
+- Omnibus configuration options
+- Layer: Core Service (Processor)
+
+Sidekiq is a Ruby background job processor that pulls jobs from the redis queue and processes them. Background jobs allow GitLab to provide a faster request/response cycle by moving work into the background.
+
+### unicorn
+
+- [Omnibus configuration options](https://docs.gitlab.com/omnibus/settings/unicorn.html)
+- Layer: Core Service (Processor)
+
+[Unicorn](https://bogomips.org/unicorn/) is a Ruby application server that is used to run the core Rails Application that provides the user facing features in GitLab. Often process output you will see this as `bundle` or `config.ru` depending on the GitLab version.
+
+### Additional Processes
+
+### GitLab Pages
+
+TODO
+
+### Mattermost
+
+TODO
+
+## GitLab by Request Type
+
+GitLab provides two "interfaces" for end users to access the service:
+
+- Web HTTP Requests (Viewing the UI/API)
+- Git HTTP/SSH Requests (Pushing/Pulling Git Data)
+
+It's important to understand the distinction as some processes are used in both and others are exclusive to a specific request type.
+
+### GitLab Web HTTP Request Cycle
+
+When making a request to an HTTP Endpoint (Think `/users/sign_in`) the request will take the following path through the GitLab Service:
+
+- nginx - Acts as our first line reverse proxy
+- gitlab-workhorse - This determines if it needs to go to the Rails application or somewhere else to reduce load on unicorn.
+- unicorn - Since this is a web request, and it needs to access the application it will go to Unicorn.
+- Postgres/Gitaly/Redis - Depending on the type of request, it may hit these services to store or retreive data.
-**Sidekiq** is a worker that primarily handles sending out emails.
-It takes tasks from the Redis communication board;
-**A Unicorn worker** is a worker that handles quick/mundane tasks.
-They work with the communication board (Redis).
-Their job description:
- - check permissions by checking the user session stored in a Redis “cubby hole”;
- - make tasks for Sidekiq;
- - fetch stuff from the warehouse or move things around in there;
+### GitLab Git Request Cycle
-**GitLab-shell** is a third kind of worker that takes orders from a fax machine (SSH) instead of the front desk (HTTP).
-GitLab-shell communicates with Sidekiq via the “communication board” (Redis), and asks quick questions of the Unicorn workers either directly or via the front desk.
+Below we describe the different pathing that HTTP vs. SSH Git requests will take. There is some overlap with the Web Request Cycle but also some differences.
-**Gitaly** is a back desk that is specialized on reaching the disks to perform git operations efficiently and keep a copy of the result of costly operations. All git operations go through Gitaly.
+### Web Request (80/443)
+TODO
-**GitLab Enterprise Edition (the application)** is the collection of processes and business practices that the office is run by.
+### SSH Request (22)
+TODO
## System Layout
diff --git a/doc/development/changelog.md b/doc/development/changelog.md
index f06d40d1dbb..cd0a1f46d27 100644
--- a/doc/development/changelog.md
+++ b/doc/development/changelog.md
@@ -133,15 +133,15 @@ If you're working on the GitLab EE repository, the entry will be added to
### Arguments
-| Argument | Shorthand | Purpose |
-| ----------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
-| [`--amend`] | | Amend the previous commit |
-| [`--force`] | `-f` | Overwrite an existing entry |
-| [`--merge-request`] | `-m` | Set merge request ID |
-| [`--dry-run`] | `-n` | Don't actually write anything, just print |
-| [`--git-username`] | `-u` | Use Git user.name configuration as the author |
-| [`--type`] | `-t` | The category of the change, valid options are: added, fixed, changed, deprecated, removed, security, other |
-| [`--help`] | `-h` | Print help message |
+| Argument | Shorthand | Purpose |
+| ----------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------- |
+| [`--amend`] | | Amend the previous commit |
+| [`--force`] | `-f` | Overwrite an existing entry |
+| [`--merge-request`] | `-m` | Set merge request ID |
+| [`--dry-run`] | `-n` | Don't actually write anything, just print |
+| [`--git-username`] | `-u` | Use Git user.name configuration as the author |
+| [`--type`] | `-t` | The category of the change, valid options are: `added`, `fixed`, `changed`, `deprecated`, `removed`, `security`, `performance`, `other` |
+| [`--help`] | `-h` | Print help message |
[`--amend`]: #-amend
[`--force`]: #-force-or-f
diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md
index 6f31e5b82e5..e4e532bb4ed 100644
--- a/doc/development/migration_style_guide.md
+++ b/doc/development/migration_style_guide.md
@@ -187,12 +187,7 @@ end
When adding a foreign-key constraint to either an existing or new
column remember to also add a index on the column.
-This is _required_ if the foreign-key constraint specifies
-`ON DELETE CASCADE` or `ON DELETE SET NULL` behavior. On a cascading
-delete, the [corresponding record needs to be retrieved using an
-index](https://www.cybertec-postgresql.com/en/postgresql-indexes-and-foreign-keys/)
-(otherwise, we'd need to scan the whole table) for subsequent update or
-deletion.
+This is _required_ for all foreign-keys.
Here's an example where we add a new column with a foreign key
constraint. Note it includes `index: true` to create an index for it.
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index dcc6d75724e..97190544c3d 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -197,7 +197,13 @@ use the CI features.
## Supported web browsers
-We support the current and the previous major release of Firefox, Chrome/Chromium, Safari and Microsoft browsers (Microsoft Edge and Internet Explorer 11).
+We support the current and the previous major release of:
+
+- Firefox
+- Chrome/Chromium
+- Safari
+- Microsoft Edge
+- Internet Explorer 11
Each time a new browser version is released, we begin supporting that version and stop supporting the third most recent version.
diff --git a/doc/university/training/topics/tags.md b/doc/university/training/topics/tags.md
index 9526bcbfb82..14c39457838 100644
--- a/doc/university/training/topics/tags.md
+++ b/doc/university/training/topics/tags.md
@@ -22,7 +22,7 @@ comments: false
**Additional resources**
-<http://git-scm.com/book/en/Git-Basics-Tagging>
+<https://git-scm.com/book/en/Git-Basics-Tagging>
----------
diff --git a/doc/user/project/clusters/eks_and_gitlab/img/new_project.png b/doc/user/project/clusters/eks_and_gitlab/img/new_project.png
deleted file mode 100644
index 02afc099f10..00000000000
--- a/doc/user/project/clusters/eks_and_gitlab/img/new_project.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/clusters/eks_and_gitlab/img/rbac.png b/doc/user/project/clusters/eks_and_gitlab/img/rbac.png
index c8adaad13c2..517e4f7ca44 100644
--- a/doc/user/project/clusters/eks_and_gitlab/img/rbac.png
+++ b/doc/user/project/clusters/eks_and_gitlab/img/rbac.png
Binary files differ
diff --git a/doc/user/project/clusters/eks_and_gitlab/index.md b/doc/user/project/clusters/eks_and_gitlab/index.md
index 45d77e075f1..fa2ed21f980 100644
--- a/doc/user/project/clusters/eks_and_gitlab/index.md
+++ b/doc/user/project/clusters/eks_and_gitlab/index.md
@@ -1,123 +1,139 @@
# Connecting and deploying to an Amazon EKS cluster
-## Introduction
+In this tutorial, we will show how to integrate an
+[Amazon EKS](https://aws.amazon.com/eks/) cluster with GitLab and begin
+deploying applications.
-In this tutorial, we will show how to integrate an [Amazon EKS](https://aws.amazon.com/eks/) cluster with GitLab, and begin deploying applications.
+## Introduction
For an end-to-end walkthrough we will:
-1. Start with a new project based on the sample Ruby on Rails template
-1. Integrate an EKS cluster
-1. Utilize [Auto DevOps](../../../../topics/autodevops/) to build, test, and deploy our application
+1. Start with a new project based on the sample Ruby on Rails template.
+1. Integrate an EKS cluster.
+1. Utilize [Auto DevOps](../../../../topics/autodevops/) to build, test, and deploy our application.
You will need:
-1. An account on GitLab, like [GitLab.com](https://gitlab.com)
-1. An Amazon EKS cluster (with worker nodes properly configured)
-1. `kubectl` [installed and configured for access to the EKS cluster](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html#get-started-kubectl)
+1. An account on GitLab, like [GitLab.com](https://gitlab.com).
+1. An Amazon EKS cluster (with worker nodes properly configured).
+1. `kubectl` [installed and configured for access to the EKS cluster](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html#get-started-kubectl).
-If you don't have an Amazon EKS cluster, one can be created by following [the EKS getting started guide](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html).
+If you don't have an Amazon EKS cluster, one can be created by following the
+[EKS getting started guide](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html).
## Creating a new project
-On GitLab, create a new project by clicking on the `+` icon in the top navigation bar, and selecting `New project`.
-
-![New Project](img/new_project.png)
+On GitLab, create a new project by clicking on the `+` icon in the top navigation
+bar and selecting **New project**.
-On the new project screen, click on the `Create from template` tab, and select `Use template` for the Ruby on Rails sample project.
+On the new project screen, click on the **Create from template** tab, and select
+"Use template" for the Ruby on Rails sample project.
-Give the project a name, and then select `Create project`.
+Give the project a name, and then select **Create project**.
![Create Project](img/create_project.png)
## Configuring and connecting the EKS cluster
-From the left side bar, hover over `Operations` and select `Kubernetes`, then click on `Add Kubernetes cluster`, and finally `Add an existing Kubernetes cluster`.
+From the left side bar, hover over **Operations > Kubernetes > Add Kubernetes cluster**,
+then click **Add an existing Kubernetes cluster**.
-A few details from the EKS cluster will be required to connect it to GitLab.
+A few details from the EKS cluster will be required to connect it to GitLab:
-1. **Retrieve the certificate**: A valid Kubernetes certificate is needed to authenticate to the EKS cluster. We will use the certificate created by default. Open a shell and use `kubectl` to retrieve it:
- - List the secrets with `kubectl get secrets`, and one should named similar to `default-token-xxxxx`. Copy that token name for use below.
- - Get the certificate with `kubectl get secret <secret name> -o jsonpath="{['data']['ca\.crt']}" | base64 -D`
+1. **Retrieve the certificate**: A valid Kubernetes certificate is needed to
+ authenticate to the EKS cluster. We will use the certificate created by default.
+ Open a shell and use `kubectl` to retrieve it:
-1. **Create admin token**: A `cluster-admin` token is required to install and manage Helm Tiller. GitLab establishes mutual SSL auth with Helm Tiller and creates limited service accounts for each application. To create the token we will create an admin service account as follows:
+ - List the secrets with `kubectl get secrets`, and one should named similar to
+ `default-token-xxxxx`. Copy that token name for use below.
+ - Get the certificate with:
- 1. Create a file called `eks-admin-service-account.yaml` with the text below:
+ ```sh
+ kubectl get secret <secret name> -o jsonpath="{['data']['ca\.crt']}" | base64 -D
+ ```
- ```yaml
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: eks-admin
- namespace: kube-system
- ```
+1. **Create admin token**: A `cluster-admin` token is required to install and
+ manage Helm Tiller. GitLab establishes mutual SSL auth with Helm Tiller
+ and creates limited service accounts for each application. To create the
+ token we will create an admin service account as follows:
- 2. Apply the service account to your cluster:
+ 2.1. Create a file called `eks-admin-service-account.yaml` with contents:
- ```bash
- kubectl apply -f eks-admin-service-account.yaml
- ```
+ ```yaml
+ apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: eks-admin
+ namespace: kube-system
+ ```
- Output:
+ 2.2. Apply the service account to your cluster:
- ```bash
- serviceaccount "eks-admin" created
- ```
+ ```bash
+ kubectl apply -f eks-admin-service-account.yaml
+ ```
- 3. Create a file called `eks-admin-cluster-role-binding.yaml` with the text below:
+ Output:
- ```yaml
- apiVersion: rbac.authorization.k8s.io/v1beta1
- kind: ClusterRoleBinding
- metadata:
- name: eks-admin
- roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: cluster-admin
- subjects:
- - kind: ServiceAccount
- name: eks-admin
- namespace: kube-system
- ```
+ ```bash
+ serviceaccount "eks-admin" created
+ ```
- 4. Apply the cluster role binding to your cluster:
+ 2.3. Create a file called `eks-admin-cluster-role-binding.yaml` with contents:
- ```bash
- kubectl apply -f eks-admin-cluster-role-binding.yaml
- ```
+ ```yaml
+ apiVersion: rbac.authorization.k8s.io/v1beta1
+ kind: ClusterRoleBinding
+ metadata:
+ name: eks-admin
+ roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: cluster-admin
+ subjects:
+ - kind: ServiceAccount
+ name: eks-admin
+ namespace: kube-system
+ ```
- Output:
+ 2.4. Apply the cluster role binding to your cluster:
- ```bash
- clusterrolebinding "eks-admin" created
- ```
+ ```bash
+ kubectl apply -f eks-admin-cluster-role-binding.yaml
+ ```
- 5. Retrieve the token for the `eks-admin` service account. Copy the `<authentication_token>` value from the output.
+ Output:
- ```bash
- kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-admin | awk '{print $1}')
- ```
+ ```bash
+ clusterrolebinding "eks-admin" created
+ ```
- Output:
-
- ```yaml
- Name: eks-admin-token-b5zv4
- Namespace: kube-system
- Labels: <none>
- Annotations: kubernetes.io/service-account.name=eks-admin
- kubernetes.io/service-account.uid=bcfe66ac-39be-11e8-97e8-026dce96b6e8
+ 2.5. Retrieve the token for the `eks-admin` service account:
- Type: kubernetes.io/service-account-token
+ ```bash
+ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-admin | awk '{print $1}')
+ ```
- Data
- ====
- ca.crt: 1025 bytes
- namespace: 11 bytes
- token: <authentication_token>
- ```
+ Copy the `<authentication_token>` value from the output:
+
+ ```yaml
+ Name: eks-admin-token-b5zv4
+ Namespace: kube-system
+ Labels: <none>
+ Annotations: kubernetes.io/service-account.name=eks-admin
+ kubernetes.io/service-account.uid=bcfe66ac-39be-11e8-97e8-026dce96b6e8
-1. The API server endpoint is also required, so GitLab can connect to the cluster. This is displayed on the AWS EKS console, when viewing the EKS cluster details.
+ Type: kubernetes.io/service-account-token
+
+ Data
+ ====
+ ca.crt: 1025 bytes
+ namespace: 11 bytes
+ token: <authentication_token>
+ ```
+
+1. The API server endpoint is also required, so GitLab can connect to the cluster.
+ This is displayed on the AWS EKS console, when viewing the EKS cluster details.
You now have all the information needed to connect the EKS cluster:
@@ -130,17 +146,26 @@ You now have all the information needed to connect the EKS cluster:
![Add Cluster](img/add_cluster.png)
-Click on `Add Kubernetes cluster`, the cluster is now connected to GitLab. At this point, [Kubernetes deployment variables](../#deployment-variables) will automatically be available during CI jobs, making it easy to interact with the cluster.
+Click on **Add Kubernetes cluster**, the cluster is now connected to GitLab.
+At this point, [Kubernetes deployment variables](../#deployment-variables) will
+automatically be available during CI/CD jobs, making it easy to interact with the cluster.
If you would like to utilize your own CI/CD scripts to deploy to the cluster, you can stop here.
-## Disable Role-Based Access Control (RBAC) - Optional
+## Disable Role-Based Access Control (RBAC) (optional)
-When connecting a cluster via GitLab integration, you may specify whether the cluster is RBAC-enabled or not. This will affect how GitLab interacts with the cluster for certain operations. If you **did not** check the "RBAC-enabled cluster" checkbox at creation time, GitLab will assume RBAC is disabled for your cluster when interacting with it. If so, you must disable RBAC on your cluster for the integration to work properly.
+When connecting a cluster via GitLab integration, you may specify whether the
+cluster is RBAC-enabled or not. This will affect how GitLab interacts with the
+cluster for certain operations. If you **did not** check the "RBAC-enabled cluster"
+checkbox at creation time, GitLab will assume RBAC is disabled for your cluster
+when interacting with it. If so, you must disable RBAC on your cluster for the
+integration to work properly.
![rbac](img/rbac.png)
-> **Note**: Disabling RBAC means that any application running in the cluster, or user who can authenticate to the cluster, has full API access. This is a [security concern](https://docs.gitlab.com/ee/user/project/clusters/#security-implications), and may not be desirable.
+NOTE: **Note**: Disabling RBAC means that any application running in the cluster,
+or user who can authenticate to the cluster, has full API access. This is a
+[security concern](../index.md#security-implications), and may not be desirable.
To effectively disable RBAC, global permissions can be applied granting full access:
@@ -154,56 +179,100 @@ kubectl create clusterrolebinding permissive-binding \
## Deploy services to the cluster
-GitLab supports one-click deployment of helpful services to the cluster, many of which support Auto DevOps. Back on the Kubernetes cluster screen in GitLab, a list of applications is now available to deploy.
+GitLab supports one-click deployment of helpful services to the cluster, many of
+which support Auto DevOps. Back on the Kubernetes cluster screen in GitLab, a
+list of applications is now available to deploy.
-First install Helm Tiller, a package manager for Kubernetes. This enables deployment of the other applications.
+First, install Helm Tiller, a package manager for Kubernetes. This enables
+deployment of the other applications.
![Deploy Apps](img/deploy_apps.png)
### Deploying NGINX Ingress (optional)
-Next, if you would like the deployed app to be reachable on the internet, deploy the Ingress. Note that this will also cause an [Elastic Load Balancer](https://aws.amazon.com/documentation/elastic-load-balancing/) to be created, which will incur additional AWS costs.
+Next, if you would like the deployed app to be reachable on the internet, deploy
+the Ingress. Note that this will also cause an
+[Elastic Load Balancer](https://aws.amazon.com/documentation/elastic-load-balancing/)
+to be created, which will incur additional AWS costs.
+
+Once installed, you may see a `?` for "Ingress IP Address". This is because the
+created ELB is available at a DNS name, not an IP address. To get the DNS name,
+run:
-Once installed, you may see a `?` for `Ingress IP Address`. This is because the created ELB is available at a DNS name, not an IP address. To get the DNS name, run: `kubectl get service ingress-nginx-ingress-controller -n gitlab-managed-apps -o jsonpath="{.status.loadBalancer.ingress[0].hostname}"`. Note, you may see a trailing `%` on some Kubernetes versions, do not include it.
+```sh
+kubectl get service ingress-nginx-ingress-controller -n gitlab-managed-apps -o jsonpath="{.status.loadBalancer.ingress[0].hostname}"
+```
+
+Note that you may see a trailing `%` on some Kubernetes versions, **do not include it**.
-The Ingress is now available at this address, and will route incoming requests to the proper service based on the DNS name in the request. To support this, a wildcard DNS CNAME record should be created for the desired domain name. For example `*.myekscluster.com` would point to the Ingress hostname obtained earlier.
+The Ingress is now available at this address and will route incoming requests to
+the proper service based on the DNS name in the request. To support this, a
+wildcard DNS CNAME record should be created for the desired domain name. For example,
+`*.myekscluster.com` would point to the Ingress hostname obtained earlier.
![Create DNS](img/create_dns.png)
### Deploying the GitLab Runner (optional)
-If the project is on GitLab.com, free shared runners are available and you do not have to deploy one. If a project specific runner is desired, or there are no shared runners, it is easy to deploy one.
+If the project is on GitLab.com, free shared Runners are available and you do
+not have to deploy one. If a project specific Runner is desired, or there are no
+shared Runners, it is easy to deploy one.
-Simply click on the `Install` button for the GitLab Runner. It is important to note that the runner deployed is set as **privileged**, which means it essentially has root access to the underlying machine. This is required to build docker images, and so is on by default.
+Simply click on the **Install** button for the GitLab Runner. It is important to
+note that the Runner deployed is set as **privileged**, which means it essentially
+has root access to the underlying machine. This is required to build docker images,
+and so is on by default.
### Deploying Prometheus (optional)
-GitLab is able to monitor applications automatically, utilizing [Prometheus](../../integrations/prometheus.html). Kubernetes container CPU and memory metrics are automatically collected, and response metrics are retrieved from NGINX Ingress as well.
+GitLab is able to monitor applications automatically, utilizing
+[Prometheus](../../integrations/prometheus.html). Kubernetes container CPU and
+memory metrics are automatically collected, and response metrics are retrieved
+from NGINX Ingress as well.
-To enable monitoring, simply install Prometheus into the cluster with the `Install` button.
+To enable monitoring, simply install Prometheus into the cluster with the
+**Install** button.
## Create a default Storage Class
-Amazon EKS does not have a default Storage Class out of the box, which means requests for persistent volumes will not be automatically fulfilled. As part of Auto DevOps, the deployed Postgres instance requests persistent storage, and without a default storage class it will fail to start.
+Amazon EKS doesn't have a default Storage Class out of the box, which means
+requests for persistent volumes will not be automatically fulfilled. As part
+of Auto DevOps, the deployed Postgres instance requests persistent storage,
+and without a default storage class it will fail to start.
-If a default Storage Class does not already exist and is desired, follow Amazon's [short guide](https://docs.aws.amazon.com/eks/latest/userguide/storage-classes.html) to create one.
+If a default Storage Class doesn't already exist and is desired, follow Amazon's
+[guide on storage classes](https://docs.aws.amazon.com/eks/latest/userguide/storage-classes.html)
+to create one.
-Alternatively, disable Postgres by setting the project variable [`POSTGRES_ENABLED`](../../../../topics/autodevops/#environment-variables) to `false`.
+Alternatively, disable Postgres by setting the project variable
+[`POSTGRES_ENABLED`](../../../../topics/autodevops/#environment-variables) to `false`.
## Deploy the app to EKS
-With RBAC disabled and services deployed, [Auto DevOps](https://docs.gitlab.com/ee/topics/autodevops/) can now be leveraged to build, test, and deploy the app. To enable, click on `Settings` in the left sidebar, then `CI/CD`. You will see a section for `Auto DevOps`, expand it. Click on the radio button to `Enable Auto DevOps`.
+With RBAC disabled and services deployed,
+[Auto DevOps](../../../../topics/autodevops/index.md) can now be leveraged
+to build, test, and deploy the app.
-If a wildcard DNS entry was created resolving to the Load Balancer, enter it in the `domain` field. Otherwise, the deployed app will not be externally available outside of the cluster. To save, click `Save changes`.
+[Enable Auto DevOps](../../../../topics/autodevops/index.md##enablingdisabling-auto-devops-at-the-project-level)
+if not already enabled. If a wildcard DNS entry was created resolving to the
+Load Balancer, enter it in the `domain` field under the Auto DevOps settings.
+Otherwise, the deployed app will not be externally available outside of the cluster.
![Deploy Pipeline](img/pipeline.png)
-A new pipeline will automatically be created, which will begin to build, test, and deploy the app.
+A new pipeline will automatically be created, which will begin to build, test,
+and deploy the app.
-After the pipeline has finished, your app will be running in EKS and available to users. Click on `CI/CD` tab in the left navigation bar, and choose `Environments`.
+After the pipeline has finished, your app will be running in EKS and available
+to users. Click on **CI/CD > Environments**.
![Deployed Environment](img/environment.png)
-You will see a list of the environments and their deploy status, as well as options to browse to the app, view monitoring metrics, and even access a shell on the running pod.
+You will see a list of the environments and their deploy status, as well as
+options to browse to the app, view monitoring metrics, and even access a shell
+on the running pod.
+
+## Learn more
-To learn more about Auto DevOps, review our [documentation](../../../../topics/autodevops/).
+To learn more on automatically deploying your applications,
+read about [Auto DevOps](../../../../topics/autodevops/index.md).
diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md
index 3fbd4c21eab..c8003d00e73 100644
--- a/doc/user/project/clusters/index.md
+++ b/doc/user/project/clusters/index.md
@@ -49,8 +49,8 @@ new Kubernetes cluster to your project:
NOTE: **Note:**
You need Maintainer [permissions] and above to access the Kubernetes page.
-1. Click on **Add Kubernetes cluster**.
-1. Click on **Create with Google Kubernetes Engine**.
+1. Click **Add Kubernetes cluster**.
+1. Click **Create with Google Kubernetes Engine**.
1. Connect your Google account if you haven't done already by clicking the
**Sign in with Google** button.
1. From there on, choose your cluster's settings:
@@ -78,8 +78,8 @@ To add an existing Kubernetes cluster to your project:
NOTE: **Note:**
You need Maintainer [permissions] and above to access the Kubernetes page.
-1. Click on **Add Kubernetes cluster**.
-1. Click on **Add an existing Kubernetes cluster** and fill in the details:
+1. Click **Add Kubernetes cluster**.
+1. Click **Add an existing Kubernetes cluster** and fill in the details:
- **Kubernetes cluster name** (required) - The name you wish to give the cluster.
- **Environment scope** (required)- The
[associated environment](#setting-the-environment-scope) to this cluster.
@@ -228,7 +228,11 @@ twice, which can lead to confusion during deployments.
| [Prometheus](https://prometheus.io/docs/introduction/overview/) | 10.4+ | Prometheus is an open-source monitoring and alerting system useful to supervise your deployed applications. | [stable/prometheus](https://github.com/helm/charts/tree/master/stable/prometheus) |
| [GitLab Runner](https://docs.gitlab.com/runner/) | 10.6+ | GitLab Runner is the open source project that is used to run your jobs and send the results back to GitLab. It is used in conjunction with [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/), the open-source continuous integration service included with GitLab that coordinates the jobs. When installing the GitLab Runner via the applications, it will run in **privileged mode** by default. Make sure you read the [security implications](#security-implications) before doing so. | [runner/gitlab-runner](https://gitlab.com/charts/gitlab-runner) |
| [JupyterHub](http://jupyter.org/) | 11.0+ | [JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) is a multi-user service for managing notebooks across a team. [Jupyter Notebooks](https://jupyter-notebook.readthedocs.io/en/latest/) provide a web-based interactive programming environment used for data analysis, visualization, and machine learning. We use [this](https://gitlab.com/gitlab-org/jupyterhub-user-image/blob/master/Dockerfile) custom Jupyter image that installs additional useful packages on top of the base Jupyter. You will also see ready-to-use DevOps Runbooks built with Nurtch's [Rubix library](https://github.com/amit1rrr/rubix). More information on creating executable runbooks can be found at [Nurtch Documentation](http://docs.nurtch.com/en/latest). **Note**: Authentication will be enabled for any user of the GitLab server via OAuth2. HTTPS will be supported in a future release. | [jupyter/jupyterhub](https://jupyterhub.github.io/helm-chart/) |
-| [Knative](https://cloud.google.com/knative) | 0.1.2 | Knative provides a platform to create, deploy, and manage serverless workloads from a Kubernetes cluster. It is used in conjunction with, and includes [Istio](https://istio.io) to provide an external IP address for all programs hosted by Knative. You will be prompted to enter a wildcard domain where your applications will be exposed. Configure your DNS server to use the external IP address for that domain. For any application created and installed, they will be accessible as <program_name>.<kubernetes_namespace>.<domain_name>. **Note**: This will require your kubernetes cluster to have RBAC enabled. | [knative/knative](https://storage.googleapis.com/triggermesh-charts)
+| [Knative](https://cloud.google.com/knative) | 0.1.2 | Knative provides a platform to create, deploy, and manage serverless workloads from a Kubernetes cluster. It is used in conjunction with, and includes [Istio](https://istio.io) to provide an external IP address for all programs hosted by Knative. You will be prompted to enter a wildcard domain where your applications will be exposed. Configure your DNS server to use the external IP address for that domain. For any application created and installed, they will be accessible as `<program_name>.<kubernetes_namespace>.<domain_name>`. **Note**: This will require your kubernetes cluster to have RBAC enabled. | [knative/knative](https://storage.googleapis.com/triggermesh-charts)
+
+NOTE: **Note:**
+As of GitLab 11.6 Helm Tiller will be upgraded to the latest version supported
+by GitLab before installing any of the above applications.
## Getting the external IP address
@@ -255,10 +259,10 @@ your ingress application in which case you should manually determine it.
### Manually determining the IP address
-If the cluster is on GKE, click on the **Google Kubernetes Engine** link in the
+If the cluster is on GKE, click the **Google Kubernetes Engine** link in the
**Advanced settings**, or go directly to the
[Google Kubernetes Engine dashboard](https://console.cloud.google.com/kubernetes/)
-and select the proper project and cluster. Then click on **Connect** and execute
+and select the proper project and cluster. Then click **Connect** and execute
the `gcloud` command in a local terminal or using the **Cloud Shell**.
If the cluster is not on GKE, follow the specific instructions for your
@@ -272,7 +276,8 @@ kubectl get svc --namespace=gitlab-managed-apps ingress-nginx-ingress-controller
```
NOTE: **Note:**
-For Istio/Knative, the command will be different:
+For Istio/Knative, use the following command:
+
```bash
kubectl get svc --namespace=istio-system knative-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip} '
```
@@ -284,6 +289,7 @@ kubectl get svc --all-namespaces -o jsonpath='{range.items[?(@.status.loadBalanc
```
> **Note**: Some Kubernetes clusters return a hostname instead, like [Amazon EKS](https://aws.amazon.com/eks/). For these platforms, run:
+
> ```bash
> kubectl get service ingress-nginx-ingress-controller -n gitlab-managed-apps -o jsonpath="{.status.loadBalancer.ingress[0].hostname}".
> ```
@@ -300,7 +306,7 @@ your apps will not be able to be reached, and you'd have to change the DNS
record again. In order to avoid that, you should change it into a static
reserved IP.
-[Read how to promote an ephemeral external IP address in GKE.](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address#promote_ephemeral_ip)
+Read how to [promote an ephemeral external IP address in GKE](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address#promote_ephemeral_ip).
### Pointing your DNS at the cluster IP
@@ -406,7 +412,7 @@ service account of the cluster integration.
After you have successfully added your cluster information, you can enable the
Kubernetes cluster integration:
-1. Click the "Enabled/Disabled" switch
+1. Click the **Enabled/Disabled** switch
1. Hit **Save** for the changes to take effect
You can now start using your Kubernetes cluster for your deployments.
@@ -423,7 +429,7 @@ When you remove a cluster, you only remove its relation to GitLab, not the
cluster itself. To remove the cluster, you can do so by visiting the GKE
dashboard or using `kubectl`.
-To remove the Kubernetes cluster integration from your project, simply click on the
+To remove the Kubernetes cluster integration from your project, simply click the
**Remove integration** button. You will then be able to follow the procedure
and add a Kubernetes cluster again.
@@ -486,7 +492,13 @@ the deployment variables above, ensuring any pods you create are labelled with
## Read more
-- [Connecting and deploying to an Amazon EKS cluster](eks_and_gitlab/index.md)
+### Integrating Amazon EKS cluster with GitLab
+
+- Learn how to [connect and deploy to an Amazon EKS cluster](eks_and_gitlab/index.md).
+
+### Serverless
+
+- [Run serverless workloads on Kubernetes with Knative.](serverless/index.md)
[permissions]: ../../permissions.md
[ee]: https://about.gitlab.com/pricing/
diff --git a/doc/user/project/clusters/serverless/img/deploy-stage.png b/doc/user/project/clusters/serverless/img/deploy-stage.png
new file mode 100644
index 00000000000..dc2f8af9c63
--- /dev/null
+++ b/doc/user/project/clusters/serverless/img/deploy-stage.png
Binary files differ
diff --git a/doc/user/project/clusters/serverless/img/dns-entry.png b/doc/user/project/clusters/serverless/img/dns-entry.png
new file mode 100644
index 00000000000..2e7655c6041
--- /dev/null
+++ b/doc/user/project/clusters/serverless/img/dns-entry.png
Binary files differ
diff --git a/doc/user/project/clusters/serverless/img/install-knative.png b/doc/user/project/clusters/serverless/img/install-knative.png
new file mode 100644
index 00000000000..dd576a9df35
--- /dev/null
+++ b/doc/user/project/clusters/serverless/img/install-knative.png
Binary files differ
diff --git a/doc/user/project/clusters/serverless/img/knative-app.png b/doc/user/project/clusters/serverless/img/knative-app.png
new file mode 100644
index 00000000000..54301e1786f
--- /dev/null
+++ b/doc/user/project/clusters/serverless/img/knative-app.png
Binary files differ
diff --git a/doc/user/project/clusters/serverless/index.md b/doc/user/project/clusters/serverless/index.md
new file mode 100644
index 00000000000..bdbc4f7f09d
--- /dev/null
+++ b/doc/user/project/clusters/serverless/index.md
@@ -0,0 +1,137 @@
+# Serverless
+
+> Introduced in GitLab 11.5.
+
+Run serverless workloads on Kubernetes using [Knative](https://cloud.google.com/knative/).
+
+## Overview
+
+Knative extends Kubernetes to provide a set of middleware components that are useful to build modern, source-centric, container-based applications. Knative brings some significant benefits out of the box through its main components:
+
+- [Build:](https://github.com/knative/build) Source-to-container build orchestration
+- [Eventing:](https://github.com/knative/eventing) Management and delivery of events
+- [Serving:](https://github.com/knative/serving) Request-driven compute that can scale to zero
+
+For more information on Knative, visit the [Knative docs repo](https://github.com/knative/docs).
+
+## Requirements
+
+To run Knative on Gitlab, you will need:
+
+1. **Kubernetes:** An RBAC-enabled Kubernetes cluster is required to deploy Knative.
+ The simplest way to get started is to add a cluster using [GitLab's GKE integration](https://docs.gitlab.com/ee/user/project/clusters/#adding-and-creating-a-new-gke-cluster-via-gitlab).
+ GitLab recommends
+1. **Helm Tiller:** Helm is a package manager for Kubernetes and is required to install
+ all the other applications.
+1. **Domain Name:** Knative will provide its own load balancer using Istio. It will provide an
+ external IP address for all the applications served by Knative. You will be prompted to enter a
+ wildcard domain where your applications will be served. Configure your DNS server to use the
+ external IP address for that domain.
+1. **Serverless `gitlab-ci.yml` Template:** GitLab uses [Kaniko](https://github.com/GoogleContainerTools/kaniko)
+ to build the application and the [TriggerMesh CLI](https://github.com/triggermesh/tm), to simplify the
+ deployment of knative services and functions.
+
+ Add the following `.gitlab-ci.yml` to the root of your repository (you may skip this step if using the sample
+ [Knative Ruby App](https://gitlab.com/knative-examples/knative-ruby-app) mentioned below).
+
+ ```yaml
+ stages:
+ - build
+ - deploy
+
+ build:
+ stage: build
+ image:
+ name: gcr.io/kaniko-project/executor:debug
+ entrypoint: [""]
+ only:
+ - master
+ script:
+ - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
+ - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE
+
+ deploy:
+ stage: deploy
+ image: gcr.io/triggermesh/tm@sha256:e3ee74db94d215bd297738d93577481f3e4db38013326c90d57f873df7ab41d5
+ only:
+ - master
+ environment: production
+ script:
+ - echo "$CI_REGISTRY_IMAGE"
+ - tm -n "$KUBE_NAMESPACE" --config "$KUBECONFIG" deploy service "$CI_PROJECT_NAME" --from-image "$CI_REGISTRY_IMAGE" --wait
+ ```
+
+1. **Dockerfile:** Knative requires a Dockerfile in order to build your application. It should be included
+ at the root of your project's repo and expose port 8080.
+
+## Installing Knative via GitLab's Kubernetes integration
+
+NOTE: **Note:**
+Minimum recommended cluster size to run Knative is 3-nodes, 6 vCPUs, and 22.50 GB memory. RBAC must be enabled.
+
+You may download the sample [Knative Ruby App](https://gitlab.com/knative-examples/knative-ruby-app) to get started.
+
+1. [Add a Kubernetes cluster](https://docs.gitlab.com/ce/user/project/clusters/) and install Helm.
+
+1. Once Helm has been successfully installed, on the Knative app section, enter the domain to be used with
+ your application and click "Install".
+
+ ![install-knative](img/install-knative.png)
+
+1. After the Knative installation has finished, retrieve the Istio Ingress IP address by running the following command:
+
+ ```bash
+ kubectl get svc --namespace=istio-system knative-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip} '
+ ```
+
+ Output:
+
+ ```bash
+ 35.161.143.124 my-machine-name:~ my-user$
+ ```
+
+1. The ingress is now available at this address and will route incoming requests to the proper service based on the DNS
+ name in the request. To support this, a wildcard DNS A record should be created for the desired domain name. For example,
+ if your Knative base domain is `knative.example.com` then you need to create an A record with domain `*.knative.example.com`
+ pointing the ip address of the ingress.
+
+ ![dns entry](img/dns-entry.png)
+
+## Deploy the application with Knative
+
+With all the pieces in place, you can simply create a new CI pipeline to deploy the Knative application. Navigate to
+**CI/CD >> Pipelines** and click the **Run Pipeline** button at the upper-right part of the screen. Then, on the
+Pipelines page, click **Create pipeline**.
+
+## Obtain the URL for the Knative deployment
+
+Once all the stages of the pipeline finish, click the **deploy** stage.
+
+![deploy stage](img/deploy-stage.png)
+
+The output will look like this:
+
+```bash
+Running with gitlab-runner 11.5.0~beta.844.g96d88322 (96d88322)
+ on docker-auto-scale 72989761
+Using Docker executor with image gcr.io/triggermesh/tm@sha256:e3ee74db94d215bd297738d93577481f3e4db38013326c90d57f873df7ab41d5 ...
+Pulling docker image gcr.io/triggermesh/tm@sha256:e3ee74db94d215bd297738d93577481f3e4db38013326c90d57f873df7ab41d5 ...
+Using docker image sha256:6b3f6590a9b30bd7aafb9573f047d930c70066e43955b4beb18a1eee175f6de1 for gcr.io/triggermesh/tm@sha256:e3ee74db94d215bd297738d93577481f3e4db38013326c90d57f873df7ab41d5 ...
+Running on runner-72989761-project-4342902-concurrent-0 via runner-72989761-stg-srm-1541795796-27929c96...
+Cloning repository...
+Cloning into '/builds/danielgruesso/knative'...
+Checking out 8671ad20 as master...
+Skipping Git submodules setup
+$ echo "$CI_REGISTRY_IMAGE"
+registry.staging.gitlab.com/danielgruesso/knative
+$ tm -n "$KUBE_NAMESPACE" --config "$KUBECONFIG" deploy service "$CI_PROJECT_NAME" --from-image "$CI_REGISTRY_IMAGE" --wait
+Deployment started. Run "tm -n knative-4342902 describe service knative" to see the details
+Waiting for ready state.......
+Service domain: knative.knative-4342902.knative.info
+Job succeeded
+```
+
+The second to last line, labeled **Service domain** contains the URL for the deployment. Copy and paste the domain into your
+browser to see the app live.
+
+![knative app](img/knative-app.png) \ No newline at end of file
diff --git a/doc/user/project/merge_requests/img/comment-on-any-diff-line.png b/doc/user/project/merge_requests/img/comment-on-any-diff-line.png
new file mode 100644
index 00000000000..856ede41527
--- /dev/null
+++ b/doc/user/project/merge_requests/img/comment-on-any-diff-line.png
Binary files differ
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index 6de2ab07fc4..f2f2497f0be 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -141,6 +141,15 @@ you hide discussions that are no longer relevant.
[Read more about resolving discussion comments in merge requests reviews.](../../discussions/index.md)
+## Commenting on any file line in merge requests
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/13950) in GitLab 11.5.
+
+GitLab provides a way of leaving comments in any part of the file being changed
+in a Merge Request. To do so, click the **...** button in the gutter of the Merge Request diff UI to expand the diff lines and leave a comment, just as you would for a changed line.
+
+![Comment on any diff file line](img/comment-on-any-diff-line.png)
+
## Resolve conflicts
When a merge request has conflicts, GitLab may provide the option to resolve
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 084d1161633..d6754372816 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -18,6 +18,8 @@ Adjust your project's name, description, avatar, [default branch](../repository/
![general project settings](img/general_settings.png)
+The project description also partially supports [standard markdown](../../markdown.md#standard-markdown). You can use [emphasis](../../markdown.md#emphasis), [links](../../markdown.md#links), and [line-breaks](../../markdown.md#line-breaks) to add more context to the project description.
+
### Sharing and permissions
Set up your project's access, [visibility](../../../public_access/public_access.md), and enable [Container Registry](../container_registry.md) for your projects:
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index 3b8f3fedccf..337b92a6183 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -207,7 +207,7 @@ module API
end
desc 'Revert a commit in a branch' do
- detail 'This feature was introduced in GitLab 11.6'
+ detail 'This feature was introduced in GitLab 11.5'
success Entities::Commit
end
params do
diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb
index 1cfb982c04b..cba1e3a6684 100644
--- a/lib/api/pipelines.rb
+++ b/lib/api/pipelines.rb
@@ -81,6 +81,21 @@ module API
present pipeline, with: Entities::Pipeline
end
+ desc 'Deletes a pipeline' do
+ detail 'This feature was introduced in GitLab 11.6'
+ http_codes [[204, 'Pipeline was deleted'], [403, 'Forbidden']]
+ end
+ params do
+ requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
+ end
+ delete ':id/pipelines/:pipeline_id' do
+ authorize! :destroy_pipeline, pipeline
+
+ destroy_conditionally!(pipeline) do
+ ::Ci::DestroyPipelineService.new(user_project, current_user).execute(pipeline)
+ end
+ end
+
desc 'Retry builds in the pipeline' do
detail 'This feature was introduced in GitLab 8.11.'
success Entities::Pipeline
diff --git a/lib/gitlab/checks/commit_check.rb b/lib/gitlab/checks/commit_check.rb
index 6dd74e8fb74..58267b6752f 100644
--- a/lib/gitlab/checks/commit_check.rb
+++ b/lib/gitlab/checks/commit_check.rb
@@ -10,8 +10,8 @@ module Gitlab
def initialize(project, user, newrev, oldrev)
@project = project
@user = user
- @newrev = user
- @oldrev = user
+ @newrev = newrev
+ @oldrev = oldrev
@file_paths = []
end
diff --git a/lib/gitlab/ci/build/policy/changes.rb b/lib/gitlab/ci/build/policy/changes.rb
index 7bf51519752..1663c875426 100644
--- a/lib/gitlab/ci/build/policy/changes.rb
+++ b/lib/gitlab/ci/build/policy/changes.rb
@@ -14,7 +14,7 @@ module Gitlab
pipeline.modified_paths.any? do |path|
@globs.any? do |glob|
- File.fnmatch?(glob, path, File::FNM_PATHNAME | File::FNM_DOTMATCH)
+ File.fnmatch?(glob, path, File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB)
end
end
end
diff --git a/lib/gitlab/ci/parsers/test/junit.rb b/lib/gitlab/ci/parsers/test/junit.rb
index ed5a79d9b9b..2791730fd26 100644
--- a/lib/gitlab/ci/parsers/test/junit.rb
+++ b/lib/gitlab/ci/parsers/test/junit.rb
@@ -14,7 +14,7 @@ module Gitlab
test_case = create_test_case(test_case)
test_suite.add_test_case(test_case)
end
- rescue REXML::ParseException
+ rescue Nokogiri::XML::SyntaxError
raise JunitParserError, "XML parsing failed"
rescue
raise JunitParserError, "JUnit parsing failed"
diff --git a/lib/gitlab/file_detector.rb b/lib/gitlab/file_detector.rb
index d6338b09e3d..2770469ca9f 100644
--- a/lib/gitlab/file_detector.rb
+++ b/lib/gitlab/file_detector.rb
@@ -8,7 +8,7 @@ module Gitlab
module FileDetector
PATTERNS = {
# Project files
- readme: %r{\A(readme|index)[^/]*\z}i,
+ readme: /\A(#{Regexp.union(*Gitlab::MarkupHelper::PLAIN_FILENAMES).source})(\.(#{Regexp.union(*Gitlab::MarkupHelper::EXTENSIONS).source}))?\z/i,
changelog: %r{\A(changelog|history|changes|news)[^/]*\z}i,
license: %r{\A((un)?licen[sc]e|copying)(\.[^/]+)?\z}i,
contributing: %r{\Acontributing[^/]*\z}i,
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index d99a9f15371..8b455dc7696 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -139,7 +139,7 @@ module Gitlab
ensure
duration = Gitlab::Metrics::System.monotonic_time - start
- # Keep track, seperately, for the performance bar
+ # Keep track, separately, for the performance bar
self.query_time += duration
gitaly_controller_action_duration_seconds.observe(
current_transaction_labels.merge(gitaly_service: service.to_s, rpc: rpc.to_s),
diff --git a/lib/gitlab/http_io.rb b/lib/gitlab/http_io.rb
index 9d7763fc5ac..e768b8adb12 100644
--- a/lib/gitlab/http_io.rb
+++ b/lib/gitlab/http_io.rb
@@ -161,14 +161,14 @@ module Gitlab
##
# Note: If provider does not return content_range, then we set it as we requested
# Provider: minio
- # - When the file size is larger than requested Content-range, the Content-range is included in responces with Net::HTTPPartialContent 206
- # - When the file size is smaller than requested Content-range, the Content-range is included in responces with Net::HTTPPartialContent 206
+ # - When the file size is larger than requested Content-range, the Content-range is included in responses with Net::HTTPPartialContent 206
+ # - When the file size is smaller than requested Content-range, the Content-range is included in responses with Net::HTTPPartialContent 206
# Provider: AWS
- # - When the file size is larger than requested Content-range, the Content-range is included in responces with Net::HTTPPartialContent 206
- # - When the file size is smaller than requested Content-range, the Content-range is included in responces with Net::HTTPPartialContent 206
+ # - When the file size is larger than requested Content-range, the Content-range is included in responses with Net::HTTPPartialContent 206
+ # - When the file size is smaller than requested Content-range, the Content-range is included in responses with Net::HTTPPartialContent 206
# Provider: GCS
- # - When the file size is larger than requested Content-range, the Content-range is included in responces with Net::HTTPPartialContent 206
- # - When the file size is smaller than requested Content-range, the Content-range is included in responces with Net::HTTPOK 200
+ # - When the file size is larger than requested Content-range, the Content-range is included in responses with Net::HTTPPartialContent 206
+ # - When the file size is smaller than requested Content-range, the Content-range is included in responses with Net::HTTPOK 200
@chunk_range ||= (chunk_start...(chunk_start + @chunk.bytesize))
end
diff --git a/lib/gitlab/kubernetes/helm.rb b/lib/gitlab/kubernetes/helm.rb
index 1cd4f9e17b7..5a22b5e3364 100644
--- a/lib/gitlab/kubernetes/helm.rb
+++ b/lib/gitlab/kubernetes/helm.rb
@@ -1,7 +1,7 @@
module Gitlab
module Kubernetes
module Helm
- HELM_VERSION = '2.7.2'.freeze
+ HELM_VERSION = '2.11.0'.freeze
KUBECTL_VERSION = '1.11.0'.freeze
NAMESPACE = 'gitlab-managed-apps'.freeze
SERVICE_ACCOUNT = 'tiller'.freeze
diff --git a/lib/gitlab/kubernetes/helm/client_command.rb b/lib/gitlab/kubernetes/helm/client_command.rb
new file mode 100644
index 00000000000..72bafc07bf0
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/client_command.rb
@@ -0,0 +1,26 @@
+module Gitlab
+ module Kubernetes
+ module Helm
+ module ClientCommand
+ def init_command
+ # Here we are always upgrading to the latest version of Tiller when
+ # installing an app. We ensure the helm version stored in the
+ # database is correct by also updating this after transition to
+ # :installed,:updated in Clusters::Concerns::ApplicationStatus
+ 'helm init --upgrade'
+ end
+
+ def wait_for_tiller_command
+ # This is necessary to give Tiller time to restart after upgrade.
+ # Ideally we'd be able to use --wait but cannot because of
+ # https://github.com/helm/helm/issues/4855
+ 'for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done'
+ end
+
+ def repository_command
+ ['helm', 'repo', 'add', name, repository].shelljoin if repository
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/install_command.rb b/lib/gitlab/kubernetes/helm/install_command.rb
index ff1c1657b98..52700b5dc09 100644
--- a/lib/gitlab/kubernetes/helm/install_command.rb
+++ b/lib/gitlab/kubernetes/helm/install_command.rb
@@ -3,6 +3,7 @@ module Gitlab
module Helm
class InstallCommand
include BaseCommand
+ include ClientCommand
attr_reader :name, :files, :chart, :version, :repository, :preinstall, :postinstall
@@ -20,6 +21,7 @@ module Gitlab
def generate_script
super + [
init_command,
+ wait_for_tiller_command,
repository_command,
repository_update_command,
preinstall_command,
@@ -34,14 +36,6 @@ module Gitlab
private
- def init_command
- 'helm init --client-only'
- end
-
- def repository_command
- ['helm', 'repo', 'add', name, repository].shelljoin if repository
- end
-
def repository_update_command
'helm repo update' if repository
end
diff --git a/lib/gitlab/kubernetes/helm/upgrade_command.rb b/lib/gitlab/kubernetes/helm/upgrade_command.rb
index b36315f7a82..9daffc138b5 100644
--- a/lib/gitlab/kubernetes/helm/upgrade_command.rb
+++ b/lib/gitlab/kubernetes/helm/upgrade_command.rb
@@ -5,6 +5,7 @@ module Gitlab
module Helm
class UpgradeCommand
include BaseCommand
+ include ClientCommand
attr_reader :name, :chart, :version, :repository, :files
@@ -20,6 +21,7 @@ module Gitlab
def generate_script
super + [
init_command,
+ wait_for_tiller_command,
repository_command,
script_command
].compact.join("\n")
@@ -35,14 +37,6 @@ module Gitlab
private
- def init_command
- 'helm init --client-only'
- end
-
- def repository_command
- "helm repo add #{name} #{repository}" if repository
- end
-
def script_command
upgrade_flags = "#{optional_version_flag}#{optional_tls_flags}" \
" --reset-values" \
diff --git a/lib/gitlab/view/presenter/base.rb b/lib/gitlab/view/presenter/base.rb
index 36162faa1eb..c3fd6d317aa 100644
--- a/lib/gitlab/view/presenter/base.rb
+++ b/lib/gitlab/view/presenter/base.rb
@@ -11,8 +11,8 @@ module Gitlab
attr_reader :subject
- def can?(user, action, overriden_subject = nil)
- super(user, action, overriden_subject || subject)
+ def can?(user, action, overridden_subject = nil)
+ super(user, action, overridden_subject || subject)
end
# delegate all #can? queries to the subject
diff --git a/locale/ar_SA/gitlab.po b/locale/ar_SA/gitlab.po
index 5a94d7fc39d..4a2b56f2806 100644
--- a/locale/ar_SA/gitlab.po
+++ b/locale/ar_SA/gitlab.po
@@ -681,7 +681,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po
index dd911bd5639..6c6eeeb6580 100644
--- a/locale/bg/gitlab.po
+++ b/locale/bg/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/ca_ES/gitlab.po b/locale/ca_ES/gitlab.po
index 30c99c93d6c..a957023bb25 100644
--- a/locale/ca_ES/gitlab.po
+++ b/locale/ca_ES/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/cs_CZ/gitlab.po b/locale/cs_CZ/gitlab.po
index 59f6687d75e..9801999299f 100644
--- a/locale/cs_CZ/gitlab.po
+++ b/locale/cs_CZ/gitlab.po
@@ -621,7 +621,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/da_DK/gitlab.po b/locale/da_DK/gitlab.po
index 0488747cca1..9c7b37f7f18 100644
--- a/locale/da_DK/gitlab.po
+++ b/locale/da_DK/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po
index 40f9365ef7d..07568765abb 100644
--- a/locale/de/gitlab.po
+++ b/locale/de/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po
index 3723844cf84..84ef902d5e1 100644
--- a/locale/eo/gitlab.po
+++ b/locale/eo/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po
index 3e85f7438a4..32e495695c6 100644
--- a/locale/es/gitlab.po
+++ b/locale/es/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/et_EE/gitlab.po b/locale/et_EE/gitlab.po
index 4d1cdfd98b4..bc6b3b67d42 100644
--- a/locale/et_EE/gitlab.po
+++ b/locale/et_EE/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/fil_PH/gitlab.po b/locale/fil_PH/gitlab.po
index 547b7859926..ecbf47aa928 100644
--- a/locale/fil_PH/gitlab.po
+++ b/locale/fil_PH/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/fr/gitlab.po b/locale/fr/gitlab.po
index ac509d27241..6e89ec73142 100644
--- a/locale/fr/gitlab.po
+++ b/locale/fr/gitlab.po
@@ -561,7 +561,7 @@ msgstr "Une erreur est survenue lors de la création de la nouvelle branche."
msgid "An error occured whilst fetching the job trace."
msgstr "Une erreur est survenue pendant le rapatriement de la trace de la tâche."
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr "Une erreur est survenue lors du rapatriement de dernier pipeline."
msgid "An error occured whilst loading all the files."
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d3e1a51370e..f18821adb5f 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -501,7 +501,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/gl_ES/gitlab.po b/locale/gl_ES/gitlab.po
index 1b899318067..5e2dbce1104 100644
--- a/locale/gl_ES/gitlab.po
+++ b/locale/gl_ES/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/he_IL/gitlab.po b/locale/he_IL/gitlab.po
index 78b1d69f02f..9aadf885770 100644
--- a/locale/he_IL/gitlab.po
+++ b/locale/he_IL/gitlab.po
@@ -621,7 +621,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/id_ID/gitlab.po b/locale/id_ID/gitlab.po
index 54fd6c61821..641886e65b0 100644
--- a/locale/id_ID/gitlab.po
+++ b/locale/id_ID/gitlab.po
@@ -531,7 +531,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po
index bccbd3d1f13..3b43d563dc5 100644
--- a/locale/it/gitlab.po
+++ b/locale/it/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/ja/gitlab.po b/locale/ja/gitlab.po
index d9530519e9c..a254bfba027 100644
--- a/locale/ja/gitlab.po
+++ b/locale/ja/gitlab.po
@@ -531,7 +531,7 @@ msgstr "新しいブランチの作成中にエラーが発生しました。"
msgid "An error occured whilst fetching the job trace."
msgstr "ジョブトレースの取得中にエラーが発生しました。"
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr "最新のパイプラインの取得中にエラーが発生しました。"
msgid "An error occured whilst loading all the files."
diff --git a/locale/ko/gitlab.po b/locale/ko/gitlab.po
index 82a770db549..daced0494cb 100644
--- a/locale/ko/gitlab.po
+++ b/locale/ko/gitlab.po
@@ -531,7 +531,7 @@ msgstr "새 브랜치를 만드는 동안 오류가 발생했습니다."
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/mn_MN/gitlab.po b/locale/mn_MN/gitlab.po
index 29b50db6d9d..cf2c7224171 100644
--- a/locale/mn_MN/gitlab.po
+++ b/locale/mn_MN/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/nb_NO/gitlab.po b/locale/nb_NO/gitlab.po
index e53838f371e..df490378e9c 100644
--- a/locale/nb_NO/gitlab.po
+++ b/locale/nb_NO/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/nl_NL/gitlab.po b/locale/nl_NL/gitlab.po
index 1f654724709..8f9c3161a26 100644
--- a/locale/nl_NL/gitlab.po
+++ b/locale/nl_NL/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/pl_PL/gitlab.po b/locale/pl_PL/gitlab.po
index d3e954a2ab1..ebe5ee77d71 100644
--- a/locale/pl_PL/gitlab.po
+++ b/locale/pl_PL/gitlab.po
@@ -621,7 +621,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po
index ae4e6df4902..39aa1256e4b 100644
--- a/locale/pt_BR/gitlab.po
+++ b/locale/pt_BR/gitlab.po
@@ -561,7 +561,7 @@ msgstr "Um erro ocorreu ao criar o novo branch."
msgid "An error occured whilst fetching the job trace."
msgstr "Ocorreu um erro ao carregar o rastro da tarefa."
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr "Ocorreu um erro ao carregar o último pipeline."
msgid "An error occured whilst loading all the files."
diff --git a/locale/ro_RO/gitlab.po b/locale/ro_RO/gitlab.po
index 205d65d48ea..a6b70d486fb 100644
--- a/locale/ro_RO/gitlab.po
+++ b/locale/ro_RO/gitlab.po
@@ -591,7 +591,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/ru/gitlab.po b/locale/ru/gitlab.po
index 5075f97bcee..739f96cba9a 100644
--- a/locale/ru/gitlab.po
+++ b/locale/ru/gitlab.po
@@ -621,7 +621,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/sq_AL/gitlab.po b/locale/sq_AL/gitlab.po
index 34281bbc387..75df8a29e6b 100644
--- a/locale/sq_AL/gitlab.po
+++ b/locale/sq_AL/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/tr_TR/gitlab.po b/locale/tr_TR/gitlab.po
index 14e2244f06e..1a8d2faf307 100644
--- a/locale/tr_TR/gitlab.po
+++ b/locale/tr_TR/gitlab.po
@@ -561,7 +561,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po
index 992a32dad39..30f1b5769d6 100644
--- a/locale/uk/gitlab.po
+++ b/locale/uk/gitlab.po
@@ -621,7 +621,7 @@ msgstr "Помилка при створенні нової гілки."
msgid "An error occured whilst fetching the job trace."
msgstr "Трапилася помилка при отриманні логу завдання."
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr "Трапилася помилка при отриманні даних останнього конвеєра."
msgid "An error occured whilst loading all the files."
diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po
index 808cea98bd1..19fa17eaff1 100644
--- a/locale/zh_CN/gitlab.po
+++ b/locale/zh_CN/gitlab.po
@@ -531,7 +531,7 @@ msgstr "创建分支时发生错误。"
msgid "An error occured whilst fetching the job trace."
msgstr "获取作业日志时发生错误。"
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr "获取流水线时发生错误。"
msgid "An error occured whilst loading all the files."
diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po
index 86647446724..6987f307dbb 100644
--- a/locale/zh_HK/gitlab.po
+++ b/locale/zh_HK/gitlab.po
@@ -531,7 +531,7 @@ msgstr ""
msgid "An error occured whilst fetching the job trace."
msgstr ""
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr ""
msgid "An error occured whilst loading all the files."
diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po
index 5dc9bcb4b2f..4e0b07e717f 100644
--- a/locale/zh_TW/gitlab.po
+++ b/locale/zh_TW/gitlab.po
@@ -531,7 +531,7 @@ msgstr "創建新分支時發生錯誤。"
msgid "An error occured whilst fetching the job trace."
msgstr "取得工作追蹤資訊時發生錯誤"
-msgid "An error occured whilst fetching the latest pipline."
+msgid "An error occured whilst fetching the latest pipeline."
msgstr "取得最新流水線時發生錯誤"
msgid "An error occured whilst loading all the files."
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 898f3863008..d334a2ff566 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -49,7 +49,7 @@ describe RegistrationsController do
end
it 'displays an error when the reCAPTCHA is not solved' do
- # Without this, `verify_recaptcha` arbitraily returns true in test env
+ # Without this, `verify_recaptcha` arbitrarily returns true in test env
Recaptcha.configuration.skip_verify_env.delete('test')
post(:create, user_params)
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 8e25b61e2f1..c691b3f478b 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -89,7 +89,7 @@ describe SessionsController do
end
it 'displays an error when the reCAPTCHA is not solved' do
- # Without this, `verify_recaptcha` arbitraily returns true in test env
+ # Without this, `verify_recaptcha` arbitrarily returns true in test env
Recaptcha.configuration.skip_verify_env.delete('test')
counter = double(:counter)
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
new file mode 100644
index 00000000000..e8584846b56
--- /dev/null
+++ b/spec/db/schema_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Database schema' do
+ let(:connection) { ActiveRecord::Base.connection }
+ let(:tables) { connection.tables }
+
+ # Use if you are certain that this column should not have a foreign key
+ IGNORED_FK_COLUMNS = {
+ abuse_reports: %w[reporter_id user_id],
+ application_settings: %w[performance_bar_allowed_group_id],
+ audit_events: %w[author_id entity_id],
+ award_emoji: %w[awardable_id user_id],
+ chat_names: %w[chat_id service_id team_id user_id],
+ chat_teams: %w[team_id],
+ ci_builds: %w[erased_by_id runner_id trigger_request_id user_id],
+ ci_pipelines: %w[user_id],
+ ci_runner_projects: %w[runner_id],
+ ci_trigger_requests: %w[commit_id],
+ cluster_providers_gcp: %w[gcp_project_id operation_id],
+ deploy_keys_projects: %w[deploy_key_id],
+ deployments: %w[deployable_id environment_id user_id],
+ emails: %w[user_id],
+ events: %w[target_id],
+ forked_project_links: %w[forked_from_project_id],
+ identities: %w[user_id],
+ issues: %w[last_edited_by_id],
+ keys: %w[user_id],
+ label_links: %w[target_id],
+ lfs_objects_projects: %w[lfs_object_id project_id],
+ members: %w[source_id created_by_id],
+ merge_requests: %w[last_edited_by_id],
+ namespaces: %w[owner_id parent_id],
+ notes: %w[author_id commit_id noteable_id updated_by_id resolved_by_id discussion_id],
+ notification_settings: %w[source_id],
+ oauth_access_grants: %w[resource_owner_id application_id],
+ oauth_access_tokens: %w[resource_owner_id application_id],
+ oauth_applications: %w[owner_id],
+ project_group_links: %w[group_id],
+ project_statistics: %w[namespace_id],
+ projects: %w[creator_id namespace_id ci_id],
+ redirect_routes: %w[source_id],
+ repository_languages: %w[programming_language_id],
+ routes: %w[source_id],
+ sent_notifications: %w[project_id noteable_id recipient_id commit_id in_reply_to_discussion_id],
+ snippets: %w[author_id],
+ spam_logs: %w[user_id],
+ subscriptions: %w[user_id subscribable_id],
+ taggings: %w[tag_id taggable_id tagger_id],
+ timelogs: %w[user_id],
+ todos: %w[target_id commit_id],
+ uploads: %w[model_id],
+ user_agent_details: %w[subject_id],
+ users: %w[color_scheme_id created_by_id theme_id],
+ users_star_projects: %w[user_id],
+ web_hooks: %w[service_id]
+ }.with_indifferent_access.freeze
+
+ context 'for table' do
+ ActiveRecord::Base.connection.tables.sort.each do |table|
+ describe table do
+ let(:indexes) { connection.indexes(table) }
+ let(:columns) { connection.columns(table) }
+ let(:foreign_keys) { connection.foreign_keys(table) }
+
+ context 'all foreign keys' do
+ # for index to be effective, the FK constraint has to be at first place
+ it 'are indexed' do
+ first_indexed_column = indexes.map(&:columns).map(&:first)
+ foreign_keys_columns = foreign_keys.map(&:column)
+
+ expect(first_indexed_column.uniq).to include(*foreign_keys_columns)
+ end
+ end
+
+ context 'columns ending with _id' do
+ let(:column_names) { columns.map(&:name) }
+ let(:column_names_with_id) { column_names.select { |column_name| column_name.ends_with?('_id') } }
+ let(:foreign_keys_columns) { foreign_keys.map(&:column) }
+ let(:ignored_columns) { ignored_fk_columns(table) }
+
+ it 'do have the foreign keys' do
+ expect(column_names_with_id - ignored_columns).to contain_exactly(*foreign_keys_columns)
+ end
+ end
+ end
+ end
+ end
+
+ private
+
+ def ignored_fk_columns(column)
+ IGNORED_FK_COLUMNS.fetch(column, [])
+ end
+end
diff --git a/spec/fast_spec_helper.rb b/spec/fast_spec_helper.rb
index fe475e1f7a0..0b5ab16ad71 100644
--- a/spec/fast_spec_helper.rb
+++ b/spec/fast_spec_helper.rb
@@ -9,3 +9,4 @@ require 'active_support/all'
ActiveSupport::Dependencies.autoload_paths << 'lib'
ActiveSupport::Dependencies.autoload_paths << 'ee/lib'
+ActiveSupport::XmlMini.backend = 'Nokogiri'
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index 1456a2f0375..f2e4c5779df 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -27,7 +27,7 @@ describe 'New/edit issue', :js do
before do
# Using `allow_any_instance_of`/`and_wrap_original`, `original` would
# somehow refer to the very block we defined to _wrap_ that method, instead of
- # the original method, resulting in infinite recurison when called.
+ # the original method, resulting in infinite recursion when called.
# This is likely a bug with helper modules included into dynamically generated view classes.
# To work around this, we have to hold on to and call to the original implementation manually.
original_issue_dropdown_options = FormHelper.instance_method(:issue_assignees_dropdown_options)
diff --git a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
index 3dfcbc2fcb8..297cd808460 100644
--- a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
+++ b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
@@ -55,11 +55,11 @@ describe 'User creates branch and merge request on issue page', :js do
test_branch_name_checking(input_branch_name)
test_source_checking(input_source)
- # The button inside dropdown should be disabled if any errors occured.
+ # The button inside dropdown should be disabled if any errors occurred.
expect(page).to have_button('Create branch', disabled: true)
end
- # The top level button should be disabled if any errors occured.
+ # The top level button should be disabled if any errors occurred.
expect(page).to have_button('Create branch', disabled: true)
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index a1323699969..99a7fbb63bd 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -719,7 +719,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
context 'on mobile', :js do
let(:job) { create(:ci_build, pipeline: pipeline) }
- it 'renders collpased sidebar' do
+ it 'renders collapsed sidebar' do
page.current_window.resize_to(600, 800)
visit project_job_path(project, job)
@@ -738,7 +738,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
wait_for_requests
expect(page).to have_css('.js-job-sidebar.right-sidebar-expanded')
- expect(page).not_to have_css('.js-job-sidebar.right-sidebar-collpased')
+ expect(page).not_to have_css('.js-job-sidebar.right-sidebar-collapsed')
end
end
diff --git a/spec/finders/pipelines_finder_spec.rb b/spec/finders/pipelines_finder_spec.rb
index c6e832ad69b..c2c304589c9 100644
--- a/spec/finders/pipelines_finder_spec.rb
+++ b/spec/finders/pipelines_finder_spec.rb
@@ -225,7 +225,7 @@ describe PipelinesFinder do
end
end
- context 'when the project has limited access to piplines' do
+ context 'when the project has limited access to pipelines' do
let(:project) { create(:project, :private, :repository) }
let(:current_user) { create(:user) }
let!(:pipelines) { create_list(:ci_pipeline, 2, project: project) }
diff --git a/spec/fixtures/trace/sample_trace b/spec/fixtures/trace/sample_trace
index 7bfe3f83b7b..3d8beb0dec2 100644
--- a/spec/fixtures/trace/sample_trace
+++ b/spec/fixtures/trace/sample_trace
@@ -2334,12 +2334,12 @@ Boards::Lists::MoveService
keeps position of lists when list type is closed
when list type is set to label
keeps position of lists when new position is nil
- keeps position of lists when new positon is equal to old position
- keeps position of lists when new positon is negative
- keeps position of lists when new positon is equal to number of labels lists
- keeps position of lists when new positon is greater than number of labels lists
- increments position of intermediate lists when new positon is equal to first position
- decrements position of intermediate lists when new positon is equal to last position
+ keeps position of lists when new position is equal to old position
+ keeps position of lists when new position is negative
+ keeps position of lists when new position is equal to number of labels lists
+ keeps position of lists when new position is greater than number of labels lists
+ increments position of intermediate lists when new position is equal to first position
+ decrements position of intermediate lists when new position is equal to last position
decrements position of intermediate lists when new position is greater than old position
increments position of intermediate lists when new position is lower than old position
when board parent is a group
@@ -2347,12 +2347,12 @@ Boards::Lists::MoveService
keeps position of lists when list type is closed
when list type is set to label
keeps position of lists when new position is nil
- keeps position of lists when new positon is equal to old position
- keeps position of lists when new positon is negative
- keeps position of lists when new positon is equal to number of labels lists
- keeps position of lists when new positon is greater than number of labels lists
- increments position of intermediate lists when new positon is equal to first position
- decrements position of intermediate lists when new positon is equal to last position
+ keeps position of lists when new position is equal to old position
+ keeps position of lists when new position is negative
+ keeps position of lists when new position is equal to number of labels lists
+ keeps position of lists when new position is greater than number of labels lists
+ increments position of intermediate lists when new position is equal to first position
+ decrements position of intermediate lists when new position is equal to last position
decrements position of intermediate lists when new position is greater than old position
increments position of intermediate lists when new position is lower than old position
diff --git a/spec/javascripts/diffs/store/actions_spec.js b/spec/javascripts/diffs/store/actions_spec.js
index d94a9cd1710..acd95a3dd8b 100644
--- a/spec/javascripts/diffs/store/actions_spec.js
+++ b/spec/javascripts/diffs/store/actions_spec.js
@@ -416,7 +416,7 @@ describe('DiffsStoreActions', () => {
const getters = {
getDiffFileDiscussions: jasmine.createSpy().and.returnValue([{ id: 1 }]),
diffHasAllExpandedDiscussions: jasmine.createSpy().and.returnValue(true),
- diffHasAllCollpasedDiscussions: jasmine.createSpy().and.returnValue(false),
+ diffHasAllCollapsedDiscussions: jasmine.createSpy().and.returnValue(false),
};
const dispatch = jasmine.createSpy('dispatch');
@@ -434,7 +434,7 @@ describe('DiffsStoreActions', () => {
const getters = {
getDiffFileDiscussions: jasmine.createSpy().and.returnValue([{ id: 1 }]),
diffHasAllExpandedDiscussions: jasmine.createSpy().and.returnValue(false),
- diffHasAllCollpasedDiscussions: jasmine.createSpy().and.returnValue(true),
+ diffHasAllCollapsedDiscussions: jasmine.createSpy().and.returnValue(true),
};
const dispatch = jasmine.createSpy();
@@ -452,7 +452,7 @@ describe('DiffsStoreActions', () => {
const getters = {
getDiffFileDiscussions: jasmine.createSpy().and.returnValue([{ expanded: false, id: 1 }]),
diffHasAllExpandedDiscussions: jasmine.createSpy().and.returnValue(false),
- diffHasAllCollpasedDiscussions: jasmine.createSpy().and.returnValue(false),
+ diffHasAllCollapsedDiscussions: jasmine.createSpy().and.returnValue(false),
};
const dispatch = jasmine.createSpy();
diff --git a/spec/javascripts/diffs/store/getters_spec.js b/spec/javascripts/diffs/store/getters_spec.js
index 2449bb65d07..eef95c823fb 100644
--- a/spec/javascripts/diffs/store/getters_spec.js
+++ b/spec/javascripts/diffs/store/getters_spec.js
@@ -106,13 +106,13 @@ describe('Diffs Module Getters', () => {
});
});
- describe('diffHasAllCollpasedDiscussions', () => {
+ describe('diffHasAllCollapsedDiscussions', () => {
it('returns true when all discussions are collapsed', () => {
discussionMock.diff_file.file_hash = diffFileMock.fileHash;
discussionMock.expanded = false;
expect(
- getters.diffHasAllCollpasedDiscussions(localState, {
+ getters.diffHasAllCollapsedDiscussions(localState, {
getDiffFileDiscussions: () => [discussionMock],
})(diffFileMock),
).toEqual(true);
@@ -120,7 +120,7 @@ describe('Diffs Module Getters', () => {
it('returns false when there are no discussions', () => {
expect(
- getters.diffHasAllCollpasedDiscussions(localState, {
+ getters.diffHasAllCollapsedDiscussions(localState, {
getDiffFileDiscussions: () => [],
})(diffFileMock),
).toEqual(false);
@@ -130,7 +130,7 @@ describe('Diffs Module Getters', () => {
discussionMock1.expanded = false;
expect(
- getters.diffHasAllCollpasedDiscussions(localState, {
+ getters.diffHasAllCollapsedDiscussions(localState, {
getDiffFileDiscussions: () => [discussionMock, discussionMock1],
})(diffFileMock),
).toEqual(false);
diff --git a/spec/javascripts/ide/stores/modules/pipelines/actions_spec.js b/spec/javascripts/ide/stores/modules/pipelines/actions_spec.js
index d85354c3681..c9c09ee9afe 100644
--- a/spec/javascripts/ide/stores/modules/pipelines/actions_spec.js
+++ b/spec/javascripts/ide/stores/modules/pipelines/actions_spec.js
@@ -77,7 +77,7 @@ describe('IDE pipelines actions', () => {
{
type: 'setErrorMessage',
payload: {
- text: 'An error occured whilst fetching the latest pipline.',
+ text: 'An error occured whilst fetching the latest pipeline.',
action: jasmine.any(Function),
actionText: 'Please try again',
actionPayload: null,
diff --git a/spec/lib/gitlab/ci/build/policy/changes_spec.rb b/spec/lib/gitlab/ci/build/policy/changes_spec.rb
index ab401108c84..523d00c1272 100644
--- a/spec/lib/gitlab/ci/build/policy/changes_spec.rb
+++ b/spec/lib/gitlab/ci/build/policy/changes_spec.rb
@@ -49,6 +49,12 @@ describe Gitlab::Ci::Build::Policy::Changes do
expect(policy).to be_satisfied_by(pipeline, seed)
end
+ it 'is satisfied by matching a pattern with a glob' do
+ policy = described_class.new(%w[some/**/*.{rb,txt}])
+
+ expect(policy).to be_satisfied_by(pipeline, seed)
+ end
+
it 'is not satisfied when pattern does not match path' do
policy = described_class.new(%w[some/*.rb])
@@ -61,6 +67,12 @@ describe Gitlab::Ci::Build::Policy::Changes do
expect(policy).not_to be_satisfied_by(pipeline, seed)
end
+ it 'is not satified when pattern with glob does not match' do
+ policy = described_class.new(%w[invalid/*.{md,rake}])
+
+ expect(policy).not_to be_satisfied_by(pipeline, seed)
+ end
+
context 'when pipelines does not run for a branch update' do
before do
pipeline.before_sha = Gitlab::Git::BLANK_SHA
diff --git a/spec/lib/gitlab/ci/build/policy/refs_spec.rb b/spec/lib/gitlab/ci/build/policy/refs_spec.rb
index 7211187e511..553fc0fb9bf 100644
--- a/spec/lib/gitlab/ci/build/policy/refs_spec.rb
+++ b/spec/lib/gitlab/ci/build/policy/refs_spec.rb
@@ -16,7 +16,7 @@ describe Gitlab::Ci::Build::Policy::Refs do
end
end
- context 'when maching tags' do
+ context 'when matching tags' do
context 'when pipeline runs for a tag' do
let(:pipeline) do
build_stubbed(:ci_pipeline, ref: 'feature', tag: true)
@@ -56,10 +56,10 @@ describe Gitlab::Ci::Build::Policy::Refs do
end
end
- context 'when maching a source' do
+ context 'when matching a source' do
let(:pipeline) { build_stubbed(:ci_pipeline, source: :push) }
- it 'is satisifed when provided source keyword matches' do
+ it 'is satisfied when provided source keyword matches' do
expect(described_class.new(%w[pushes]))
.to be_satisfied_by(pipeline)
end
diff --git a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb
index d48aac15f28..bd1f2c92844 100644
--- a/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/artifacts_spec.rb
@@ -8,7 +8,7 @@ describe Gitlab::Ci::Config::Entry::Artifacts do
let(:config) { { paths: %w[public/] } }
describe '#value' do
- it 'returns artifacs configuration' do
+ it 'returns artifacts configuration' do
expect(entry.value).to eq config
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/policy_spec.rb b/spec/lib/gitlab/ci/config/entry/policy_spec.rb
index bef93fe7af7..83001b7fdd8 100644
--- a/spec/lib/gitlab/ci/config/entry/policy_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/policy_spec.rb
@@ -58,7 +58,7 @@ describe Gitlab::Ci::Config::Entry::Policy do
end
context 'when using complex policy' do
- context 'when specifiying refs policy' do
+ context 'when specifying refs policy' do
let(:config) { { refs: ['master'] } }
it 'is a correct configuraton' do
diff --git a/spec/lib/gitlab/ci/config/entry/reports_spec.rb b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
index 1140bfdf6c3..38943138cbf 100644
--- a/spec/lib/gitlab/ci/config/entry/reports_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
@@ -19,7 +19,7 @@ describe Gitlab::Ci::Config::Entry::Reports do
shared_examples 'a valid entry' do |keyword, file|
describe '#value' do
- it 'returns artifacs configuration' do
+ it 'returns artifacts configuration' do
expect(entry.value).to eq({ "#{keyword}": [file] } )
end
end
diff --git a/spec/lib/gitlab/file_detector_spec.rb b/spec/lib/gitlab/file_detector_spec.rb
index edab53247e9..4ba9094b24e 100644
--- a/spec/lib/gitlab/file_detector_spec.rb
+++ b/spec/lib/gitlab/file_detector_spec.rb
@@ -15,14 +15,22 @@ describe Gitlab::FileDetector do
describe '.type_of' do
it 'returns the type of a README file' do
- %w[README readme INDEX index].each do |filename|
+ filenames = Gitlab::MarkupHelper::PLAIN_FILENAMES + Gitlab::MarkupHelper::PLAIN_FILENAMES.map(&:upcase)
+ extensions = Gitlab::MarkupHelper::EXTENSIONS + Gitlab::MarkupHelper::EXTENSIONS.map(&:upcase)
+
+ filenames.each do |filename|
expect(described_class.type_of(filename)).to eq(:readme)
- %w[.md .adoc .rst].each do |extname|
- expect(described_class.type_of(filename + extname)).to eq(:readme)
+
+ extensions.each do |extname|
+ expect(described_class.type_of("#{filename}.#{extname}")).to eq(:readme)
end
end
end
+ it 'returns nil for a README.rb file' do
+ expect(described_class.type_of('README.rb')).to be_nil
+ end
+
it 'returns nil for a README file in a directory' do
expect(described_class.type_of('foo/README.md')).to be_nil
end
diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb
index 9ef27081f98..6be35eee0fd 100644
--- a/spec/lib/gitlab/git/commit_spec.rb
+++ b/spec/lib/gitlab/git/commit_spec.rb
@@ -94,7 +94,7 @@ describe Gitlab::Git::Commit, :seed_helper do
context 'body_size less than threshold' do
let(:body_size) { 123 }
- it 'fetches commit message seperately' do
+ it 'fetches commit message separately' do
expect(described_class).to receive(:get_message).with(repository, id)
commit.safe_message
diff --git a/spec/lib/gitlab/git/tag_spec.rb b/spec/lib/gitlab/git/tag_spec.rb
index 2d9db576a6c..c5bad062c2a 100644
--- a/spec/lib/gitlab/git/tag_spec.rb
+++ b/spec/lib/gitlab/git/tag_spec.rb
@@ -68,7 +68,7 @@ describe Gitlab::Git::Tag, :seed_helper do
context 'message_size less than threshold' do
let(:message_size) { 123 }
- it 'fetches tag message seperately' do
+ it 'fetches tag message separately' do
expect(described_class).to receive(:get_message).with(repository, gitaly_tag.id)
tag.message
diff --git a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
index 2b7e3ea6def..39852b7fe29 100644
--- a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
@@ -26,7 +26,8 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm repo add app-name https://repository.example.com
helm repo update
#{helm_install_comand}
@@ -54,7 +55,8 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm repo add app-name https://repository.example.com
helm repo update
#{helm_install_command}
@@ -84,7 +86,8 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
#{helm_install_command}
EOS
end
@@ -111,7 +114,8 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm repo add app-name https://repository.example.com
helm repo update
#{helm_install_command}
@@ -134,7 +138,8 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm repo add app-name https://repository.example.com
helm repo update
#{helm_install_command}
@@ -157,7 +162,8 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm repo add app-name https://repository.example.com
helm repo update
#{helm_install_command}
@@ -182,7 +188,8 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm repo add app-name https://repository.example.com
helm repo update
#{helm_install_command}
diff --git a/spec/lib/gitlab/kubernetes/helm/pod_spec.rb b/spec/lib/gitlab/kubernetes/helm/pod_spec.rb
index c92bc92c42d..2dd3a570a1d 100644
--- a/spec/lib/gitlab/kubernetes/helm/pod_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/pod_spec.rb
@@ -30,7 +30,7 @@ describe Gitlab::Kubernetes::Helm::Pod do
it 'should generate the appropriate specifications for the container' do
container = subject.generate.spec.containers.first
expect(container.name).to eq('helm')
- expect(container.image).to eq('registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/2.7.2-kube-1.11.0')
+ expect(container.image).to eq('registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/2.11.0-kube-1.11.0')
expect(container.env.count).to eq(3)
expect(container.env.map(&:name)).to match_array([:HELM_VERSION, :TILLER_NAMESPACE, :COMMAND_SCRIPT])
expect(container.command).to match_array(["/bin/sh"])
diff --git a/spec/lib/gitlab/kubernetes/helm/upgrade_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/upgrade_command_spec.rb
index 9c9fc91ef3c..9b201dae417 100644
--- a/spec/lib/gitlab/kubernetes/helm/upgrade_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/upgrade_command_spec.rb
@@ -21,7 +21,8 @@ describe Gitlab::Kubernetes::Helm::UpgradeCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm upgrade #{application.name} #{application.chart} --tls --tls-ca-cert /data/helm/#{application.name}/config/ca.pem --tls-cert /data/helm/#{application.name}/config/cert.pem --tls-key /data/helm/#{application.name}/config/key.pem --reset-values --install --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml
EOS
end
@@ -33,7 +34,8 @@ describe Gitlab::Kubernetes::Helm::UpgradeCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm upgrade #{application.name} #{application.chart} --tls --tls-ca-cert /data/helm/#{application.name}/config/ca.pem --tls-cert /data/helm/#{application.name}/config/cert.pem --tls-key /data/helm/#{application.name}/config/key.pem --reset-values --install --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml
EOS
end
@@ -56,7 +58,8 @@ describe Gitlab::Kubernetes::Helm::UpgradeCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm repo add #{application.name} #{application.repository}
helm upgrade #{application.name} #{application.chart} --tls --tls-ca-cert /data/helm/#{application.name}/config/ca.pem --tls-cert /data/helm/#{application.name}/config/cert.pem --tls-key /data/helm/#{application.name}/config/key.pem --reset-values --install --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml
EOS
@@ -70,7 +73,8 @@ describe Gitlab::Kubernetes::Helm::UpgradeCommand do
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
- helm init --client-only
+ helm init --upgrade
+ for i in $(seq 1 30); do helm version && break; sleep 1s; echo "Retrying ($i)..."; done
helm upgrade #{application.name} #{application.chart} --reset-values --install --namespace #{namespace} -f /data/helm/#{application.name}/config/values.yaml
EOS
end
diff --git a/spec/models/clusters/applications/prometheus_spec.rb b/spec/models/clusters/applications/prometheus_spec.rb
index 86de9dc60f2..b5aa1dcece5 100644
--- a/spec/models/clusters/applications/prometheus_spec.rb
+++ b/spec/models/clusters/applications/prometheus_spec.rb
@@ -35,7 +35,7 @@ describe Clusters::Applications::Prometheus do
describe 'transition to installed' do
let(:project) { create(:project) }
- let(:cluster) { create(:cluster, projects: [project]) }
+ let(:cluster) { create(:cluster, :with_installed_helm, projects: [project]) }
let(:prometheus_service) { double('prometheus_service') }
subject { create(:clusters_applications_prometheus, :installing, cluster: cluster) }
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 131db6a5ff9..a58dc8e25e8 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -1782,7 +1782,7 @@ describe MergeRequest do
allow(subject).to receive(:head_pipeline) { nil }
end
- it { expect(subject.mergeable_ci_state?).to be_truthy }
+ it { expect(subject.mergeable_ci_state?).to be_falsey }
end
end
diff --git a/spec/policies/ci/pipeline_policy_spec.rb b/spec/policies/ci/pipeline_policy_spec.rb
index bd32faf06ef..8022f61e67d 100644
--- a/spec/policies/ci/pipeline_policy_spec.rb
+++ b/spec/policies/ci/pipeline_policy_spec.rb
@@ -74,5 +74,23 @@ describe Ci::PipelinePolicy, :models do
expect(policy).to be_allowed :update_pipeline
end
end
+
+ describe 'destroy_pipeline' do
+ let(:project) { create(:project, :public) }
+
+ context 'when user has owner access' do
+ let(:user) { project.owner }
+
+ it 'is enabled' do
+ expect(policy).to be_allowed :destroy_pipeline
+ end
+ end
+
+ context 'when user is not owner' do
+ it 'is disabled' do
+ expect(policy).not_to be_allowed :destroy_pipeline
+ end
+ end
+ end
end
end
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index f0e1992bccd..638cc9767d4 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -438,6 +438,67 @@ describe API::Pipelines do
end
end
+ describe 'DELETE /projects/:id/pipelines/:pipeline_id' do
+ context 'authorized user' do
+ let(:owner) { project.owner }
+
+ it 'destroys the pipeline' do
+ delete api("/projects/#{project.id}/pipelines/#{pipeline.id}", owner)
+
+ expect(response).to have_gitlab_http_status(204)
+ expect { pipeline.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'returns 404 when it does not exist' do
+ delete api("/projects/#{project.id}/pipelines/123456", owner)
+
+ expect(response).to have_gitlab_http_status(404)
+ expect(json_response['message']).to eq '404 Not found'
+ end
+
+ it 'logs an audit event' do
+ expect { delete api("/projects/#{project.id}/pipelines/#{pipeline.id}", owner) }.to change { SecurityEvent.count }.by(1)
+ end
+
+ context 'when the pipeline has jobs' do
+ let!(:build) { create(:ci_build, project: project, pipeline: pipeline) }
+
+ it 'destroys associated jobs' do
+ delete api("/projects/#{project.id}/pipelines/#{pipeline.id}", owner)
+
+ expect(response).to have_gitlab_http_status(204)
+ expect { build.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+ end
+
+ context 'unauthorized user' do
+ context 'when user is not member' do
+ it 'should return a 404' do
+ delete api("/projects/#{project.id}/pipelines/#{pipeline.id}", non_member)
+
+ expect(response).to have_gitlab_http_status(404)
+ expect(json_response['message']).to eq '404 Project Not Found'
+ end
+ end
+
+ context 'when user is developer' do
+ let(:developer) { create(:user) }
+
+ before do
+ project.add_developer(developer)
+ end
+
+ it 'should return a 403' do
+ delete api("/projects/#{project.id}/pipelines/#{pipeline.id}", developer)
+
+ expect(response).to have_gitlab_http_status(403)
+ expect(json_response['message']).to eq '403 Forbidden'
+ end
+ end
+ end
+ end
+
describe 'POST /projects/:id/pipelines/:pipeline_id/retry' do
context 'authorized user' do
let!(:pipeline) do
diff --git a/spec/services/ci/destroy_pipeline_service_spec.rb b/spec/services/ci/destroy_pipeline_service_spec.rb
new file mode 100644
index 00000000000..097daf67feb
--- /dev/null
+++ b/spec/services/ci/destroy_pipeline_service_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ::Ci::DestroyPipelineService do
+ let(:project) { create(:project) }
+ let!(:pipeline) { create(:ci_pipeline, project: project) }
+
+ subject { described_class.new(project, user).execute(pipeline) }
+
+ context 'user is owner' do
+ let(:user) { project.owner }
+
+ it 'destroys the pipeline' do
+ subject
+
+ expect { pipeline.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'logs an audit event' do
+ expect { subject }.to change { SecurityEvent.count }.by(1)
+ end
+
+ context 'when the pipeline has jobs' do
+ let!(:build) { create(:ci_build, project: project, pipeline: pipeline) }
+
+ it 'destroys associated jobs' do
+ subject
+
+ expect { build.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'destroys associated stages' do
+ stages = pipeline.stages
+
+ subject
+
+ expect(stages).to all(raise_error(ActiveRecord::RecordNotFound))
+ end
+
+ context 'when job has artifacts' do
+ let!(:artifact) { create(:ci_job_artifact, :archive, job: build) }
+
+ it 'destroys associated artifacts' do
+ subject
+
+ expect { artifact.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+ end
+ end
+
+ context 'user is not owner' do
+ let(:user) { create(:user) }
+
+ it 'raises an exception' do
+ expect { subject }.to raise_error(Gitlab::Access::AccessDeniedError)
+ end
+ end
+end
diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb
index e0335880e8e..81b2c17fdb5 100644
--- a/spec/services/system_hooks_service_spec.rb
+++ b/spec/services/system_hooks_service_spec.rb
@@ -32,7 +32,7 @@ describe SystemHooksService do
end
it do
- project.old_path_with_namespace = 'transfered_from_path'
+ project.old_path_with_namespace = 'transferred_from_path'
expect(event_data(project, :transfer)).to include(
:event_name, :name, :created_at, :updated_at, :path, :project_id,
:owner_name, :owner_email, :project_visibility,
diff --git a/spec/support/shared_examples/models/cluster_application_status_shared_examples.rb b/spec/support/shared_examples/models/cluster_application_status_shared_examples.rb
index 82f0dd5d00f..c391cc48f4e 100644
--- a/spec/support/shared_examples/models/cluster_application_status_shared_examples.rb
+++ b/spec/support/shared_examples/models/cluster_application_status_shared_examples.rb
@@ -44,10 +44,40 @@ shared_examples 'cluster application status specs' do |application_name|
subject { create(application_name, :installing) }
it 'is installed' do
- subject.make_installed
+ subject.make_installed!
expect(subject).to be_installed
end
+
+ it 'updates helm version' do
+ subject.cluster.application_helm.update!(version: '1.2.3')
+
+ subject.make_installed!
+
+ subject.cluster.application_helm.reload
+
+ expect(subject.cluster.application_helm.version).to eq(Gitlab::Kubernetes::Helm::HELM_VERSION)
+ end
+ end
+
+ describe '#make_updated' do
+ subject { create(application_name, :updating) }
+
+ it 'is updated' do
+ subject.make_updated!
+
+ expect(subject).to be_updated
+ end
+
+ it 'updates helm version' do
+ subject.cluster.application_helm.update!(version: '1.2.3')
+
+ subject.make_updated!
+
+ subject.cluster.application_helm.reload
+
+ expect(subject.cluster.application_helm.version).to eq(Gitlab::Kubernetes::Helm::HELM_VERSION)
+ end
end
describe '#make_errored' do
diff --git a/spec/workers/emails_on_push_worker_spec.rb b/spec/workers/emails_on_push_worker_spec.rb
index f17c5ac6aac..05b4fb49ea3 100644
--- a/spec/workers/emails_on_push_worker_spec.rb
+++ b/spec/workers/emails_on_push_worker_spec.rb
@@ -101,7 +101,7 @@ describe EmailsOnPushWorker, :mailer do
context "when there are multiple recipients" do
before do
- # This is a hack because we modify the mail object before sending, for efficency,
+ # This is a hack because we modify the mail object before sending, for efficiency,
# but the TestMailer adapter just appends the objects to an array. To clone a mail
# object, create a new one!
# https://github.com/mikel/mail/issues/314#issuecomment-12750108