summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-27 18:07:48 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-27 18:07:48 +0000
commite20baee820ea2c76ee16980a98e8080f255d9035 (patch)
tree6e13a73bee42b7ef310850d03982faebea17a0b1
parent71c5863d7b1ca9836a7d7703f35750cd726a9846 (diff)
downloadgitlab-ce-e20baee820ea2c76ee16980a98e8080f255d9035.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/issue_templates/Solution_validation32
-rw-r--r--.rubocop.yml5
-rw-r--r--app/assets/javascripts/clusters/clusters_bundle.js13
-rw-r--r--app/assets/javascripts/pages/projects/serverless/index.js2
-rw-r--r--app/assets/javascripts/serverless/survey_banner.js36
-rw-r--r--app/assets/javascripts/serverless/survey_banner.vue52
-rw-r--r--app/controllers/admin/application_settings_controller.rb11
-rw-r--r--app/controllers/admin/projects_controller.rb5
-rw-r--r--app/controllers/admin/services_controller.rb2
-rw-r--r--app/graphql/types/environment_type.rb3
-rw-r--r--app/models/concerns/bulk_insert_safe.rb4
-rw-r--r--app/models/service.rb20
-rw-r--r--app/views/admin/services/index.html.haml2
-rw-r--r--app/views/clusters/clusters/show.html.haml2
-rw-r--r--app/views/projects/serverless/functions/index.html.haml2
-rw-r--r--app/views/projects/services/_integrations.html.haml2
-rw-r--r--changelogs/unreleased/18424-archived-corrupted-repo-not-displaying.yml5
-rw-r--r--changelogs/unreleased/35530-serverless-on-knative-install-functions-view-invite-user-to-help-sh.yml5
-rw-r--r--config/initializers/active_record_fix_insert_all.rb26
-rw-r--r--danger/commit_messages/Dangerfile73
-rw-r--r--doc/administration/integration/terminal.md6
-rw-r--r--doc/administration/monitoring/gitlab_self_monitoring_project/index.md5
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql5
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json18
-rw-r--r--doc/api/graphql/reference/index.md1
-rw-r--r--doc/api/packages.md68
-rw-r--r--doc/development/README.md2
-rw-r--r--doc/development/prometheus.md43
-rw-r--r--doc/install/aws/img/aws_ha_architecture_diagram.pngbin40323 -> 142738 bytes
-rw-r--r--doc/install/aws/index.md13
-rw-r--r--doc/raketasks/README.md1
-rw-r--r--doc/topics/autodevops/index.md10
-rw-r--r--doc/user/admin_area/settings/index.md133
-rw-r--r--doc/user/analytics/index.md37
-rw-r--r--doc/user/application_security/offline_deployments/index.md46
-rw-r--r--doc/user/compliance/license_compliance/img/license_compliance_add_license_v12_3.pngbin14046 -> 28440 bytes
-rw-r--r--doc/user/compliance/license_compliance/index.md14
-rw-r--r--doc/user/project/integrations/prometheus.md5
-rw-r--r--lib/gitlab/analytics/cycle_analytics/stage_events/production_stage_end.rb2
-rw-r--r--lib/gitlab/danger/commit_linter.rb2
-rw-r--r--lib/gitlab/import_export/group/import_export.yml4
-rw-r--r--locale/gitlab.pot22
-rw-r--r--rubocop/cop/performance/readlines_each.rb32
-rw-r--r--spec/controllers/admin/application_settings_controller_spec.rb4
-rw-r--r--spec/controllers/admin/projects_controller_spec.rb12
-rw-r--r--spec/factories/projects.rb4
-rw-r--r--spec/features/admin/admin_settings_spec.rb7
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb3
-rw-r--r--spec/fixtures/lib/gitlab/import_export/group_exports/complex/group.json10
-rw-r--r--spec/frontend/serverless/survey_banner_spec.js51
-rw-r--r--spec/graphql/types/environment_type_spec.rb2
-rw-r--r--spec/lib/gitlab/danger/commit_linter_spec.rb1
-rw-r--r--spec/models/concerns/bulk_insert_safe_spec.rb6
-rw-r--r--spec/models/project_services/irker_service_spec.rb2
-rw-r--r--spec/models/service_spec.rb43
-rw-r--r--spec/rubocop/cop/performance/readlines_each_spec.rb77
56 files changed, 795 insertions, 198 deletions
diff --git a/.gitlab/issue_templates/Solution_validation b/.gitlab/issue_templates/Solution_validation
new file mode 100644
index 00000000000..27f97d8dd12
--- /dev/null
+++ b/.gitlab/issue_templates/Solution_validation
@@ -0,0 +1,32 @@
+<!--Please answer the below questions to the best of your ability.-->
+
+#### What's this issue all about? (Background and context)
+
+#### What hypotheses and/or assumptions do you have?
+
+#### What questions are you trying to answer?
+
+#### What research methodology do you intend to use?
+
+<!-- What needs to be answered to move work forward? If you have a completed Opportunity Canvas include a link.-->
+
+#### What persona, persona segment, or customer type experiences the problem most acutely?
+
+#### What business decisions will be made based on this information?
+
+#### What, if any, relevant prior research already exists?
+
+<!-- Have a look at our UXR_Insights repo: https://gitlab.com/gitlab-org/uxr_insights -->
+
+#### Who will be leading the research?
+
+#### What timescales do you have in mind for the research?
+
+#### Relevant links (problem validation issue, design issue, script, prototype, notes, etc.)
+
+<!-- #### TODO Checklist
+ Consider adding a checklist in order to keep track of what stage the research is up to. Some possible checklist templates are here:
+ https://about.gitlab.com/handbook/engineering/ux/ux-research-training/templates-resources-for-research-studies/#checklists
+ -->
+
+/label ~"workflow::solution validation" \ No newline at end of file
diff --git a/.rubocop.yml b/.rubocop.yml
index 873876ecc94..984377cbb90 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -204,7 +204,6 @@ Gitlab/DuplicateSpecLocation:
Exclude:
- ee/spec/helpers/auth_helper_spec.rb
- ee/spec/lib/gitlab/gl_repository_spec.rb
- - ee/spec/lib/gitlab/usage_data_spec.rb
- ee/spec/models/namespace_spec.rb
- ee/spec/models/note_spec.rb
- ee/spec/serializers/environment_entity_spec.rb
@@ -215,7 +214,6 @@ Gitlab/DuplicateSpecLocation:
- ee/spec/services/system_hooks_service_spec.rb
- ee/spec/helpers/ee/auth_helper_spec.rb
- ee/spec/lib/ee/gitlab/gl_repository_spec.rb
- - ee/spec/lib/ee/gitlab/usage_data_spec.rb
- ee/spec/models/ee/namespace_spec.rb
- ee/spec/models/ee/note_spec.rb
- ee/spec/serializers/ee/environment_entity_spec.rb
@@ -382,3 +380,6 @@ Style/FloatDivision:
Cop/BanCatchThrow:
Enabled: true
+
+Performance/ReadlinesEach:
+ Enabled: true
diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js
index cb9c44bc36d..da34c5030f9 100644
--- a/app/assets/javascripts/clusters/clusters_bundle.js
+++ b/app/assets/javascripts/clusters/clusters_bundle.js
@@ -8,13 +8,20 @@ import Flash from '../flash';
import Poll from '../lib/utils/poll';
import initSettingsPanels from '../settings_panels';
import eventHub from './event_hub';
-import { APPLICATION_STATUS, INGRESS, INGRESS_DOMAIN_SUFFIX, CROSSPLANE } from './constants';
+import {
+ APPLICATION_STATUS,
+ INGRESS,
+ INGRESS_DOMAIN_SUFFIX,
+ CROSSPLANE,
+ KNATIVE,
+} from './constants';
import ClustersService from './services/clusters_service';
import ClustersStore from './stores/clusters_store';
import Applications from './components/applications.vue';
import RemoveClusterConfirmation from './components/remove_cluster_confirmation.vue';
import setupToggleButtons from '../toggle_buttons';
import initProjectSelectDropdown from '~/project_select';
+import initServerlessSurveyBanner from '~/serverless/survey_banner';
const Environments = () => import('ee_component/clusters/components/environments.vue');
@@ -326,6 +333,10 @@ export default class Clusters {
this.store.state.applications[INGRESS],
);
}
+
+ if (this.store.state.applications[KNATIVE]?.status === APPLICATION_STATUS.INSTALLED) {
+ initServerlessSurveyBanner();
+ }
}
showToken() {
diff --git a/app/assets/javascripts/pages/projects/serverless/index.js b/app/assets/javascripts/pages/projects/serverless/index.js
index 7b08620773c..a883737ac9b 100644
--- a/app/assets/javascripts/pages/projects/serverless/index.js
+++ b/app/assets/javascripts/pages/projects/serverless/index.js
@@ -1,5 +1,7 @@
import ServerlessBundle from '~/serverless/serverless_bundle';
+import initServerlessSurveyBanner from '~/serverless/survey_banner';
document.addEventListener('DOMContentLoaded', () => {
+ initServerlessSurveyBanner();
new ServerlessBundle(); // eslint-disable-line no-new
});
diff --git a/app/assets/javascripts/serverless/survey_banner.js b/app/assets/javascripts/serverless/survey_banner.js
new file mode 100644
index 00000000000..070e8f4c661
--- /dev/null
+++ b/app/assets/javascripts/serverless/survey_banner.js
@@ -0,0 +1,36 @@
+import Vue from 'vue';
+import { setUrlParams } from '~/lib/utils/url_utility';
+import SurveyBanner from './survey_banner.vue';
+
+let bannerInstance;
+const SURVEY_URL_BASE = 'https://gitlab.fra1.qualtrics.com/jfe/form/SV_00PfofFfY9s8Shf';
+
+export default function initServerlessSurveyBanner() {
+ const el = document.querySelector('.js-serverless-survey-banner');
+ if (el && !bannerInstance) {
+ const { userName, userEmail } = el.dataset;
+
+ // pre-populate survey fields
+ const surveyUrl = setUrlParams(
+ {
+ Q_PopulateResponse: JSON.stringify({
+ QID1: userEmail,
+ QID2: userName,
+ QID16: '1', // selects "yes" to "do you currently use GitLab?"
+ }),
+ },
+ SURVEY_URL_BASE,
+ );
+
+ bannerInstance = new Vue({
+ el,
+ render(createElement) {
+ return createElement(SurveyBanner, {
+ props: {
+ surveyUrl,
+ },
+ });
+ },
+ });
+ }
+}
diff --git a/app/assets/javascripts/serverless/survey_banner.vue b/app/assets/javascripts/serverless/survey_banner.vue
new file mode 100644
index 00000000000..a0a90fa5e80
--- /dev/null
+++ b/app/assets/javascripts/serverless/survey_banner.vue
@@ -0,0 +1,52 @@
+<script>
+import Cookies from 'js-cookie';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import { GlBanner } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlBanner,
+ },
+ props: {
+ surveyUrl: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ visible: true,
+ };
+ },
+ created() {
+ if (parseBoolean(Cookies.get('hide_serverless_survey'))) {
+ this.visible = false;
+ }
+ },
+ methods: {
+ handleClose() {
+ Cookies.set('hide_serverless_survey', 'true', { expires: 365 * 10 });
+ this.visible = false;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-banner
+ v-if="visible"
+ class="mt-4"
+ :title="s__('Serverless|Help shape the future of Serverless at GitLab')"
+ :button-text="s__('Serverless|Sign up for First Look')"
+ :button-link="surveyUrl"
+ @close="handleClose"
+ >
+ <p>
+ {{
+ s__(
+ 'Serverless|We are continually striving to improve our Serverless functionality. As a Knative user, we would love to hear how we can make this experience better for you. Sign up for GitLab First Look today and we will be in touch shortly.',
+ )
+ }}
+ </p>
+ </gl-banner>
+</template>
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index ef6af01eff6..ce71730cef1 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -8,7 +8,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
# ApplicationSetting model uses Gitlab::ThreadMemoryCache for caching and the
# cache might be stale immediately after an update.
# https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30233
- before_action :set_application_setting
+ before_action :set_application_setting, except: :integrations
before_action :whitelist_query_limiting, only: [:usage_data]
@@ -29,12 +29,11 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
def integrations
if Feature.enabled?(:instance_level_integrations)
- # TODO: Update this with actual integrations
- # To be fixed with https://gitlab.com/gitlab-org/gitlab/-/issues/199388
- @integrations = []
+ @integrations = Service.find_or_initialize_instances.sort_by(&:title)
+ else
+ set_application_setting
+ perform_update if submitted?
end
-
- perform_update if submitted?
end
def update
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index 7015da8bd50..9fe1f22c342 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -9,6 +9,11 @@ class Admin::ProjectsController < Admin::ApplicationController
def index
params[:sort] ||= 'latest_activity_desc'
@sort = params[:sort]
+
+ if params[:last_repository_check_failed].present? && params[:archived].nil?
+ params[:archived] = true
+ end
+
@projects = Admin::ProjectsFinder.new(params: params, current_user: current_user).execute
respond_to do |format|
diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb
index 55817550b4b..08ef992e604 100644
--- a/app/controllers/admin/services_controller.rb
+++ b/app/controllers/admin/services_controller.rb
@@ -6,7 +6,7 @@ class Admin::ServicesController < Admin::ApplicationController
before_action :service, only: [:edit, :update]
def index
- @services = Service.find_or_create_templates
+ @services = Service.find_or_create_templates.sort_by(&:title)
end
def edit
diff --git a/app/graphql/types/environment_type.rb b/app/graphql/types/environment_type.rb
index ad65caa24a6..c165c0ddc61 100644
--- a/app/graphql/types/environment_type.rb
+++ b/app/graphql/types/environment_type.rb
@@ -12,5 +12,8 @@ module Types
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the environment'
+
+ field :state, GraphQL::STRING_TYPE, null: false,
+ description: 'State of the environment, for example: available/stopped'
end
end
diff --git a/app/models/concerns/bulk_insert_safe.rb b/app/models/concerns/bulk_insert_safe.rb
index f1a2d566e97..e09f44e68dc 100644
--- a/app/models/concerns/bulk_insert_safe.rb
+++ b/app/models/concerns/bulk_insert_safe.rb
@@ -160,9 +160,7 @@ module BulkInsertSafe
attributes = {}
column_names.each do |name|
- value = item.read_attribute(name)
- value = item.type_for_attribute(name).serialize(value) # rubocop:disable Cop/ActiveRecordSerialize
- attributes[name] = value
+ attributes[name] = item.read_attribute(name)
end
_bulk_insert_reject_primary_key!(attributes, item.class.primary_key)
diff --git a/app/models/service.rb b/app/models/service.rb
index 138da0c546e..e4ae68cdaa7 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -47,6 +47,7 @@ class Service < ApplicationRecord
scope :without_defaults, -> { where(default: false) }
scope :by_type, -> (type) { where(type: type) }
scope :templates, -> { where(template: true, type: available_services_types) }
+ scope :instances, -> { where(instance: true, type: available_services_types) }
scope :push_hooks, -> { where(push_events: true, active: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
@@ -260,17 +261,16 @@ class Service < ApplicationRecord
self.category == :issue_tracker
end
- # Find all service templates; if some of them do not exist, create them
- # within a transaction to perform the lowest possible SQL queries.
def self.find_or_create_templates
create_nonexistent_templates
templates
end
private_class_method def self.create_nonexistent_templates
- nonexistent_services = available_services_types - templates.map(&:type)
+ nonexistent_services = list_nonexistent_services_for(templates)
return if nonexistent_services.empty?
+ # Create within a transaction to perform the lowest possible SQL queries.
transaction do
nonexistent_services.each do |service_type|
service_type.constantize.create(template: true)
@@ -278,6 +278,20 @@ class Service < ApplicationRecord
end
end
+ def self.find_or_initialize_instances
+ instances + build_nonexistent_instances
+ end
+
+ private_class_method def self.build_nonexistent_instances
+ list_nonexistent_services_for(instances).map do |service_type|
+ service_type.constantize.new
+ end
+ end
+
+ private_class_method def self.list_nonexistent_services_for(scope)
+ available_services_types - scope.map(&:type)
+ end
+
def self.available_services_names
service_names = %w[
alerts
diff --git a/app/views/admin/services/index.html.haml b/app/views/admin/services/index.html.haml
index 89872c1b91a..48f31bd0c6e 100644
--- a/app/views/admin/services/index.html.haml
+++ b/app/views/admin/services/index.html.haml
@@ -10,7 +10,7 @@
%th Service
%th Description
%th Last edit
- - @services.sort_by(&:title).each do |service|
+ - @services.each do |service|
%tr
%td
= boolean_to_icon service.activated?
diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml
index 4aa5b6af636..8797178f920 100644
--- a/app/views/clusters/clusters/show.html.haml
+++ b/app/views/clusters/clusters/show.html.haml
@@ -39,6 +39,8 @@
.js-cluster-application-notice
.flash-container
+ .js-serverless-survey-banner{ data: { user_name: current_user.name, user_email: current_user.email } }
+
%h4= @cluster.name
= render 'banner'
diff --git a/app/views/projects/serverless/functions/index.html.haml b/app/views/projects/serverless/functions/index.html.haml
index 09f4e556949..2f1da453c0a 100644
--- a/app/views/projects/serverless/functions/index.html.haml
+++ b/app/views/projects/serverless/functions/index.html.haml
@@ -10,6 +10,8 @@
help_path: help_page_path('user/project/clusters/serverless/index') } }
%div{ class: [('limit-container-width' unless fluid_layout)] }
+ .js-serverless-survey-banner{ data: { user_name: current_user.name, user_email: current_user.email } }
+
.js-serverless-functions-notice
.flash-container
diff --git a/app/views/projects/services/_integrations.html.haml b/app/views/projects/services/_integrations.html.haml
index e51585e55a4..24aeb598d7b 100644
--- a/app/views/projects/services/_integrations.html.haml
+++ b/app/views/projects/services/_integrations.html.haml
@@ -12,7 +12,7 @@
%th{ role: 'columnheader', scope: 'col', 'aria-colindex': 4 }= _('Last updated')
%tbody{ role: 'rowgroup' }
- - @integrations&.each do |integration|
+ - @integrations.each do |integration|
%tr{ role: 'row' }
%td{ role: 'cell', 'aria-colindex': 1 }
= boolean_to_icon integration.activated?
diff --git a/changelogs/unreleased/18424-archived-corrupted-repo-not-displaying.yml b/changelogs/unreleased/18424-archived-corrupted-repo-not-displaying.yml
new file mode 100644
index 00000000000..e9caeb2b8de
--- /dev/null
+++ b/changelogs/unreleased/18424-archived-corrupted-repo-not-displaying.yml
@@ -0,0 +1,5 @@
+---
+title: Fix archived corrupted projects not displaying in admin
+merge_request: 25171
+author: erickcspice
+type: fixed
diff --git a/changelogs/unreleased/35530-serverless-on-knative-install-functions-view-invite-user-to-help-sh.yml b/changelogs/unreleased/35530-serverless-on-knative-install-functions-view-invite-user-to-help-sh.yml
new file mode 100644
index 00000000000..15ddbecce8f
--- /dev/null
+++ b/changelogs/unreleased/35530-serverless-on-knative-install-functions-view-invite-user-to-help-sh.yml
@@ -0,0 +1,5 @@
+---
+title: Provide link to a survey for Knative users
+merge_request: 23025
+author:
+type: other
diff --git a/config/initializers/active_record_fix_insert_all.rb b/config/initializers/active_record_fix_insert_all.rb
new file mode 100644
index 00000000000..8ae208dd0e5
--- /dev/null
+++ b/config/initializers/active_record_fix_insert_all.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+# This fix is needed to properly support
+# columns that perform data mutation to a SQL datatype
+# ex. would be `jsonb` and `enum`
+#
+# This is covered by tests in `BulkInsertSafe`
+# that validates handling of different data types
+
+if Rails.gem_version > Gem::Version.new("6.0.2")
+ raise Gem::DependencyError,
+ "Remove patch once the https://github.com/rails/rails/pull/38763 is included"
+end
+
+module ActiveRecordInsertAllBuilderMixin
+ def extract_types_from_columns_on(table_name, keys:)
+ columns = connection.schema_cache.columns_hash(table_name)
+
+ unknown_column = (keys - columns.keys).first
+ raise UnknownAttributeError.new(model.new, unknown_column) if unknown_column
+
+ keys.index_with { |key| model.type_for_attribute(key) }
+ end
+end
+
+ActiveRecord::InsertAll::Builder.prepend(ActiveRecordInsertAllBuilderMixin)
diff --git a/danger/commit_messages/Dangerfile b/danger/commit_messages/Dangerfile
index 2db49f60710..59d42082de9 100644
--- a/danger/commit_messages/Dangerfile
+++ b/danger/commit_messages/Dangerfile
@@ -2,19 +2,28 @@
require_relative File.expand_path('../../lib/gitlab/danger/commit_linter', __dir__)
-URL_GIT_COMMIT = "https://chris.beams.io/posts/git-commit/"
+COMMIT_MESSAGE_GUIDELINES = "https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html#commit-messages-guidelines"
+MORE_INFO = "For more information, take a look at our [Commit message guidelines](#{COMMIT_MESSAGE_GUIDELINES})."
+THE_DANGER_JOB_TEXT = "the `danger-review` job"
MAX_COMMITS_COUNT = 10
def gitlab_danger
@gitlab_danger ||= GitlabDanger.new(helper.gitlab_helper)
end
-def fail_commit(commit, message)
- self.fail("#{commit.sha}: #{message}")
+def fail_commit(commit, message, more_info: true)
+ self.fail(build_message(commit, message, more_info: more_info))
end
-def warn_commit(commit, message)
- self.warn("#{commit.sha}: #{message}")
+def warn_commit(commit, message, more_info: true)
+ self.warn(build_message(commit, message, more_info: more_info))
+end
+
+def build_message(commit, message, more_info: true)
+ [message].tap do |full_message|
+ full_message << ". #{MORE_INFO}" if more_info
+ full_message.unshift("#{commit.sha}: ") if commit.sha
+ end.join
end
def squash_mr?
@@ -25,6 +34,10 @@ def wip_mr?
gitlab_danger.ci? ? gitlab.mr_json['work_in_progress'] : false
end
+def danger_job_link
+ gitlab_danger.ci? ? "[#{THE_DANGER_JOB_TEXT}](#{ENV['CI_JOB_URL']})" : THE_DANGER_JOB_TEXT
+end
+
# Perform various checks against commits. We're not using
# https://github.com/jonallured/danger-commit_lint because its output is not
# very helpful, and it doesn't offer the means of ignoring merge commits.
@@ -42,11 +55,11 @@ def lint_commit(commit)
return linter if linter.fixup? && squash_mr?
if linter.fixup?
- msg = 'Squash or fixup commits must be squashed before merge, or enable squash merge option'
+ msg = "Squash or fixup commits must be squashed before merge, or enable squash merge option and re-run #{danger_job_link}."
if wip_mr? || squash_mr?
- warn_commit(commit, msg)
+ warn_commit(commit, msg, more_info: false)
else
- fail_commit(commit, msg)
+ fail_commit(commit, msg, more_info: false)
end
# Makes no sense to process other rules for fixup commits, they trigger just more noise
@@ -56,7 +69,7 @@ def lint_commit(commit)
# Fail if a suggestion commit is used and squash is not enabled
if linter.suggestion?
unless squash_mr?
- fail_commit(commit, "If you are applying suggestions, enable squash in the merge request and re-run the `danger-review` job")
+ fail_commit(commit, "If you are applying suggestions, enable squash in the merge request and re-run #{danger_job_link}.", more_info: false)
end
return linter
@@ -93,18 +106,12 @@ def lint_commits(commits)
if multi_line_commit_linter && multi_line_commit_linter.failed?
warn_or_fail_commits(multi_line_commit_linter)
- fail_message('The commit message that will be used in the squash commit does not meet our Git commit message standards.')
else
title_linter = lint_mr_title(gitlab.mr_json['title'])
if title_linter.failed?
warn_or_fail_commits(title_linter)
- fail_message('The merge request title that will be used in the squash commit does not meet our Git commit message standards.')
end
end
- else
- if failed_commit_linters.any?
- fail_message('One or more commit messages do not meet our Git commit message standards.')
- end
end
end
@@ -123,40 +130,4 @@ def warn_or_fail_commits(failed_linters, default_to_fail: true)
end
end
-def fail_message(intro)
- markdown(<<~MARKDOWN)
- ## Commit message standards
-
- #{intro}
-
- For more information on how to write a good commit message, take a look at
- [How to Write a Git Commit Message](#{URL_GIT_COMMIT}).
-
- Here is an example of a good commit message:
-
- Reject ruby interpolation in externalized strings
-
- When using ruby interpolation in externalized strings, they can't be
- detected. Which means they will never be presented to be translated.
-
- To mix variables into translations we need to use `sprintf`
- instead.
-
- Instead of:
-
- _("Hello \#{subject}")
-
- Use:
-
- _("Hello %{subject}") % { subject: 'world' }
-
- This is an example of a bad commit message:
-
- updated README.md
-
- This commit message is bad because although it tells us that README.md is
- updated, it doesn't tell us why or how it was updated.
- MARKDOWN
-end
-
lint_commits(git.commits)
diff --git a/doc/administration/integration/terminal.md b/doc/administration/integration/terminal.md
index 0aa42e630b9..251e4ded8b4 100644
--- a/doc/administration/integration/terminal.md
+++ b/doc/administration/integration/terminal.md
@@ -96,7 +96,5 @@ they will receive a `Connection failed` message.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8413) in GitLab 8.17.
-Terminal sessions use long-lived connections; by default, these may last
-forever. You can configure a maximum session time in the Admin Area of your
-GitLab instance if you find this undesirable from a scalability or security
-point of view.
+Terminal sessions, by default, do not expire.
+You can limit terminal session lifetime in your GitLab instance. To do so, navigate to **{admin}** [**Admin Area > Settings > Web terminal**](../../user/admin_area/settings/index.md#general), and set a `max session time`.
diff --git a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
index 2058aa4f01c..884bb44cfda 100644
--- a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
+++ b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
@@ -21,10 +21,7 @@ This project will be used for self monitoring your GitLab instance.
1. Navigate to **Admin Area > Settings > Metrics and profiling**, and expand the **Self monitoring** section.
1. Toggle the **Create Project** button on.
-1. It can take a few seconds for the project to be created. After the project is
-created, GitLab displays a message with a link to the project. The project
-will also be linked in the help text above the **Create Project** button. You can also
-find the project under **Projects > Your projects**.
+1. Once your GitLab instance creates the project, you'll see a link to the project in the text above the **Create Project** toggle. You can also find it under **Projects > Your projects**.
## Deleting the self monitoring project
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index f6a1cb79a1f..2f1b902825a 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -1869,6 +1869,11 @@ type Environment {
Human-readable name of the environment
"""
name: String!
+
+ """
+ State of the environment, for example: available/stopped
+ """
+ state: String!
}
"""
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index a8f6923927b..aebd9131f3d 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -5542,6 +5542,24 @@
},
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "state",
+ "description": "State of the environment, for example: available/stopped",
+ "args": [
+
+ ],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"inputFields": null,
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index fb13c674347..dc3638dc7bc 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -318,6 +318,7 @@ Describes where code is deployed for a project
| --- | ---- | ---------- |
| `id` | ID! | ID of the environment |
| `name` | String! | Human-readable name of the environment |
+| `state` | String! | State of the environment, for example: available/stopped |
## Epic
diff --git a/doc/api/packages.md b/doc/api/packages.md
index ebab03662e0..31fc2863708 100644
--- a/doc/api/packages.md
+++ b/doc/api/packages.md
@@ -73,6 +73,10 @@ GET /groups/:id/packages
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/packages?exclude_subgroups=true
```
+CAUTION: **Deprecation**
+> The `build_info` attribute in the response is deprecated in favour of `pipeline`.
+> Introduced [GitLab 12.10](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28040).
+
Example response:
```json
@@ -87,15 +91,17 @@ Example response:
"delete_api_path": "/namespace1/project1/-/packages/1"
},
"created_at": "2019-11-27T03:37:38.711Z",
- "build_info": {
- "pipeline": {
- "id": 123,
- "status": "pending",
- "ref": "new-pipeline",
- "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "web_url": "https://example.com/foo/bar/pipelines/47",
- "created_at": "2016-08-11T11:28:34.085Z",
- "updated_at": "2016-08-11T11:32:35.169Z",
+ "pipeline": {
+ "id": 123,
+ "status": "pending",
+ "ref": "new-pipeline",
+ "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
+ "web_url": "https://example.com/foo/bar/pipelines/47",
+ "created_at": "2016-08-11T11:28:34.085Z",
+ "updated_at": "2016-08-11T11:32:35.169Z",
+ "user": {
+ "name": "Administrator",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
}
}
},
@@ -109,15 +115,17 @@ Example response:
"delete_api_path": "/namespace1/project1/-/packages/1"
},
"created_at": "2019-11-27T03:37:38.711Z",
- "build_info": {
- "pipeline": {
- "id": 123,
- "status": "pending",
- "ref": "new-pipeline",
- "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "web_url": "https://example.com/foo/bar/pipelines/47",
- "created_at": "2016-08-11T11:28:34.085Z",
- "updated_at": "2016-08-11T11:32:35.169Z",
+ "pipeline": {
+ "id": 123,
+ "status": "pending",
+ "ref": "new-pipeline",
+ "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
+ "web_url": "https://example.com/foo/bar/pipelines/47",
+ "created_at": "2016-08-11T11:28:34.085Z",
+ "updated_at": "2016-08-11T11:32:35.169Z",
+ "user": {
+ "name": "Administrator",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
}
}
}
@@ -150,6 +158,10 @@ GET /projects/:id/packages/:package_id
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/packages/:package_id
```
+CAUTION: **Deprecation**
+> The `build_info` attribute in the response is deprecated in favour of `pipeline`.
+> Introduced [GitLab 12.10](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28040).
+
Example response:
```json
@@ -163,15 +175,17 @@ Example response:
"delete_api_path": "/namespace1/project1/-/packages/1"
},
"created_at": "2019-11-27T03:37:38.711Z",
- "build_info": {
- "pipeline": {
- "id": 123,
- "status": "pending",
- "ref": "new-pipeline",
- "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
- "web_url": "https://example.com/foo/bar/pipelines/47",
- "created_at": "2016-08-11T11:28:34.085Z",
- "updated_at": "2016-08-11T11:32:35.169Z",
+ "pipeline": {
+ "id": 123,
+ "status": "pending",
+ "ref": "new-pipeline",
+ "sha": "a91957a858320c0e17f3a0eca7cfacbff50ea29a",
+ "web_url": "https://example.com/foo/bar/pipelines/47",
+ "created_at": "2016-08-11T11:28:34.085Z",
+ "updated_at": "2016-08-11T11:32:35.169Z",
+ "user": {
+ "name": "Administrator",
+ "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
}
}
}
diff --git a/doc/development/README.md b/doc/development/README.md
index 94b67ee0dfa..2089cf794ba 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -81,7 +81,7 @@ Complementary reads:
- [Working with Merge Request diffs](diffs.md)
- [Kubernetes integration guidelines](kubernetes.md)
- [Permissions](permissions.md)
-- [Prometheus metrics](prometheus_metrics.md)
+- [Prometheus](prometheus.md)
- [Guidelines for reusing abstractions](reusing_abstractions.md)
- [DeclarativePolicy framework](policies.md)
- [How Git object deduplication works in GitLab](git_object_deduplication.md)
diff --git a/doc/development/prometheus.md b/doc/development/prometheus.md
new file mode 100644
index 00000000000..f64d4a2eda1
--- /dev/null
+++ b/doc/development/prometheus.md
@@ -0,0 +1,43 @@
+# Working with Prometheus
+
+For more information on working with [Prometheus metrics](prometheus_metrics.md), see
+the documentation.
+
+## Access the UI of a Prometheus managed application in Kubernetes
+
+You can connect directly to Prometheus, and view the Prometheus user interface, when
+using a Prometheus managed application in Kubernetes:
+
+1. Find the name of the Prometheus pod in the user interface of your Kubernetes
+ provider, such as GKE, or by running the following `kubectl` command in your
+ terminal:
+
+ ```shell
+ kubectl get pods -n gitlab-managed-apps | grep 'prometheus-prometheus-server'
+ ```
+
+ The command should return a result like the following example, where
+ `prometheus-prometheus-server-55b4bd64c9-dpc6b` is the name of the Prometheus pod:
+
+ ```plaintext
+ gitlab-managed-apps prometheus-prometheus-server-55b4bd64c9-dpc6b 2/2 Running 0 71d
+ ```
+
+1. Run a `kubectl port-forward` command. In the following example, `9090` is the
+ Prometheus server's listening port:
+
+ ```shell
+ kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 9090:9090 -n gitlab-managed-apps
+ ```
+
+ The `port-forward` command forwards all requests sent to your system's `9090` port
+ to the `9090` port of the Prometheus pod. If the `9090` port on your system is used
+ by another application, you can change the port number before the colon to your
+ desired port. For example, to forward port `8080` of your local system, change the
+ command to:
+
+ ```shell
+ kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 8080:9090 -n gitlab-managed-apps
+ ```
+
+1. Open `localhost:9090` in your browser to display the Prometheus user interface.
diff --git a/doc/install/aws/img/aws_ha_architecture_diagram.png b/doc/install/aws/img/aws_ha_architecture_diagram.png
index 2064b0f49ae..b3f4d5b2bd8 100644
--- a/doc/install/aws/img/aws_ha_architecture_diagram.png
+++ b/doc/install/aws/img/aws_ha_architecture_diagram.png
Binary files differ
diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md
index ab89446d9ec..3c828ef1726 100644
--- a/doc/install/aws/index.md
+++ b/doc/install/aws/index.md
@@ -122,6 +122,19 @@ RDS instances as well:
| `gitlab-public-10.0.2.0` | public | `us-west-2b` | `10.0.2.0` |
| `gitlab-private-10.0.3.0` | private | `us-west-2b` | `10.0.3.0` |
+### Create NAT Gateways
+
+Instances deployed in our private subnets need to connect to the internet for updates, but should not be reachable from the public internet. To achieve this, we'll make use of [NAT Gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) deployed in each of our public subnets:
+
+1. Navigate to the VPC dashboard and click on **NAT Gateways** in the left menu bar.
+1. Click **Create NAT Gateway** and complete the following:
+ 1. **Subnet**: Select `gitlab-public-10.0.0.0` from the dropdown.
+ 1. **Elastic IP Allocation ID**: Enter an existing Elastic IP or click **Allocate Elastic IP address** to allocate a new IP to your NAT gateway.
+ 1. Add tags if needed.
+ 1. Click **Create NAT Gateway**.
+
+Create a second NAT gateway but this time place it in the second public subnet, `gitlab-public-10.0.2.0`.
+
### Route Table
Up to now all our subnets are private. We need to create a Route Table
diff --git a/doc/raketasks/README.md b/doc/raketasks/README.md
index a9ba44f82c6..51d85bd70f0 100644
--- a/doc/raketasks/README.md
+++ b/doc/raketasks/README.md
@@ -16,3 +16,4 @@ comments: false
- [Rebuild authorized_keys file](../administration/raketasks/maintenance.md#rebuild-authorized_keys-file) task for administrators
- [Uploads Migrate](../administration/raketasks/uploads/migrate.md)
- [Uploads Sanitize](../administration/raketasks/uploads/sanitize.md)
+- [Importing large GitLab project exports](../development/import_project.md#importing-via-a-rake-task)
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index 093f595258d..d49de056def 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -535,18 +535,14 @@ in the first place, and thus not realize that it needs to re-apply the old confi
> Introduced in [GitLab Ultimate][ee] 10.4.
-This is an optional step, since it requires a [review app](#auto-review-apps).
-If that requirement is not met, the job will be silently skipped.
-
Dynamic Application Security Testing (DAST) uses the
popular open source tool [OWASP ZAProxy](https://github.com/zaproxy/zaproxy)
to perform an analysis on the current code and checks for potential security
issues. The Auto DAST stage will be skipped on licenses other than Ultimate.
-Once the report is created, it's uploaded as an artifact which you can
-later download and check out.
-
-Any security warnings are also shown in the merge request widget. Read how
+Once the DAST scan is complete, any security warnings are shown
+on the [Security Dashboard](../../user/application_security/security_dashboard/index.md)
+and the Merge Request Widget. Read how
[DAST works](../../user/application_security/dast/index.md).
On your default branch, DAST scans an app deployed specifically for that purpose.
diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md
index 103a3f7230d..e85ab9051d4 100644
--- a/doc/user/admin_area/settings/index.md
+++ b/doc/user/admin_area/settings/index.md
@@ -4,35 +4,110 @@ type: index
# Admin Area settings **(CORE ONLY)**
-In the Admin Area **Settings** page, you can find various options for your GitLab
-instance like sign-up restrictions, account limits and quota, metrics, etc.
-
-Navigate to it by going to **Admin Area > Settings**. Some of the settings
-include:
-
-- [Account and limit settings](account_and_limit_settings.md) **(STARTER)**
-- [Continuous Integration and Deployment](continuous_integration.md)
-- [Email](email.md)
-- [Sign up restrictions](sign_up_restrictions.md)
-- [Sign in restrictions](sign_in_restrictions.md)
-- [Terms](terms.md)
-- [Third party offers](third_party_offers.md)
-- [Usage statistics](usage_statistics.md)
-- [Visibility and access controls](visibility_and_access_controls.md)
-- [User and IP rate limits](user_and_ip_rate_limits.md)
-- [Custom templates repository](instance_template_repository.md) **(PREMIUM)**
-- [Protected paths](protected_paths.md) **(CORE ONLY)**
-- [Help messages for the `/help` page and the login page](help_page.md)
-- [Push event activities limit and bulk push events](push_event_activities_limit.md)
-- [Gitaly timeouts](gitaly_timeouts.md)
+As an administrator of a GitLab self-managed instance, you can manage the behavior of your deployment. To do so, select **{admin}** **Admin Area > Settings**.
-NOTE: **Note:**
-You can change the [first day of the week](../../profile/preferences.md) for the entire GitLab instance
-in the **Localization** section of **Admin Area > Settings > Preferences**.
+The admin area is not accessible on GitLab.com, and settings can only be changed by the
+GitLab.com administrators. See the [GitLab.com settings](../../gitlab_com/index.md)
+documentation for all current settings and limits on the GitLab.com instance.
+
+## General
+
+Access the default page for admin area settings by navigating to
+**{admin}** **Admin Area > Settings > General**:
+
+| Option | Description |
+| ------ | ----------- |
+| [Visibility and access controls](visibility_and_access_controls.md) | Set default and restrict visibility levels. Configure import sources and Git access protocol. |
+| [Account and limit](account_and_limit_settings.md) **(STARTER)** | Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan. |
+| [Diff limits](../diff_limits.md) | Diff content limits. |
+| [Sign-up restrictions](sign_up_restrictions.md) | Configure the way a user creates a new account. |
+| [Sign in restrictions](sign_in_restrictions.md) | Set requirements for a user to sign-in. Enable mandatory two-factor authentication. |
+| [Terms of Service and Privacy Policy](terms.md) | Include a Terms of Service agreement and Privacy Policy that all users must accept. |
+| [External Authentication](external_authorization.md#configuration) | External Classification Policy Authorization |
+| [Web terminal](../../../administration/integration/terminal.md#limiting-websocket-connection-time) | Set max session time for web terminal. |
+| [Web IDE](../../project/web_ide/index.md#enabling-client-side-evaluation) | Manage Web IDE Features. |
+
+## Integrations
+
+| Option | Description |
+| ------ | ----------- |
+| [Elasticsearch](../../../integration/elasticsearch.md#enabling-elasticsearch) | Elasticsearch integration. Elasticsearch AWS IAM. |
+| [PlantUML](../../../administration/integration/plantuml.md#gitlab) | Allow rendering of PlantUML diagrams in Asciidoc documents. |
+| [Slack application](../../../user/project/integrations/gitlab_slack_application.md#configuration) **(FREE ONLY)** | Slack integration allows you to interact with GitLab via slash commands in a chat window. This option is only available on GitLab.com, though it may be [available for self-managed instances in the future](https://gitlab.com/gitlab-org/gitlab/-/issues/28164). |
+| [Third party offers](third_party_offers.md) | Control the display of third party offers. |
+| [Snowplow](../../../telemetry/index.md#enabling-tracking) | Configure the Snowplow integration. |
+| [Amazon EKS](../../project/clusters/add_remove_clusters.md#additional-requirements-for-self-managed-instances-core-only) | Amazon EKS integration allows you to provision EKS clusters from GitLab. |
+
+## Repository
+
+| Option | Description |
+| ------ | ----------- |
+| [Repository mirror](visibility_and_access_controls.md#allow-mirrors-to-be-set-up-for-projects) | Configure repository mirroring. |
+| [Repository storage](../../../administration/repository_storage_types.md#how-to-migrate-to-hashed-storage) | Configure storage path settings. |
+| Repository maintenance | ([Repository checks](../../../administration/repository_checks.md) and [Housekeeping](../../../administration/housekeeping.md)). Configure automatic Git checks and housekeeping on repositories. |
+| [Repository static objects](../../../administration/static_objects_external_storage.md) | Serve repository static objects (e.g. archives, blobs, ...) from an external storage (e.g. a CDN). |
+
+## Templates **(PREMIUM ONLY)**
+
+| Option | Description |
+| ------ | ----------- |
+| [Templates](instance_template_repository.md#configuration) | Set instance-wide template repository. |
+| [Custom project templates](../custom_project_templates.md) | Select the custom project template source group. |
+
+## CI/CD
-## GitLab.com Admin Area settings
+| Option | Description |
+| ------ | ----------- |
+| [Continuous Integration and Deployment](continuous_integration.md) | Auto DevOps, runners and job artifacts. |
+| [Required pipeline configuration](continuous_integration.md#required-pipeline-configuration-premium-only) **(PREMIUM ONLY)** | Set an instance-wide auto included [pipeline configuration](../../../ci/yaml/README.md). This pipeline configuration will be run after the project's own configuration. |
+| [Package Registry](continuous_integration.md#package-registry-configuration-premium-only) **(PREMIUM ONLY)**| Settings related to the use and experience of using GitLab's Package Registry. |
-Most of the settings under the Admin Area change the behavior of the whole
-GitLab instance. For GitLab.com, the admin settings are available only for the
-GitLab.com administrators, and the parameters can be found on the
-[GitLab.com settings](../../gitlab_com/index.md) documentation.
+## Reporting
+
+| Option | Description |
+| ------ | ----------- |
+| [Spam and Anti-bot Protection](../../../integration/recaptcha.md) | Enable reCAPTCHA or Akismet and set IP limits. For reCAPTCHA, we currently only support [v2](https://developers.google.com/recaptcha/docs/versions). |
+| [Abuse reports](../abuse_reports.md) | Set notification email for abuse reports. |
+
+## Metrics and profiling
+
+| Option | Description |
+| ------ | ----------- |
+| [Metrics - Influx](../../../administration/monitoring/performance/gitlab_configuration.md) | Enable and configure InfluxDB metrics. |
+| [Metrics - Prometheus](../../../administration/monitoring/prometheus/gitlab_metrics.md) | Enable and configure Prometheus metrics. |
+| [Metrics - Grafana](../../../administration/monitoring/performance/grafana_configuration.md#integration-with-gitlab-ui) | Enable and configure Grafana. |
+| [Profiling - Performance bar](../../../administration/monitoring/performance/performance_bar.md#enable-the-performance-bar-via-the-admin-panel) | Enable access to the Performance Bar for a given group. |
+| [Self monitoring](../../../administration/monitoring/gitlab_self_monitoring_project/index.md#creating-the-self-monitoring-project) | Enable or disable instance self monitoring. |
+| [Usage statistics](usage_statistics.md) | Enable or disable version check and usage ping. |
+| [Pseudonymizer data collection](../../../administration/pseudonymizer.md) **(ULTIMATE)** | Enable or disable the Pseudonymizer data collection. |
+
+## Network
+
+| Option | Description |
+| ------ | ----------- |
+| Performance optimization | [Write to "authorized_keys" file](../../../administration/operations/fast_ssh_key_lookup.md#setting-up-fast-lookup-via-gitlab-shell) and [Push event activities limit and bulk push events](push_event_activities_limit.md). Various settings that affect GitLab performance. |
+| [User and IP rate limits](user_and_ip_rate_limits.md) | Configure limits for web and API requests. |
+| [Outbound requests](../../../security/webhooks.md) | Allow requests to the local network from hooks and services. |
+| [Protected Paths](protected_paths.md) | Configure paths to be protected by Rack Attack. |
+| [Incident Management](../../incident_management/index.md) Limits | Configure limits on the number of inbound alerts able to be sent to a project. |
+
+## Geo
+
+| Option | Description |
+| ------ | ----------- |
+| Geo | Geo allows you to replicate your GitLab instance to other geographical locations. Redirects to **{admin}** **Admin Area >** **{location-dot}** **Geo >** **{settings}** **Settings**, and will no longer be available at **{admin}** **Admin Area >** **{settings}** **Settings >** **{location-dot}** **Geo** in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/36896). |
+
+## Preferences
+
+| Option | Description |
+| ------ | ----------- |
+| [Email](email.md) | Various email settings. |
+| [Help page](../../../customization/help_message.md) | Help page text and support page url. |
+| [Pages](../../../administration/pages/index.md#custom-domain-verification) | Size and domain settings for static websites |
+| [Real-time features](../../../administration/polling.md) | Change this value to influence how frequently the GitLab UI polls for updates. |
+| [Gitaly timeouts](gitaly_timeouts.md) | Configure Gitaly timeouts. |
+| Localization | [Default first day of the week](../../profile/preferences.md) and [Time tracking](../../project/time_tracking.md#limit-displayed-units-to-hours-core-only). |
+
+NOTE: **Note:**
+You can change the [Default first day of the week](../../profile/preferences.md) for the entire GitLab instance
+in the **Localization** section of **Admin Area > Settings > Preferences**.
diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md
index 2aa9d31d8bf..b2f7da234ad 100644
--- a/doc/user/analytics/index.md
+++ b/doc/user/analytics/index.md
@@ -1,4 +1,6 @@
-# Analytics workspace
+# Analytics
+
+## Analytics workspace
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12077) in GitLab 12.2.
@@ -6,27 +8,30 @@ The Analytics workspace will make it possible to aggregate analytics across
GitLab, so that users can view information across multiple projects and groups
in one place.
-To access the centralized analytics workspace, enable at least
-[one of the features](#available-analytics) under the workspace.
+To access the Analytics workspace, click on **More > Analytics** in the top navigation bar.
-Once enabled, click on **Analytics** from the top navigation bar.
+## Group-level analytics
-## Available analytics
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/195979) in GitLab 12.8.
-From the centralized analytics workspace, the following analytics are available:
+The following analytics features are available at the group level:
-- [Code Review Analytics](code_review_analytics.md). **(STARTER)**
-- [Value Stream Analytics](value_stream_analytics.md), enabled with the `cycle_analytics`
+- [Contribution](../group/contribution_analytics/index.md). **(STARTER)**
+- [Insights](../group/insights/index.md). **(ULTIMATE)**
+- [Issues](../group/issues_analytics/index.md). **(PREMIUM)**
+- [Productivity](productivity_analytics.md), enabled with the `productivity_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)**
-- [Productivity Analytics](productivity_analytics.md), enabled with the `productivity_analytics`
+- [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)**
-NOTE: **Note:**
-Project-level Value Stream Analytics are still available at a project's **Project > Value Stream Analytics**.
-
-## Other analytics tools
+## Project-level analytics
-In addition to the tools available in the Analytics workspace, GitLab provides:
+The following analytics features are available at the project level:
-- [Contribution analytics](../group/contribution_analytics/index.md). **(STARTER)**
-- [Issue analytics](../group/issues_analytics/index.md). **(PREMIUM)**
+- [CI/CD](../../ci/pipelines/index.md#pipeline-success-and-duration-charts). **(STARTER)**
+- [Code Review](code_review_analytics.md). **(STARTER)**
+- [Insights](../group/insights/index.md). **(ULTIMATE)**
+- [Issues](../group/issues_analytics/index.md). **(PREMIUM)**
+- Repository. **(STARTER)**
+- [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics`
+ [feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(STARTER)**
diff --git a/doc/user/application_security/offline_deployments/index.md b/doc/user/application_security/offline_deployments/index.md
index 6fc16684d79..c8161b2ef33 100644
--- a/doc/user/application_security/offline_deployments/index.md
+++ b/doc/user/application_security/offline_deployments/index.md
@@ -2,48 +2,62 @@
type: reference, howto
---
-# Offline deployments
+# Air-gapped (or offline) environment deployments
-This document describes how to operate Secure scanners offline.
+It is possible to run most of the GitLab security scanners when not
+connected to the internet.
-## Overview
+This document describes how to operate Secure scanners in an air-gapped or offline envionment. These instructions also apply to
+self-managed installations that are secured, have security policies (e.g., firewall policies), or otherwise restricted from
+accessing the full internet. These instructions are designed for physically disconnected networks,
+but can also be followed in these other use cases.
-It is possible to run most of the GitLab security scanners when not
-connected to the internet, in what is sometimes known as an offline,
-limited connectivity, Local Area Network (LAN), Intranet, or "air-gap"
-environment.
+## Air-gapped (or offline) environments
+
+In this situation, the GitLab instance can be one or more servers and services that can communicate
+on a local network, but with no or very restricted access to the internet. Assume anything within
+the GitLab instance and supporting infrastructure (for example, a private Maven repository) can be
+accessed through a local network connection. Assume any files from the internet must come in through
+physical media (USB drive, hard drive, writeable DVD, etc.).
-In this situation, the GitLab instance can be one, or more, servers and services running in a network that can talk to one another, but have zero, or perhaps very restricted access to the internet. Assume anything within the GitLab instance and supporting infrastructure (private Maven repository for example) can be accessed via local network connection. Assume any files from the internet must come in via physical media (USB drive, hard drive).
+## Overview
GitLab scanners generally will connect to the internet to download the
latest sets of signatures, rules, and patches. A few extra steps are necessary
-to configure the tools to not do this and to still function properly.
+to configure the tools to function properly by using resources available on your local network.
### Container registries and package repositories
-At a high-level, each of the security analyzers are delivered as Docker
-containers and reference various package repositories. When you run a job on
+At a high-level, the security analyzers are delivered as Docker images and
+may leverage various package repositories. When you run a job on
an internet-connected GitLab installation, GitLab checks the GitLab.com-hosted
-container registry and package repositories to ensure that you have
-the latest versions.
+container registry to check that you have the latest versions of these Docker images
+and possibly connect to package repositories to install necessary dependencies.
-In an air-gapped environment, this must be disabled so that GitLab.com is not
+In an air-gapped environment, these checks must be disabled so that GitLab.com is not
queried. Because the GitLab.com registry and repositories are not available,
you must update each of the scanners to either reference a different,
internally-hosted registry or provide access to the individual scanner images.
-You must also ensure that your app has access to common package repos
+You must also ensure that your app has access to common package repositories
that are not hosted on GitLab.com, such as npm, yarn, or rubygems. Packages
from these repos can be obtained by temporarily connecting to a network or by
mirroring the packages inside your own offline network.
+### Interacting with the vulnerabilities
+
+Once a vulnerability is found, you can interact with it. Read more on how to [interact with the vulnerabilities](../index.md#interacting-with-the-vulnerabilities).
+
+Please note that in some cases the reported vulnerabilities provide metadata that can contain external links exposed in the UI. These links might not be accessible within an air-gapped (or offline) environment.
+
### Scanner signature and rule updates
When connected to the internet, some scanners will reference public databases
for the latest sets of signatures and rules to check against. Without connectivity,
this is not possible. Depending on the scanner, you must therefore disable
these automatic update checks and either use the databases that they came
-with or manually update those databases.
+with and manually update those databases or provide access to your own copies
+hosted within your network.
## Specific scanner instructions
diff --git a/doc/user/compliance/license_compliance/img/license_compliance_add_license_v12_3.png b/doc/user/compliance/license_compliance/img/license_compliance_add_license_v12_3.png
index 79f6160e63f..ea4db16284c 100644
--- a/doc/user/compliance/license_compliance/img/license_compliance_add_license_v12_3.png
+++ b/doc/user/compliance/license_compliance/img/license_compliance_add_license_v12_3.png
Binary files differ
diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md
index 77314faea29..c968ad26b5e 100644
--- a/doc/user/compliance/license_compliance/index.md
+++ b/doc/user/compliance/license_compliance/index.md
@@ -18,9 +18,9 @@ that is provided by [Auto DevOps](../../../topics/autodevops/index.md).
GitLab checks the License Compliance report, compares the licenses between the
source and target branches, and shows the information right on the merge request.
-Blacklisted licenses will be clearly visible with an `x` red icon next to them
+Denied licenses will be clearly visible with an `x` red icon next to them
as well as new licenses which need a decision from you. In addition, you can
-[manually approve or blacklist](#project-policies-for-license-compliance)
+[manually allow or deny](#project-policies-for-license-compliance)
licenses in your project's settings.
NOTE: **Note:**
@@ -33,7 +33,7 @@ compliance report will be shown properly.
![License Compliance Widget](img/license_compliance.png)
If you are a project or group Maintainer, you can click on a license to be given
-the choice to approve it or blacklist it.
+the choice to allow it or deny it.
![License approval decision](img/license_compliance_decision.png)
@@ -282,9 +282,9 @@ license_scanning:
From the project's settings:
- The list of licenses and their status can be managed.
-- Licenses can be manually approved or blacklisted.
+- Licenses can be manually allowed or denied.
-To approve or blacklist a license:
+To allow or deny a license:
1. Either use the **Manage licenses** button in the merge request widget, or
navigate to the project's **Settings > CI/CD** and expand the
@@ -298,12 +298,12 @@ To approve or blacklist a license:
at the top of the list.
- Enter arbitrary text in the field at the top of the list. This will cause the text to be
added as a license name to the list.
-1. Select the **Approve** or **Blacklist** radio button to approve or blacklist respectively
+1. Select the **Allow** or **Deny** radio button to allow or deny respectively
the selected license.
To modify an existing license:
-1. In the **License Compliance** list, click the **Approved/Declined** dropdown to change it to the desired status.
+1. In the **License Compliance** list, click the **Allow/Deny** dropdown to change it to the desired status.
![License Compliance Settings](img/license_compliance_settings_v12_3.png)
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index 502e0f95dd2..1ff58930a61 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -837,6 +837,11 @@ Prerequisites for embedding from a Grafana instance:
## Troubleshooting
+When troubleshooting issues with a managed Prometheus app, it is often useful to
+[view the Prometheus UI](../../../development/prometheus.md#access-the-ui-of-a-prometheus-managed-application-in-kubernetes).
+
+### "No data found" error on Metrics dashboard page
+
If the "No data found" screen continues to appear, it could be due to:
- No successful deployments have occurred to this environment.
diff --git a/lib/gitlab/analytics/cycle_analytics/stage_events/production_stage_end.rb b/lib/gitlab/analytics/cycle_analytics/stage_events/production_stage_end.rb
index b249f6874e7..619b45664fa 100644
--- a/lib/gitlab/analytics/cycle_analytics/stage_events/production_stage_end.rb
+++ b/lib/gitlab/analytics/cycle_analytics/stage_events/production_stage_end.rb
@@ -6,7 +6,7 @@ module Gitlab
module StageEvents
class ProductionStageEnd < StageEvent
def self.name
- PlanStageStart.name
+ _("Issue first depoloyed to production")
end
def self.identifier
diff --git a/lib/gitlab/danger/commit_linter.rb b/lib/gitlab/danger/commit_linter.rb
index 8f51ef05f69..616c05d0a02 100644
--- a/lib/gitlab/danger/commit_linter.rb
+++ b/lib/gitlab/danger/commit_linter.rb
@@ -173,7 +173,7 @@ module Gitlab
end
def details
- message_parts[2]
+ message_parts[2]&.gsub(/^Signed-off-by.*$/, '')
end
def line_too_long?(line)
diff --git a/lib/gitlab/import_export/group/import_export.yml b/lib/gitlab/import_export/group/import_export.yml
index 2721198860c..49b9e0f83d9 100644
--- a/lib/gitlab/import_export/group/import_export.yml
+++ b/lib/gitlab/import_export/group/import_export.yml
@@ -36,6 +36,8 @@ excluded_attributes:
- :runners_token_encrypted
- :saml_discovery_token
- :visibility_level
+ epics:
+ - :state_id
methods:
labels:
@@ -50,6 +52,8 @@ methods:
- :action
lists:
- :list_type
+ epics:
+ - :state
preloads:
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 444fea14ff9..d1fd25c6a86 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -6127,19 +6127,19 @@ msgstr ""
msgid "CycleAnalyticsEvent|Issue last edited"
msgstr ""
-msgid "CycleAnalyticsEvent|Merge Request label was added"
+msgid "CycleAnalyticsEvent|Merge request closed"
msgstr ""
-msgid "CycleAnalyticsEvent|Merge Request label was removed"
+msgid "CycleAnalyticsEvent|Merge request created"
msgstr ""
-msgid "CycleAnalyticsEvent|Merge request closed"
+msgid "CycleAnalyticsEvent|Merge request first deployed to production"
msgstr ""
-msgid "CycleAnalyticsEvent|Merge request created"
+msgid "CycleAnalyticsEvent|Merge request label was added"
msgstr ""
-msgid "CycleAnalyticsEvent|Merge request first deployed to production"
+msgid "CycleAnalyticsEvent|Merge request label was removed"
msgstr ""
msgid "CycleAnalyticsEvent|Merge request last build finish time"
@@ -11161,6 +11161,9 @@ msgstr ""
msgid "Issue events"
msgstr ""
+msgid "Issue first depoloyed to production"
+msgstr ""
+
msgid "Issue or Merge Request ID is required"
msgstr ""
@@ -17972,6 +17975,9 @@ msgstr ""
msgid "Serverless|Getting started with serverless"
msgstr ""
+msgid "Serverless|Help shape the future of Serverless at GitLab"
+msgstr ""
+
msgid "Serverless|If you believe none of these apply, please check back later as the function data may be in the process of becoming available."
msgstr ""
@@ -17984,6 +17990,9 @@ msgstr ""
msgid "Serverless|No functions available"
msgstr ""
+msgid "Serverless|Sign up for First Look"
+msgstr ""
+
msgid "Serverless|The deploy job has not finished."
msgstr ""
@@ -17993,6 +18002,9 @@ msgstr ""
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr ""
+msgid "Serverless|We are continually striving to improve our Serverless functionality. As a Knative user, we would love to hear how we can make this experience better for you. Sign up for GitLab First Look today and we will be in touch shortly."
+msgstr ""
+
msgid "Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly configured."
msgstr ""
diff --git a/rubocop/cop/performance/readlines_each.rb b/rubocop/cop/performance/readlines_each.rb
new file mode 100644
index 00000000000..cb4ffaca6e9
--- /dev/null
+++ b/rubocop/cop/performance/readlines_each.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module Performance
+ class ReadlinesEach < RuboCop::Cop::Cop
+ MESSAGE = 'Avoid `IO.readlines.each`, since it reads contents into memory in full. ' \
+ 'Use `IO.each_line` or `IO.each` instead.'
+
+ def_node_matcher :full_file_read_via_class?, <<~PATTERN
+ (send
+ (send (const nil? {:IO :File}) :readlines _) :each)
+ PATTERN
+
+ def_node_matcher :full_file_read_via_instance?, <<~PATTERN
+ (... (... :readlines) :each)
+ PATTERN
+
+ def on_send(node)
+ full_file_read_via_class?(node) { add_offense(node, location: :selector, message: MESSAGE) }
+ full_file_read_via_instance?(node) { add_offense(node, location: :selector, message: MESSAGE) }
+ end
+
+ def autocorrect(node)
+ lambda do |corrector|
+ corrector.replace(node.loc.expression, node.source.gsub('readlines.each', 'each_line'))
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb
index 05c4743ed7f..f28465f0555 100644
--- a/spec/controllers/admin/application_settings_controller_spec.rb
+++ b/spec/controllers/admin/application_settings_controller_spec.rb
@@ -127,6 +127,10 @@ describe Admin::ApplicationSettingsController do
end
describe 'verify panel actions' do
+ before do
+ stub_feature_flags(instance_level_integrations: false)
+ end
+
Admin::ApplicationSettingsController::VALID_SETTING_PANELS.each do |valid_action|
it_behaves_like 'renders correct panels' do
let(:action) { valid_action }
diff --git a/spec/controllers/admin/projects_controller_spec.rb b/spec/controllers/admin/projects_controller_spec.rb
index 2d783dab621..f0157fb4260 100644
--- a/spec/controllers/admin/projects_controller_spec.rb
+++ b/spec/controllers/admin/projects_controller_spec.rb
@@ -24,6 +24,18 @@ describe Admin::ProjectsController do
expect(response.body).not_to match(project.name)
end
+ it 'retrieves archived and non archived corrupted projects when last_repository_check_failed is true' do
+ archived_corrupted_project = create(:project, :public, :archived, :last_repository_check_failed, name: 'CorruptedArchived', path: 'A')
+ corrupted_project = create(:project, :public, :last_repository_check_failed, name: 'CorruptedOnly', path: 'C')
+
+ get :index, params: { last_repository_check_failed: true }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).not_to match(project.name)
+ expect(response.body).to match(archived_corrupted_project.name)
+ expect(response.body).to match(corrupted_project.name)
+ end
+
it 'does not respond with projects pending deletion' do
pending_delete_project = create(:project, pending_delete: true)
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index ba38e1bb312..2b468ef92e1 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -114,6 +114,10 @@ FactoryBot.define do
archived { true }
end
+ trait :last_repository_check_failed do
+ last_repository_check_failed { true }
+ end
+
storage_version { Project::LATEST_STORAGE_VERSION }
trait :legacy_storage do
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 743aa0ed60e..ed05ad60ff0 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -194,6 +194,13 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc
expect(page).to have_content "Application settings saved successfully"
expect(current_settings.terminal_max_session_time).to eq(15)
end
+ end
+
+ context 'Integrations page' do
+ before do
+ stub_feature_flags(instance_level_integrations: false)
+ visit integrations_admin_application_settings_path
+ end
it 'Enable hiding third party offers' do
page.within('.as-third-party-offers') do
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index 15045023cf8..b35e79bef43 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -205,10 +205,11 @@ describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
let(:admin) { create(:admin) }
before do
+ stub_feature_flags(instance_level_integrations: false)
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
- visit general_admin_application_settings_path
+ visit integrations_admin_application_settings_path
end
it 'user does not see the offer' do
diff --git a/spec/fixtures/lib/gitlab/import_export/group_exports/complex/group.json b/spec/fixtures/lib/gitlab/import_export/group_exports/complex/group.json
index 504daae8abd..66512019f12 100644
--- a/spec/fixtures/lib/gitlab/import_export/group_exports/complex/group.json
+++ b/spec/fixtures/lib/gitlab/import_export/group_exports/complex/group.json
@@ -1492,7 +1492,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
- "state_id": "opened",
+ "state": "opened",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
@@ -1524,7 +1524,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
- "state_id": "opened",
+ "state": "closed",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
@@ -1556,7 +1556,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
- "state_id": "opened",
+ "state": "opened",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
@@ -1588,7 +1588,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
- "state_id": "opened",
+ "state": "closed",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
@@ -1620,7 +1620,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
- "state_id": "opened",
+ "state": "opened",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
diff --git a/spec/frontend/serverless/survey_banner_spec.js b/spec/frontend/serverless/survey_banner_spec.js
new file mode 100644
index 00000000000..15e9c6ec350
--- /dev/null
+++ b/spec/frontend/serverless/survey_banner_spec.js
@@ -0,0 +1,51 @@
+import { shallowMount } from '@vue/test-utils';
+import Cookies from 'js-cookie';
+import SurveyBanner from '~/serverless/survey_banner.vue';
+import { GlBanner } from '@gitlab/ui';
+
+describe('Knative survey banner', () => {
+ let wrapper;
+
+ function mountBanner() {
+ wrapper = shallowMount(SurveyBanner, {
+ propsData: {
+ surveyUrl: 'http://somesurvey.com/',
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('should render the banner when the cookie is absent', () => {
+ jest.spyOn(Cookies, 'get').mockReturnValue(undefined);
+ mountBanner();
+
+ expect(Cookies.get).toHaveBeenCalled();
+ expect(wrapper.find(GlBanner).exists()).toBe(true);
+ });
+
+ it('should close the banner and set a cookie when close button is clicked', () => {
+ jest.spyOn(Cookies, 'get').mockReturnValue(undefined);
+ jest.spyOn(Cookies, 'set');
+ mountBanner();
+
+ expect(wrapper.find(GlBanner).exists()).toBe(true);
+ wrapper.find(GlBanner).vm.$emit('close');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(Cookies.set).toHaveBeenCalledWith('hide_serverless_survey', 'true', { expires: 3650 });
+ expect(wrapper.find(GlBanner).exists()).toBe(false);
+ });
+ });
+
+ it('should not render the banner when the cookie is set', () => {
+ jest.spyOn(Cookies, 'get').mockReturnValue('true');
+ mountBanner();
+
+ expect(Cookies.get).toHaveBeenCalled();
+ expect(wrapper.find(GlBanner).exists()).toBe(false);
+ });
+});
diff --git a/spec/graphql/types/environment_type_spec.rb b/spec/graphql/types/environment_type_spec.rb
index 9e8f13e4c2e..b3711fa2f5c 100644
--- a/spec/graphql/types/environment_type_spec.rb
+++ b/spec/graphql/types/environment_type_spec.rb
@@ -7,7 +7,7 @@ describe GitlabSchema.types['Environment'] do
it 'has the expected fields' do
expected_fields = %w[
- name id
+ name id state
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/lib/gitlab/danger/commit_linter_spec.rb b/spec/lib/gitlab/danger/commit_linter_spec.rb
index a4760c942dc..e57ccd12fa5 100644
--- a/spec/lib/gitlab/danger/commit_linter_spec.rb
+++ b/spec/lib/gitlab/danger/commit_linter_spec.rb
@@ -86,6 +86,7 @@ describe Gitlab::Danger::CommitLinter do
"A commit message" | false
"A commit message\n" | false
"A commit message\n\n" | false
+ "A commit message\n\nSigned-off-by: User Name <user@name.me>" | false
"A commit message\n\nWith details" | true
end
diff --git a/spec/models/concerns/bulk_insert_safe_spec.rb b/spec/models/concerns/bulk_insert_safe_spec.rb
index 5ed1d6b9967..5d65d614ac5 100644
--- a/spec/models/concerns/bulk_insert_safe_spec.rb
+++ b/spec/models/concerns/bulk_insert_safe_spec.rb
@@ -7,7 +7,7 @@ describe BulkInsertSafe do
include BulkInsertSafe
include ShaAttribute
- validates :name, :enum_value, :secret_value, :sha_value, presence: true
+ validates :name, :enum_value, :secret_value, :sha_value, :jsonb_value, presence: true
ENUM_VALUES = {
case_1: 1
@@ -26,6 +26,7 @@ describe BulkInsertSafe do
default_value_for :enum_value, 'case_1'
default_value_for :secret_value, 'my-secret'
default_value_for :sha_value, '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12'
+ default_value_for :jsonb_value, { "key" => "value" }
def self.valid_list(count)
Array.new(count) { |n| new(name: "item-#{n}") }
@@ -60,6 +61,7 @@ describe BulkInsertSafe do
t.text :encrypted_secret_value, null: false
t.string :encrypted_secret_value_iv, null: false
t.binary :sha_value, null: false, limit: 20
+ t.jsonb :jsonb_value, null: false
t.index :name, unique: true
end
@@ -114,7 +116,7 @@ describe BulkInsertSafe do
described_class.bulk_insert!(items)
- attribute_names = described_class.attribute_names - %w[id]
+ attribute_names = described_class.attribute_names - %w[id created_at updated_at]
expect(described_class.last(items.size).pluck(*attribute_names)).to eq(
items.pluck(*attribute_names))
end
diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb
index 309dc51191b..badc964db16 100644
--- a/spec/models/project_services/irker_service_spec.rb
+++ b/spec/models/project_services/irker_service_spec.rb
@@ -64,7 +64,7 @@ describe IrkerService do
irker.execute(sample_data)
conn = @irker_server.accept
- conn.readlines.each do |line|
+ conn.each_line do |line|
msg = JSON.parse(line.chomp("\n"))
expect(msg.keys).to match_array(%w(to privmsg))
expect(msg['to']).to match_array(["irc://chat.freenode.net/#commits",
diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb
index cecd4f76fc5..d1a4924c07e 100644
--- a/spec/models/service_spec.rb
+++ b/spec/models/service_spec.rb
@@ -149,6 +149,47 @@ describe Service do
end
end
+ describe '.find_or_initialize_instances' do
+ shared_examples 'service instances' do
+ it 'returns the available service instances' do
+ expect(Service.find_or_initialize_instances.pluck(:type)).to match_array(Service.available_services_types)
+ end
+
+ it 'does not create service instances' do
+ expect { Service.find_or_initialize_instances }.not_to change { Service.count }
+ end
+ end
+
+ it_behaves_like 'service instances'
+
+ context 'with all existing instances' do
+ before do
+ Service.insert_all(
+ Service.available_services_types.map { |type| { instance: true, type: type } }
+ )
+ end
+
+ it_behaves_like 'service instances'
+
+ context 'with a previous existing service (Previous) and a new service (Asana)' do
+ before do
+ Service.insert(type: 'PreviousService', instance: true)
+ Service.delete_by(type: 'AsanaService', instance: true)
+ end
+
+ it_behaves_like 'service instances'
+ end
+ end
+
+ context 'with a few existing instances' do
+ before do
+ create(:jira_service, :instance)
+ end
+
+ it_behaves_like 'service instances'
+ end
+ end
+
describe 'template' do
let(:project) { create(:project) }
@@ -173,7 +214,7 @@ describe Service do
end
it 'does not create service templates' do
- expect { Service.find_or_create_templates }.to change { Service.count }.by(0)
+ expect { Service.find_or_create_templates }.not_to change { Service.count }
end
it_behaves_like 'retrieves service templates'
diff --git a/spec/rubocop/cop/performance/readlines_each_spec.rb b/spec/rubocop/cop/performance/readlines_each_spec.rb
new file mode 100644
index 00000000000..5b3691e2342
--- /dev/null
+++ b/spec/rubocop/cop/performance/readlines_each_spec.rb
@@ -0,0 +1,77 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require_relative '../../../support/helpers/expect_offense'
+require_relative '../../../../rubocop/cop/performance/readlines_each'
+
+describe RuboCop::Cop::Performance::ReadlinesEach do
+ include CopHelper
+ include ExpectOffense
+
+ subject(:cop) { described_class.new }
+
+ let(:message) { 'Avoid `IO.readlines.each`, since it reads contents into memory in full. Use `IO.each_line` or `IO.each` instead.' }
+
+ shared_examples_for(:class_read) do |klass|
+ context "and it is called as a class method on #{klass}" do
+ # We can't use `expect_offense` here because indentation changes based on `klass`
+ it 'flags it as an offense' do
+ inspect_source "#{klass}.readlines(file_path).each { |line| puts line }"
+
+ expect(cop.offenses.map(&:cop_name)).to contain_exactly('Performance/ReadlinesEach')
+ end
+ end
+
+ context 'when just using readlines without each' do
+ it 'does not flag it as an offense' do
+ expect_no_offenses "contents = #{klass}.readlines(file_path)"
+ end
+ end
+ end
+
+ context 'when reading all lines using IO.readlines.each' do
+ %w(IO File).each do |klass|
+ it_behaves_like(:class_read, klass)
+ end
+
+ context 'and it is called as an instance method on a return value' do
+ it 'flags it as an offense' do
+ expect_offense <<~SOURCE
+ get_file.readlines.each { |line| puts line }
+ ^^^^ #{message}
+ SOURCE
+ end
+ end
+
+ context 'and it is called as an instance method on an assigned variable' do
+ it 'flags it as an offense' do
+ expect_offense <<~SOURCE
+ file = File.new(path)
+ file.readlines.each { |line| puts line }
+ ^^^^ #{message}
+ SOURCE
+ end
+ end
+
+ context 'and it is called as an instance method on a new object' do
+ it 'flags it as an offense' do
+ expect_offense <<~SOURCE
+ File.new(path).readlines.each { |line| puts line }
+ ^^^^ #{message}
+ SOURCE
+ end
+ end
+
+ it 'autocorrects `readlines.each` to `each_line`' do
+ expect(autocorrect_source('obj.readlines.each { |line| line }')).to(
+ eq('obj.each_line { |line| line }')
+ )
+ end
+ end
+
+ context 'when just using readlines without each' do
+ it 'does not flag it as an offense' do
+ expect_no_offenses 'contents = my_file.readlines'
+ end
+ end
+end