diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 9a12db258d569916a0466a61ed937d87b1419a9f..150f24a5d5bcf0c3a99fbc0748ae08a24da02e81 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -74,7 +74,7 @@ module IssuablesHelper
end
end
- def serialize_issuable(issuable, serializer: nil)
+ def serialize_issuable(issuable, opts = {})
serializer_klass = case issuable
when Issue
IssueSerializer
@@ -84,7 +84,7 @@ module IssuablesHelper
serializer_klass
.new(current_user: current_user, project: issuable.project)
- .represent(issuable, serializer: serializer)
+ .represent(issuable, opts)
.to_json
end
diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb
index 70d296fe3b833537715f6b967e1f68b5ca35ec1c..506c8d251b76f2865763dfd38c6f21ab6f8b5adc 100644
--- a/app/mailers/emails/notes.rb
+++ b/app/mailers/emails/notes.rb
@@ -60,7 +60,7 @@ module Emails
# `note_id` is a `Note` when originating in `NotifyPreview`
@note = note_id.is_a?(Note) ? note_id : Note.find(note_id)
@project = @note.project
- @group = @note.noteable.try(:group)
+ @group = @project.try(:group) || @note.noteable.try(:group)
if (@project || @group) && @note.persisted?
@sent_notification = SentNotification.record_note(@note, recipient_id, reply_key)
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 6da6fbe55cb80d34c7830fe71feb4fe127f73f9d..30e29911758b7c504e139c595740a416094459a9 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -254,6 +254,10 @@ class Issue < ApplicationRecord
merge_requests_closing_issues.count
end
+ def labels_hook_attrs
+ labels.map(&:hook_attrs)
+ end
+
private
def ensure_metrics
diff --git a/app/models/note.rb b/app/models/note.rb
index 15271c68a9e26404ee201777c4e61cf1a19c5d31..b55af7d9b5e79548a5236feede46cb83df02babf 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -457,7 +457,7 @@ class Note < ApplicationRecord
end
def banzai_render_context(field)
- super.merge(noteable: noteable)
+ super.merge(noteable: noteable, system_note: system?)
end
def retrieve_upload(_identifier, paths)
diff --git a/app/serializers/merge_request_widget_entity.rb b/app/serializers/merge_request_widget_entity.rb
index a428930dbbfd10e52446279f20255bc7017e719e..43aced598a9149971728cfa20960b6ff553afed6 100644
--- a/app/serializers/merge_request_widget_entity.rb
+++ b/app/serializers/merge_request_widget_entity.rb
@@ -114,7 +114,10 @@ class MergeRequestWidgetEntity < IssuableEntity
presenter(merge_request).ci_status
end
- expose :issues_links do
+ # Rendering and redacting Markdown can be expensive. These links are
+ # just nice to have in the merge request widget, so only
+ # include them if they are explicitly requested on first load.
+ expose :issues_links, if: -> (_, opts) { opts[:issues_links] } do
expose :assign_to_closing do |merge_request|
presenter(merge_request).assign_to_closing_issues_link
end
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index f593f4e049e4b93f9a877bc9bb68083383821098..2084ca6f905545a4333de43f707f2714fed358c0 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -19,7 +19,7 @@
-# haml-lint:disable InlineJavaScript
:javascript
window.gl = window.gl || {};
- window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget')}
+ window.gl.mrWidgetData = #{serialize_issuable(@merge_request, serializer: 'widget', issues_links: true)}
window.gl.mrWidgetData.squash_before_merge_help_path = '#{help_page_path("user/project/merge_requests/squash_and_merge")}';
window.gl.mrWidgetData.troubleshooting_docs_path = '#{help_page_path('user/project/merge_requests/index.md', anchor: 'troubleshooting')}';
diff --git a/changelogs/unreleased/59702-fix-notification-flags-for-ms-teams.yml b/changelogs/unreleased/59702-fix-notification-flags-for-ms-teams.yml
new file mode 100644
index 0000000000000000000000000000000000000000..14a8da95ed983f80d13df2f44a19ef25029d5fe4
--- /dev/null
+++ b/changelogs/unreleased/59702-fix-notification-flags-for-ms-teams.yml
@@ -0,0 +1,5 @@
+---
+title: Fix missing API notification flags for Microsoft Teams
+merge_request: 29824
+author: Seiji Suenaga
+type: fixed
diff --git a/changelogs/unreleased/63513-ensure-gitlab-jsoncache-includes-the-gitlab-version-in-the-cache-key.yml b/changelogs/unreleased/63513-ensure-gitlab-jsoncache-includes-the-gitlab-version-in-the-cache-key.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b5715902630e504abbef92c1dae69ded23dccb8f
--- /dev/null
+++ b/changelogs/unreleased/63513-ensure-gitlab-jsoncache-includes-the-gitlab-version-in-the-cache-key.yml
@@ -0,0 +1,5 @@
+---
+title: Include the GitLab version in the cache key for Gitlab::JsonCache
+merge_request: 29938
+author:
+type: fixed
diff --git a/changelogs/unreleased/bug-63162-duplicate_path_in_links.yml b/changelogs/unreleased/bug-63162-duplicate_path_in_links.yml
new file mode 100644
index 0000000000000000000000000000000000000000..d3f246492fbee26b82cf5e81db46fa76aad65272
--- /dev/null
+++ b/changelogs/unreleased/bug-63162-duplicate_path_in_links.yml
@@ -0,0 +1,5 @@
+---
+title: Fixed 'diff version changes' link not working
+merge_request: 29825
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-labels-in-hooks.yml b/changelogs/unreleased/fix-labels-in-hooks.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c0904a860c51228e34aa28d97367ec2f486f3cc5
--- /dev/null
+++ b/changelogs/unreleased/fix-labels-in-hooks.yml
@@ -0,0 +1,5 @@
+---
+title: Fix label serialization in issue and note hooks
+merge_request: 29850
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-notes-emails-with-group-settings.yml b/changelogs/unreleased/fix-notes-emails-with-group-settings.yml
new file mode 100644
index 0000000000000000000000000000000000000000..77dae8418a8587167a59d673048046edfa74c2bb
--- /dev/null
+++ b/changelogs/unreleased/fix-notes-emails-with-group-settings.yml
@@ -0,0 +1,5 @@
+---
+title: Fix comment emails not respecting group-level notification email
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-omit-issues-links-on-poll.yml b/changelogs/unreleased/sh-omit-issues-links-on-poll.yml
new file mode 100644
index 0000000000000000000000000000000000000000..21e51d3534fd1ef7aca169b1491ae88968f47995
--- /dev/null
+++ b/changelogs/unreleased/sh-omit-issues-links-on-poll.yml
@@ -0,0 +1,5 @@
+---
+title: Omit issues links in merge request entity API response
+merge_request: 29917
+author:
+type: performance
diff --git a/changelogs/unreleased/sh-quiet-backup-secrets-log.yml b/changelogs/unreleased/sh-quiet-backup-secrets-log.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cf3e90c0cb1624041f9cb53e66caa8a001ba4a2e
--- /dev/null
+++ b/changelogs/unreleased/sh-quiet-backup-secrets-log.yml
@@ -0,0 +1,5 @@
+---
+title: Silence backup warnings when CRON=1 in use
+merge_request: 30033
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-recover-ee-schema-backport-migration-failure.yml b/changelogs/unreleased/sh-recover-ee-schema-backport-migration-failure.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1695e2827eba27f3a0c9be4df03ab0cbacd53aa9
--- /dev/null
+++ b/changelogs/unreleased/sh-recover-ee-schema-backport-migration-failure.yml
@@ -0,0 +1,5 @@
+---
+title: Prevent EE backport migrations from running if CE is not migrated
+merge_request: 30002
+author:
+type: fixed
diff --git a/db/migrate/20190402150158_backport_enterprise_schema.rb b/db/migrate/20190402150158_backport_enterprise_schema.rb
index 610a8808383d32d3a2f663b8ea465d7f01bdee77..8762cc53ed71a27f21bbad565aac2fe2a8ea0673 100644
--- a/db/migrate/20190402150158_backport_enterprise_schema.rb
+++ b/db/migrate/20190402150158_backport_enterprise_schema.rb
@@ -117,6 +117,8 @@ class BackportEnterpriseSchema < ActiveRecord::Migration[5.0]
end
def up
+ check_schema!
+
create_missing_tables
update_appearances
@@ -868,6 +870,52 @@ class BackportEnterpriseSchema < ActiveRecord::Migration[5.0]
remove_column_if_exists(:geo_nodes, :internal_url)
end
+ # Some users may have upgraded to EE at some point but downgraded to
+ # CE v11.11.3. As a result, their EE tables may not be in the right
+ # state. Here we check for these such cases and attempt to guide the
+ # user into recovering from this state by upgrading to v11.11.3 EE
+ # before installing v12.0.0 CE.
+ def check_schema!
+ # The following cases will fail later when this migration attempts
+ # to add a foreign key for non-existent columns.
+ columns_to_check = [
+ [:epics, :parent_id], # Added in GitLab 11.7
+ [:geo_event_log, :cache_invalidation_event_id], # Added in GitLab 11.4
+ [:vulnerability_feedback, :merge_request_id] # Added in GitLab 11.9
+ ].freeze
+
+ columns_to_check.each do |table, column|
+ check_ee_columns!(table, column)
+ end
+ end
+
+ def check_ee_columns!(table, column)
+ return unless table_exists?(table)
+ return if column_exists?(table, column)
+
+ raise_ee_migration_error!(table, column)
+ end
+
+ def raise_ee_migration_error!(table, column)
+ message = "Your database is missing the '#{column}' column from the '#{table}' table that is present for GitLab EE."
+
+ message +=
+ if ::Gitlab.ee?
+ "\nUpgrade your GitLab instance to 11.11.3 EE first!"
+ else
+ <<~MSG
+
+ Even though it looks like you're running a CE installation, it appears
+ you may have installed GitLab EE at some point. To migrate to GitLab 12.0:
+
+ 1. Install GitLab 11.11.3 EE
+ 2. Install GitLab 12.0.x CE
+ MSG
+ end
+
+ raise Exception.new(message)
+ end
+
def create_missing_tables
create_table_if_not_exists "approval_merge_request_rule_sources", id: :bigserial do |t|
t.bigint "approval_merge_request_rule_id", null: false
diff --git a/doc/administration/high_availability/README.md b/doc/administration/high_availability/README.md
index d9c80b1ec593db4dd05a89e97ad270d302328d41..0c4f926c57973dab6ac7e65450d628a096233b35 100644
--- a/doc/administration/high_availability/README.md
+++ b/doc/administration/high_availability/README.md
@@ -65,6 +65,7 @@ larger one.
- 1 Redis node
- 1 NFS/Gitaly storage server
- 2 or more GitLab application nodes (Unicorn, Workhorse, Sidekiq)
+- 1 Monitoring node (Prometheus, Grafana)
#### Installation Instructions
@@ -76,6 +77,7 @@ you can continue with the next step.
1. [Redis](redis.md#redis-in-a-scaled-environment)
1. [Gitaly](gitaly.md) (recommended) or [NFS](nfs.md)
1. [GitLab application nodes](gitlab.md)
+1. [Monitoring node (Prometheus and Grafana)](monitoring_node.md)
### Full Scaling
@@ -90,6 +92,7 @@ in size, indicating that there is contention or not enough resources.
- 2 or more NFS/Gitaly storage servers
- 2 or more Sidekiq nodes
- 2 or more GitLab application nodes (Unicorn, Workhorse)
+- 1 Monitoring node (Prometheus, Grafana)
## High Availability Architecture Examples
@@ -133,6 +136,7 @@ the contention.
- 3 Consul/Sentinel nodes
- 2 or more GitLab application nodes (Unicorn, Workhorse, Sidekiq, PGBouncer)
- 1 NFS/Gitaly server
+- 1 Monitoring node (Prometheus, Grafana)

@@ -192,6 +196,7 @@ with the added complexity of many more nodes to configure, manage and monitor.
- 2 or more API nodes (All requests to `/api`)
- 2 or more Web nodes (All other web requests)
- 2 or more NFS/Gitaly servers
+- 1 Monitoring node (Prometheus, Grafana)

@@ -205,4 +210,5 @@ separately:
1. [NFS Client and Host setup](nfs_host_client_setup.md)
1. [Configure the GitLab application servers](gitlab.md)
1. [Configure the load balancers](load_balancer.md)
+1. [Monitoring node (Prometheus and Grafana)](monitoring_node.md)
diff --git a/doc/administration/high_availability/database.md b/doc/administration/high_availability/database.md
index 3b874e5d312957f648e8dd57fbb202b02ebdbe3b..0aab7d6a58f252d88e84cd63a46cb7f7067b98a3 100644
--- a/doc/administration/high_availability/database.md
+++ b/doc/administration/high_availability/database.md
@@ -82,7 +82,8 @@ deploy the bundled PostgreSQL.
1. Note the PostgreSQL node's IP address or hostname, port, and
plain text password. These will be necessary when configuring the GitLab
application servers later.
-
+1. [Enable monitoring](#enable-monitoring)
+
Advanced configuration options are supported and can be added if
needed.
@@ -399,6 +400,7 @@ check the [Troubleshooting section](#troubleshooting) before proceeding.
```
1. [Reconfigure GitLab] for the changes to take effect.
+1. [Enable Monitoring](#enable-monitoring)
> Please note:
>
@@ -1086,6 +1088,25 @@ the previous section:
the `gitlab` database user
1. [Reconfigure GitLab] for the changes to take effect
+## Enable Monitoring
+
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+
+If you enable Monitoring, it must be enabled on **all** database servers.
+
+1. Create/edit `/etc/gitlab/gitlab.rb` and add the following configuration:
+
+ ```ruby
+ # Enable service discovery for Prometheus
+ consul['monitoring_service_discovery'] = true
+
+ # Set the network addresses that the exporters will listen on
+ node_exporter['listen_address'] = '0.0.0.0:9100'
+ postgres_exporter['listen_address'] = '0.0.0.0:9187'
+ ```
+
+1. Run `sudo gitlab-ctl reconfigure` to compile the configuration.
+
## Troubleshooting
#### Consul and PostgreSQL changes not taking effect.
diff --git a/doc/administration/high_availability/gitaly.md b/doc/administration/high_availability/gitaly.md
index 1d8e6c999cbc594feb8fce74326047f6934a7154..90e5f71d8351c65b2e2a9f6f9a3f6e71d7fc2699 100644
--- a/doc/administration/high_availability/gitaly.md
+++ b/doc/administration/high_availability/gitaly.md
@@ -19,3 +19,28 @@ Continue configuration of other components by going back to:
- [Scaled Architectures](README.md#scalable-architecture-examples)
- [High Availability Architectures](README.md#high-availability-architecture-examples)
+
+## Enable Monitoring
+
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+
+ 1. Create/edit `/etc/gitlab/gitlab.rb` and add the following configuration:
+
+ ```ruby
+ # Enable service discovery for Prometheus
+ consul['enable'] = true
+ consul['monitoring_service_discovery'] = true
+
+ # Replace placeholders
+ # Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
+ # with the addresses of the Consul server nodes
+ consul['configuration'] = {
+ retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z),
+ }
+
+ # Set the network addresses that the exporters will listen on
+ node_exporter['listen_address'] = '0.0.0.0:9100'
+ gitaly['prometheus_listen_addr'] = "0.0.0.0:9236"
+ ```
+
+ 1. Run `sudo gitlab-ctl reconfigure` to compile the configuration.
diff --git a/doc/administration/high_availability/gitlab.md b/doc/administration/high_availability/gitlab.md
index 888426ece5cc7125e233f991af1bc64d4aa505cc..1a530bb62550412595d02e445e434896923c21c9 100644
--- a/doc/administration/high_availability/gitlab.md
+++ b/doc/administration/high_availability/gitlab.md
@@ -76,6 +76,8 @@
registry['gid'] = 9002
```
+1. [Enable monitoring](#enable-monitoring)
+
> **Note:** To maintain uniformity of links across HA clusters, the `external_url`
on the first application server as well as the additional application
servers should point to the external url that users will use to access GitLab.
@@ -88,7 +90,8 @@
[Nginx documentation](http://docs.gitlab.com/omnibus/settings/nginx.html#enable-https)
for more information.
>
- > **Note:** It is best to set the `uid` and `gid`s prior to the initial reconfigure of GitLab. Omnibus will not recursively `chown` directories if set after the initial reconfigure.
+ > **Note:** It is best to set the `uid` and `gid`s prior to the initial reconfigure
+ of GitLab. Omnibus will not recursively `chown` directories if set after the initial reconfigure.
## First GitLab application server
@@ -129,6 +132,46 @@ need some extra configuration.
1. Run `sudo gitlab-ctl reconfigure` to compile the configuration.
+## Enable Monitoring
+
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+
+If you enable Monitoring, it must be enabled on **all** GitLab servers.
+
+1. Create/edit `/etc/gitlab/gitlab.rb` and add the following configuration:
+
+ ```ruby
+ # Enable service discovery for Prometheus
+ consul['enable'] = true
+ consul['monitoring_service_discovery'] = true
+
+ # Replace placeholders
+ # Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
+ # with the addresses of the Consul server nodes
+ consul['configuration'] = {
+ retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z),
+ }
+
+ # Set the network addresses that the exporters will listen on
+ node_exporter['listen_address'] = '0.0.0.0:9100'
+ gitlab_workhorse['prometheus_listen_addr'] = '0.0.0.0:9229'
+ sidekiq['listen_address'] = "0.0.0.0"
+ unicorn['listen'] = '0.0.0.0'
+
+ # Add the monitoring node's IP address to the monitoring whitelist and allow it to scrape the NGINX metrics
+ # Replace placeholder
+ # monitoring.gitlab.example.com
+ # with the addresses gathered for the monitoring node
+ gitlab_rails['monitoring_whitelist'] = ['monitoring.gitlab.example.com']
+ nginx['status']['options']['allow'] = ['monitoring.gitlab.example.com']
+ ```
+
+1. Run `sudo gitlab-ctl reconfigure` to compile the configuration.
+
+> **Warning:** After changing `unicorn['listen']` in `gitlab.rb`, and running `sudo gitlab-ctl reconfigure`,
+ it can take an extended period of time for unicorn to complete reloading after receiving a `HUP`.
+ For more information, see the [issue](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/4401).
+
## Troubleshooting
- `mount: wrong fs type, bad option, bad superblock on`
diff --git a/doc/administration/high_availability/monitoring_node.md b/doc/administration/high_availability/monitoring_node.md
new file mode 100644
index 0000000000000000000000000000000000000000..d16bf7dc0f06657d9f20b7193d379d6d895d6736
--- /dev/null
+++ b/doc/administration/high_availability/monitoring_node.md
@@ -0,0 +1,67 @@
+# Configuring a Monitoring node for Scaling and High Availability
+
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+
+## Standalone Monitoring node using GitLab Omnibus
+
+The GitLab Omnibus package can be used to configure a standalone Monitoring node running Prometheus and Grafana.
+The monitoring node is not highly available. See [Scaling and High Availability](README.md)
+for an overview of GitLab scaling and high availability options.
+
+The steps below are the minimum necessary to configure a Monitoring node running Prometheus and Grafana with
+Omnibus:
+
+1. SSH into the Monitoring node.
+1. [Download/install](https://about.gitlab.com/installation) the Omnibus GitLab
+ package you want using **steps 1 and 2** from the GitLab downloads page.
+ - Do not complete any other steps on the download page.
+
+1. Edit `/etc/gitlab/gitlab.rb` and add the contents:
+
+ ```ruby
+ external_url 'http://gitlab.example.com'
+
+ # Enable Prometheus
+ prometheus['enable'] = true
+ prometheus['listen_address'] = '0.0.0.0:9090'
+ prometheus['monitor_kubernetes'] = false
+
+ # Enable Grafana
+ grafana['enable'] = true
+ grafana['admin_password'] = 'toomanysecrets'
+
+ # Enable service discovery for Prometheus
+ consul['enable'] = true
+ consul['monitoring_service_discovery'] = true
+
+ # Replace placeholders
+ # Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
+ # with the addresses of the Consul server nodes
+ consul['configuration'] = {
+ retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z),
+ }
+
+ # Disable all other services
+ gitlab_rails['auto_migrate'] = false
+ alertmanager['enable'] = false
+ gitaly['enable'] = false
+ gitlab_monitor['enable'] = false
+ gitlab_workhorse['enable'] = false
+ nginx['enable'] = true
+ postgres_exporter['enable'] = false
+ postgresql['enable'] = false
+ redis['enable'] = false
+ redis_exporter['enable'] = false
+ sidekiq['enable'] = false
+ unicorn['enable'] = false
+ node_exporter['enable'] = false
+ ```
+
+1. Run `sudo gitlab-ctl reconfigure` to compile the configuration.
+
+## Migrating to Service Discovery
+
+Once monitoring using Service Discovery is enabled with `consul['monitoring_service_discovery'] = true`,
+ensure that `prometheus['scrape_configs']` is not set in `/etc/gitlab/gitlab.rb`. Setting both
+`consul['monitoring_service_discovery'] = true` and `prometheus['scrape_configs']` in `/etc/gitlab/gitlab.rb`
+will result in errors.
diff --git a/doc/administration/high_availability/redis.md b/doc/administration/high_availability/redis.md
index 1aaa709fc8fea0d45e2d1b7edbfcb0a52a760ae0..f61a8834af3eb3d1cfd4ae054d4d258c9aae33ae 100644
--- a/doc/administration/high_availability/redis.md
+++ b/doc/administration/high_availability/redis.md
@@ -74,6 +74,7 @@ Omnibus:
1. Note the Redis node's IP address or hostname, port, and
Redis password. These will be necessary when configuring the GitLab
application servers later.
+1. [Enable Monitoring](#enable-monitoring)
Advanced configuration options are supported and can be added if
needed.
@@ -749,6 +750,33 @@ gitlab_rails['redis_sentinels'] = [
[Reconfigure Omnibus GitLab][reconfigure] for the changes to take effect.
+## Enable Monitoring
+
+> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/3786) in GitLab 12.0.
+
+ If you enable Monitoring, it must be enabled on **all** Redis servers.
+
+ 1. Create/edit `/etc/gitlab/gitlab.rb` and add the following configuration:
+
+ ```ruby
+ # Enable service discovery for Prometheus
+ consul['enable'] = true
+ consul['monitoring_service_discovery'] = true
+
+ # Replace placeholders
+ # Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z
+ # with the addresses of the Consul server nodes
+ consul['configuration'] = {
+ retry_join: %w(Y.Y.Y.Y consul1.gitlab.example.com Z.Z.Z.Z),
+ }
+
+ # Set the network addresses that the exporters will listen on
+ node_exporter['listen_address'] = '0.0.0.0:9100'
+ redis_exporter['listen_address'] = '0.0.0.0:9121'
+ ```
+
+ 1. Run `sudo gitlab-ctl reconfigure` to compile the configuration.
+
## Advanced configuration
Omnibus GitLab configures some things behind the curtains to make the sysadmins'
diff --git a/doc/api/services.md b/doc/api/services.md
index f38f96f64ad1c73e0614b8b330b443703679fd9d..042fee4a21a61bcc615a34cf4a516f3d731621cb 100644
--- a/doc/api/services.md
+++ b/doc/api/services.md
@@ -1023,6 +1023,8 @@ Parameters:
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `webhook` | string | true | The Microsoft Teams webhook. For example, `https://outlook.office.com/webhook/...` |
+| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
+| `notify_only_default_branch` | boolean | false | Send notifications only for the default branch |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index df455857dee4995eec82b52c9e7069c4d58ba967..bef533c05c7397ebbdb7115367ff29e40d251466 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -480,7 +480,7 @@ Below you can find supported syntax reference:
> Example: `$VARIABLE == "some value"`
- > Example: `$VARIABLE != "some value"` _(added in 11.11)_
+ > Example: `$VARIABLE != "some value"` (introduced in GitLab 11.11)
You can use equality operator `==` or `!=` to compare a variable content to a
string. We support both, double quotes and single quotes to define a string
@@ -491,7 +491,7 @@ Below you can find supported syntax reference:
> Example: `$VARIABLE == null`
- > Example: `$VARIABLE != null` _(added in 11.11)_
+ > Example: `$VARIABLE != null` (introduced in GitLab 11.11)
It sometimes happens that you want to check whether a variable is defined
or not. To do that, you can compare a variable to `null` keyword, like
@@ -502,7 +502,7 @@ Below you can find supported syntax reference:
> Example: `$VARIABLE == ""`
- > Example: `$VARIABLE != ""` _(added in 11.11)_
+ > Example: `$VARIABLE != ""` (introduced in GitLab 11.11)
If you want to check whether a variable is defined, but is empty, you can
simply compare it against an empty string, like `$VAR == ''` or non-empty
@@ -512,7 +512,7 @@ Below you can find supported syntax reference:
> Example: `$VARIABLE_1 == $VARIABLE_2`
- > Example: `$VARIABLE_1 != $VARIABLE_2` _(added in 11.11)_
+ > Example: `$VARIABLE_1 != $VARIABLE_2` (introduced in GitLab 11.11)
It is possible to compare two variables. This is going to compare values
of these variables.
@@ -528,11 +528,11 @@ Below you can find supported syntax reference:
`$STAGING` value needs to a string, with length higher than zero.
Variable that contains only whitespace characters is not an empty variable.
-1. Pattern matching _(added in 11.0)_
+1. Pattern matching (introduced in GitLab 11.0)
> Example: `$VARIABLE =~ /^content.*/`
- > Example: `$VARIABLE_1 !~ /^content.*/` _(added in 11.11)_
+ > Example: `$VARIABLE_1 !~ /^content.*/` (introduced in GitLab 11.11)
It is possible perform pattern matching against a variable and regular
expression. Expression like this evaluates to truth if matches are found
@@ -541,7 +541,7 @@ Below you can find supported syntax reference:
Pattern matching is case-sensitive by default. Use `i` flag modifier, like
`/pattern/i` to make a pattern case-insensitive.
-1. Conjunction / Disjunction
+1. Conjunction / Disjunction ([introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/27925) in GitLab 12.0)
> Example: `$VARIABLE1 =~ /^content.*/ && $VARIABLE2 == "something"`
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 5f32cd7eba284fe12732c1f5ea56c0e2f8eb2475..fc161fa09a90336de48f94d8699662b98d763d5b 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -141,13 +141,13 @@ Component statuses are linked to configuration documentation for each component.
| [Consul](#consul) | Database node discovery, failover | [⚙][consul-omnibus] | [❌][consul-charts] | [❌][consul-charts] | [✅](../user/gitlab_com/index.md#consul) | ❌ | ❌ | EE Only |
| [GitLab self-monitoring: Prometheus](#prometheus) | Time-series database, metrics collection, and query service | [✅][prometheus-omnibus] | [✅][prometheus-charts] | [⚙][prometheus-charts] | [✅](../user/gitlab_com/index.md#prometheus) | ❌ | ❌ | CE & EE |
| [GitLab self-monitoring: Alertmanager](#alertmanager) | Deduplicates, groups, and routes alerts from Prometheus | [⚙][alertmanager-omnibus] | [✅][alertmanager-charts] | [⚙][alertmanager-charts] | [✅](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
-| [GitLab self-monitoring: Grafana](#grafana) | Metrics dashboard | [⚙][grafana-omnibus] | [⤓][grafana-charts] | [⤓][grafana-charts] | [✅](https://dashboards.gitlab.com/d/RZmbBr7mk/gitlab-triage?refresh=30s) | ❌ | ❌ | CE & EE |
+| [GitLab self-monitoring: Grafana](#grafana) | Metrics dashboard | [✅][grafana-omnibus] | [⤓][grafana-charts] | [⤓][grafana-charts] | [✅](https://dashboards.gitlab.com/d/RZmbBr7mk/gitlab-triage?refresh=30s) | ❌ | ❌ | CE & EE |
| [GitLab self-monitoring: Sentry](#sentry) | Track errors generated by the GitLab instance | [⤓][sentry-omnibus] | [❌][sentry-charts] | [❌][sentry-charts] | [✅](https://about.gitlab.com/handbook/support/workflows/services/gitlab_com/500_errors.html#searching-sentry) | [⤓][gitlab-yml] | [⤓][gitlab-yml] | CE & EE |
| [GitLab self-monitoring: Jaeger](#jaeger) | View traces generated by the GitLab instance | [❌][jaeger-omnibus] | [❌][jaeger-charts] | [❌][jaeger-charts] | [❌](https://gitlab.com/gitlab-org/omnibus-gitlab/issues/4104) | [⤓][jaeger-source] | [⚙][jaeger-gdk] | CE & EE |
| [Redis Exporter](#redis-exporter) | Prometheus endpoint with Redis metrics | [✅][redis-exporter-omnibus] | [✅][redis-exporter-charts] | [✅][redis-exporter-charts] | [✅](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
| [Postgres Exporter](#postgres-exporter) | Prometheus endpoint with PostgreSQL metrics | [✅][postgres-exporter-omnibus] | [✅][postgres-exporter-charts] | [✅][postgres-exporter-charts] | [✅](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
| [PgBouncer Exporter](#pgbouncer-exporter) | Prometheus endpoint with PgBouncer metrics | [⚙][pgbouncer-exporter-omnibus] | [❌][pgbouncer-exporter-charts] | [❌][pgbouncer-exporter-charts] | [✅](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
-| [GitLab Monitor](#gitlab-monitor) | Generates a variety of GitLab metrics | [✅][gitlab-monitor-omnibus] | [❌][gitab-monitor-charts] | [❌][gitab-monitor-charts] | [✅](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
+| [GitLab Monitor](#gitlab-monitor) | Generates a variety of GitLab metrics | [✅][gitlab-monitor-omnibus] | [✅][gitab-monitor-charts] | [✅][gitab-monitor-charts] | [✅](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
| [Node Exporter](#node-exporter) | Prometheus endpoint with system metrics | [✅][node-exporter-omnibus] | [❌][node-exporter-charts] | [❌][node-exporter-charts] | [✅](https://about.gitlab.com/handbook/engineering/monitoring/) | ❌ | ❌ | CE & EE |
| [Mattermost](#mattermost) | Open-source Slack alternative | [⚙][mattermost-omnibus] | [⤓][mattermost-charts] | [⤓][mattermost-charts] | [⤓](../user/project/integrations/mattermost_slash_commands.md#manual-configuration), [⤓](../user/project/integrations/mattermost.html) | ❌ | ❌ | CE & EE |
| [MinIO](#minio) | Object storage service | [⤓][minio-omnibus] | [✅][minio-charts] | [✅][minio-charts] | [✅](https://about.gitlab.com/handbook/engineering/infrastructure/production-architecture/#storage-architecture) | ❌ | [⚙][minio-gdk] | CE & EE |
@@ -681,7 +681,7 @@ We've also detailed [our architecture of GitLab.com](https://about.gitlab.com/ha
[pgbouncer-exporter-omnibus]: ../administration/monitoring/prometheus/pgbouncer_exporter.md
[pgbouncer-exporter-charts]: https://docs.gitlab.com/charts/installation/deployment.html#postgresql
[gitlab-monitor-omnibus]: ../administration/monitoring/prometheus/gitlab_monitor_exporter.md
-[gitab-monitor-charts]: https://gitlab.com/charts/gitlab/issues/319
+[gitab-monitor-charts]: https://docs.gitlab.com/charts/charts/gitlab/gitlab-monitor/index.html
[node-exporter-omnibus]: ../administration/monitoring/prometheus/node_exporter.md
[node-exporter-charts]: https://gitlab.com/charts/gitlab/issues/1332
[mattermost-omnibus]: https://docs.gitlab.com/omnibus/gitlab-mattermost/
diff --git a/doc/user/admin_area/settings/visibility_and_access_controls.md b/doc/user/admin_area/settings/visibility_and_access_controls.md
index a1229484388f14e0d37f8cd8520bea596eb087c0..63879935fd8d19baefa2024df5b5d8c3e8c72048 100644
--- a/doc/user/admin_area/settings/visibility_and_access_controls.md
+++ b/doc/user/admin_area/settings/visibility_and_access_controls.md
@@ -4,12 +4,15 @@ type: reference
# Visibility and access controls
-GitLab allows admins to:
+GitLab allows administrators to:
- Control access and visibility to GitLab resources including branches and projects.
- Select from which hosting sites code can be imported into GitLab.
- Select the protocols permitted to access GitLab.
- Enable or disable repository mirroring.
+- Prevent non-administrators from deleting projects
+ ([introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/5615) in GitLab 12.0).
+ **[PREMIUM ONLY]**
To access the visibility and access control options:
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index 34d4507210eac51bed1363563df7d7031c4d8fd2..a4e5b19bdc7271e5d25697317dc5490b1556a39e 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -346,7 +346,7 @@ the report JSON unless stated otherwise. Presence of optional fields depends on
| `vulnerabilities[].scanner` | A node that describes the analyzer used to find this vulnerability. |
| `vulnerabilities[].scanner.id` | Id of the scanner as a snake_case string. |
| `vulnerabilities[].scanner.name` | Name of the scanner, for display purposes. |
-| `vulnerabilities[].location` | A node that tells where the vulnerability is located. |
+| `vulnerabilities[].location` | A node that tells where the vulnerability is located. |
| `vulnerabilities[].location.file` | Path to the dependencies file (e.g., `yarn.lock`). Optional. |
| `vulnerabilities[].location.dependency` | A node that describes the dependency of a project where the vulnerability is located. |
| `vulnerabilities[].location.dependency.package` | A node that provides the information on the package where the vulnerability is located. |
@@ -379,17 +379,17 @@ Once a vulnerability is found, you can interact with it. Read more on how to
## Dependency List
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/10075)
-in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/10075) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.0.
-An additional benefit of Dependency Scanning is the ability to get a list of your project's dependencies with their versions.
+An additional benefit of Dependency Scanning is the ability to get a list of your
+project's dependencies with their versions. This list can be generated only for
+[languages and package managers](#supported-languages-and-package-managers)
+supported by Gemnasium.
-This list can be generated only for [languages and package managers](#supported-languages-and-package-managers) supported by [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium/general).
-
-To see the generated dependency list, navigate to the Dependency List page under your project's left sidebar menu **Project > Dependency List**.
+To see the generated dependency list, navigate to your project's **Project > Dependency List**.
## Contributing to the vulnerability database
You can search the [gemnasium-db](https://gitlab.com/gitlab-org/security-products/gemnasium-db) project
to find a vulnerability in the Gemnasium database.
-You can also [submit new vulnerabilities](https://gitlab.com/gitlab-org/security-products/gemnasium-db/blob/master/CONTRIBUTING.md).
\ No newline at end of file
+You can also [submit new vulnerabilities](https://gitlab.com/gitlab-org/security-products/gemnasium-db/blob/master/CONTRIBUTING.md).
diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md
index 1d640966013269e6f1a4d26a173f6bed57c7a82e..6c430ff7cd953e848dc4c9c5c268e52532802176 100644
--- a/doc/user/project/quick_actions.md
+++ b/doc/user/project/quick_actions.md
@@ -35,7 +35,7 @@ discussions, and descriptions:
| `/label ~label1 ~label2` | Add label(s). Label names can also start without ~ but mixed syntax is not supported. | ✓ | ✓ |
| `/unlabel ~label1 ~label2` | Remove all or specific label(s)| ✓ | ✓ |
| `/relabel ~label1 ~label2` | Replace label | ✓ | ✓ |
-| /copy_metadata #issue | !merge_request | Copy labels and milestone from other issue or merge request in the project | ✓ | ✓ |
+| /copy_metadata <#issue | !merge_request> | Copy labels and milestone from other issue or merge request in the project | ✓ | ✓ |
| /estimate <1w 3d 2h 14m> | Set time estimate | ✓ | ✓ |
| `/remove_estimate` | Remove time estimate | ✓ | ✓ |
| /spend <time(1h 30m | -1h 5m)> <date(YYYY-MM-DD)> | Add or subtract spent time; optionally, specify the date that time was spent on | ✓ | ✓ |
@@ -44,14 +44,14 @@ discussions, and descriptions:
| `/unlock` | Unlock the discussion | ✓ | ✓ |
| /due <in 2 days | this Friday | December 31st>| Set due date | ✓ | |
| `/remove_due_date` | Remove due date | ✓ | |
-| `/weight 0,1,2, ...` | Set weight **[STARTER]** | ✓ | |
+| /weight <0 | 1 | 2 | ...> | Set weight **[STARTER]** | ✓ | |
| `/clear_weight` | Clears weight **[STARTER]** | ✓ | |
-| `/epic <&epic | group&epic | Epic URL>` | Add to epic **[ULTIMATE]** | ✓ | |
+| /epic <&epic | group&epic | Epic URL> | Add to epic **[ULTIMATE]** | ✓ | |
| `/remove_epic` | Removes from epic **[ULTIMATE]** | ✓ | |
| `/promote` | Promote issue to epic **[ULTIMATE]** | ✓ | |
| `/confidential` | Make confidential | ✓ | |
-| `/duplicate #issue` | Mark this issue as a duplicate of another issue | ✓ |
-| `/move path/to/project` | Move this issue to another project | ✓ | |
+| `/duplicate <#issue>` | Mark this issue as a duplicate of another issue | ✓ |
+| `/move ` | Move this issue to another project | ✓ | |
| `/target_branch ` | Set target branch | | ✓ |
| `/wip` | Toggle the Work In Progress status | | ✓ |
| `/approve` | Approve the merge request | | ✓ |
@@ -85,3 +85,5 @@ The following quick actions are applicable for epics threads and description:
| `/label ~label1 ~label2` | Add label(s) |
| `/unlabel ~label1 ~label2` | Remove all or specific label(s) |
| `/relabel ~label1 ~label2` | Replace label |
+| /child_epic <&epic | group&epic | Epic URL> | Adds child epic to epic ([introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab-ee/issues/7330)) |
+| /remove_child_epic <&epic | group&epic | Epic URL> | Removes child epic from epic ([introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab-ee/issues/7330)) |
diff --git a/lib/api/helpers/services_helpers.rb b/lib/api/helpers/services_helpers.rb
index 44c577204b8083bc1118f726a364d954029403f0..cf2e9d01356efb52e246ded5e46f7407eb4263fa 100644
--- a/lib/api/helpers/services_helpers.rb
+++ b/lib/api/helpers/services_helpers.rb
@@ -683,8 +683,9 @@ module API
name: :webhook,
type: String,
desc: 'The Microsoft Teams webhook. e.g. https://outlook.office.com/webhook/…'
- }
- ],
+ },
+ chat_notification_flags
+ ].flatten,
'mattermost' => [
chat_notification_settings,
chat_notification_flags,
diff --git a/lib/banzai/filter/relative_link_filter.rb b/lib/banzai/filter/relative_link_filter.rb
index 199b3533cf408c7eff128b4fe639e7de4b8ea1e9..80c84c0f6226f3a848f0664335c548a3cc94348d 100644
--- a/lib/banzai/filter/relative_link_filter.rb
+++ b/lib/banzai/filter/relative_link_filter.rb
@@ -17,6 +17,8 @@ module Banzai
include Gitlab::Utils::StrongMemoize
def call
+ return doc if context[:system_note]
+
@uri_types = {}
clear_memoization(:linkable_files)
diff --git a/lib/gitlab/data_builder/note.rb b/lib/gitlab/data_builder/note.rb
index 16e62622ed4ebc41efe988a427c14f02c1d97a74..2c4ef73a68839ce0fc0861e88d9e4197f1543c76 100644
--- a/lib/gitlab/data_builder/note.rb
+++ b/lib/gitlab/data_builder/note.rb
@@ -44,7 +44,7 @@ module Gitlab
data[:commit] = build_data_for_commit(project, user, note)
elsif note.for_issue?
data[:issue] = note.noteable.hook_attrs
- data[:issue][:labels] = note.noteable.labels(&:hook_attrs)
+ data[:issue][:labels] = note.noteable.labels_hook_attrs
elsif note.for_merge_request?
data[:merge_request] = note.noteable.hook_attrs
elsif note.for_snippet?
diff --git a/lib/gitlab/hook_data/issue_builder.rb b/lib/gitlab/hook_data/issue_builder.rb
index cfc9ebe4f924b7e3573a5136fe8e1bb4add30e04..e5f86ca02b5176f8ea1d556fa8757b6f913c61c2 100644
--- a/lib/gitlab/hook_data/issue_builder.rb
+++ b/lib/gitlab/hook_data/issue_builder.rb
@@ -45,7 +45,7 @@ module Gitlab
human_time_estimate: issue.human_time_estimate,
assignee_ids: issue.assignee_ids,
assignee_id: issue.assignee_ids.first, # This key is deprecated
- labels: issue.labels
+ labels: issue.labels_hook_attrs
}
issue.attributes.with_indifferent_access.slice(*self.class.safe_hook_attributes)
diff --git a/lib/gitlab/json_cache.rb b/lib/gitlab/json_cache.rb
index e4bc437d78723251b74ed6970db59686a5057779..d01183d7845195702e818f2c85eabdb5cc5ddef3 100644
--- a/lib/gitlab/json_cache.rb
+++ b/lib/gitlab/json_cache.rb
@@ -22,10 +22,10 @@ module Gitlab
expanded_cache_key = [namespace, key].compact
if cache_key_with_version
- expanded_cache_key << Rails.version
+ expanded_cache_key << [Gitlab::VERSION, Rails.version]
end
- expanded_cache_key.join(':')
+ expanded_cache_key.flatten.join(':').freeze
end
def expire(key)
@@ -58,7 +58,7 @@ module Gitlab
private
def parse_value(raw, klass)
- value = ActiveSupport::JSON.decode(raw)
+ value = ActiveSupport::JSON.decode(raw.to_s)
case value
when Hash then parse_entry(value, klass)
diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake
index c531eb1d2163b77b161ec95fe6f66d3890ab6773..2bf71701b5738a7dc17f7474d64333102b0d0740 100644
--- a/lib/tasks/gitlab/backup.rake
+++ b/lib/tasks/gitlab/backup.rake
@@ -21,10 +21,10 @@ namespace :gitlab do
backup.cleanup
backup.remove_old
- puts "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \
+ progress.puts "Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data \n" \
"and are not included in this backup. You will need these files to restore a backup.\n" \
"Please back them up manually.".color(:red)
- puts "Backup task is done."
+ progress.puts "Backup task is done."
end
# Restore backup of GitLab system
diff --git a/spec/lib/banzai/filter/relative_link_filter_spec.rb b/spec/lib/banzai/filter/relative_link_filter_spec.rb
index dad0a5535c04aa2e458b0f50de3caaa87406827d..8ff971114d61c54872cf1c6d7f0009cb03ed9780 100644
--- a/spec/lib/banzai/filter/relative_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/relative_link_filter_spec.rb
@@ -101,6 +101,13 @@ describe Banzai::Filter::RelativeLinkFilter do
.to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
end
+ it 'does not modify relative URLs in system notes' do
+ path = "#{project_path}/merge_requests/1/diffs"
+ doc = filter(link(path), system_note: true)
+
+ expect(doc.at_css('a')['href']).to eq path
+ end
+
it 'ignores absolute URLs with two leading slashes' do
doc = filter(link('//doc/api/README.md'))
expect(doc.at_css('a')['href']).to eq '//doc/api/README.md'
diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb
index ed9a1e2352906f7f4d346ec72c423fb180bab424..1b5dd2538e035013d8392ccde6272ebeb9de87dc 100644
--- a/spec/lib/gitlab/data_builder/note_spec.rb
+++ b/spec/lib/gitlab/data_builder/note_spec.rb
@@ -38,9 +38,11 @@ describe Gitlab::DataBuilder::Note do
end
describe 'When asking for a note on issue' do
+ let(:label) { create(:label, project: project) }
+
let(:issue) do
- create(:issue, created_at: fixed_time, updated_at: fixed_time,
- project: project)
+ create(:labeled_issue, created_at: fixed_time, updated_at: fixed_time,
+ project: project, labels: [label])
end
let(:note) do
@@ -48,13 +50,16 @@ describe Gitlab::DataBuilder::Note do
end
it 'returns the note and issue-specific data' do
+ without_timestamps = lambda { |label| label.except('created_at', 'updated_at') }
+ hook_attrs = issue.reload.hook_attrs
+
expect(data).to have_key(:issue)
- expect(data[:issue].except('updated_at'))
- .to eq(issue.reload.hook_attrs.except('updated_at'))
+ expect(data[:issue].except('updated_at', 'labels'))
+ .to eq(hook_attrs.except('updated_at', 'labels'))
expect(data[:issue]['updated_at'])
- .to be >= issue.hook_attrs['updated_at']
- expect(data[:issue]['labels'])
- .to eq(issue.hook_attrs['labels'])
+ .to be >= hook_attrs['updated_at']
+ expect(data[:issue]['labels'].map(&without_timestamps))
+ .to eq(hook_attrs['labels'].map(&without_timestamps))
end
context 'with confidential issue' do
diff --git a/spec/lib/gitlab/hook_data/issue_builder_spec.rb b/spec/lib/gitlab/hook_data/issue_builder_spec.rb
index f066c0e3813b675b500d8c0fda97909558d23cba..b06d05c1c7fed44c268780062f0306b4ff5b0f14 100644
--- a/spec/lib/gitlab/hook_data/issue_builder_spec.rb
+++ b/spec/lib/gitlab/hook_data/issue_builder_spec.rb
@@ -1,7 +1,8 @@
require 'spec_helper'
describe Gitlab::HookData::IssueBuilder do
- set(:issue) { create(:issue) }
+ set(:label) { create(:label) }
+ set(:issue) { create(:labeled_issue, labels: [label], project: label.project) }
let(:builder) { described_class.new(issue) }
describe '#build' do
@@ -39,6 +40,7 @@ describe Gitlab::HookData::IssueBuilder do
expect(data).to include(:human_time_estimate)
expect(data).to include(:human_total_time_spent)
expect(data).to include(:assignee_ids)
+ expect(data).to include('labels' => [label.hook_attrs])
end
context 'when the issue has an image in the description' do
diff --git a/spec/lib/gitlab/json_cache_spec.rb b/spec/lib/gitlab/json_cache_spec.rb
index b82c09af30689052b0d365f5f5a735981fa88a5e..59160741c45fc00e45d8494fef3df9e39d9d01af 100644
--- a/spec/lib/gitlab/json_cache_spec.rb
+++ b/spec/lib/gitlab/json_cache_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::JsonCache do
let(:backend) { double('backend').as_null_object }
let(:namespace) { 'geo' }
let(:key) { 'foo' }
- let(:expanded_key) { "#{namespace}:#{key}:#{Rails.version}" }
+ let(:expanded_key) { "#{namespace}:#{key}:#{Gitlab::VERSION}:#{Rails.version}" }
set(:broadcast_message) { create(:broadcast_message) }
subject(:cache) { described_class.new(namespace: namespace, backend: backend) }
@@ -35,42 +35,68 @@ describe Gitlab::JsonCache do
describe '#cache_key' do
context 'when namespace is not defined' do
- it 'expands out the key with Rails version' do
- cache = described_class.new(cache_key_with_version: true)
+ context 'when cache_key_with_version is true' do
+ it 'expands out the key with GitLab, and Rails versions' do
+ cache = described_class.new(cache_key_with_version: true)
- cache_key = cache.cache_key(key)
+ cache_key = cache.cache_key(key)
- expect(cache_key).to eq("#{key}:#{Rails.version}")
+ expect(cache_key).to eq("#{key}:#{Gitlab::VERSION}:#{Rails.version}")
+ end
end
- end
- context 'when cache_key_with_version is true' do
- it 'expands out the key with namespace and Rails version' do
- cache = described_class.new(namespace: namespace, cache_key_with_version: true)
+ context 'when cache_key_with_version is false' do
+ it 'returns the key' do
+ cache = described_class.new(namespace: nil, cache_key_with_version: false)
- cache_key = cache.cache_key(key)
+ cache_key = cache.cache_key(key)
- expect(cache_key).to eq("#{namespace}:#{key}:#{Rails.version}")
+ expect(cache_key).to eq(key)
+ end
end
end
- context 'when cache_key_with_version is false' do
- it 'expands out the key with namespace' do
- cache = described_class.new(namespace: namespace, cache_key_with_version: false)
+ context 'when namespace is nil' do
+ context 'when cache_key_with_version is true' do
+ it 'expands out the key with GitLab, and Rails versions' do
+ cache = described_class.new(cache_key_with_version: true)
- cache_key = cache.cache_key(key)
+ cache_key = cache.cache_key(key)
- expect(cache_key).to eq("#{namespace}:#{key}")
+ expect(cache_key).to eq("#{key}:#{Gitlab::VERSION}:#{Rails.version}")
+ end
+ end
+
+ context 'when cache_key_with_version is false' do
+ it 'returns the key' do
+ cache = described_class.new(namespace: nil, cache_key_with_version: false)
+
+ cache_key = cache.cache_key(key)
+
+ expect(cache_key).to eq(key)
+ end
end
end
- context 'when namespace is nil, and cache_key_with_version is false' do
- it 'returns the key' do
- cache = described_class.new(namespace: nil, cache_key_with_version: false)
+ context 'when namespace is set' do
+ context 'when cache_key_with_version is true' do
+ it 'expands out the key with namespace and Rails version' do
+ cache = described_class.new(namespace: namespace, cache_key_with_version: true)
+
+ cache_key = cache.cache_key(key)
+
+ expect(cache_key).to eq("#{namespace}:#{key}:#{Gitlab::VERSION}:#{Rails.version}")
+ end
+ end
+
+ context 'when cache_key_with_version is false' do
+ it 'expands out the key with namespace' do
+ cache = described_class.new(namespace: namespace, cache_key_with_version: false)
- cache_key = cache.cache_key(key)
+ cache_key = cache.cache_key(key)
- expect(cache_key).to eq(key)
+ expect(cache_key).to eq("#{namespace}:#{key}")
+ end
end
end
end
@@ -106,6 +132,16 @@ describe Gitlab::JsonCache do
expect(cache.read(key)).to be_nil
end
+ context 'when the cached value is a boolean' do
+ it 'parses the cached value' do
+ allow(backend).to receive(:read)
+ .with(expanded_key)
+ .and_return(true)
+
+ expect(cache.read(key, BroadcastMessage)).to eq(true)
+ end
+ end
+
context 'when the cached value is a hash' do
it 'parses the cached value' do
allow(backend).to receive(:read)
diff --git a/spec/mailers/emails/pages_domains_spec.rb b/spec/mailers/emails/pages_domains_spec.rb
index 2f594dbf9d1310eaaab0d725ee1c343fa9fd26ca..eae83cd64d362c2b3eaba94fb444fa0cd8e852e9 100644
--- a/spec/mailers/emails/pages_domains_spec.rb
+++ b/spec/mailers/emails/pages_domains_spec.rb
@@ -9,7 +9,7 @@ describe Emails::PagesDomains do
set(:user) { project.creator }
shared_examples 'a pages domain email' do
- let(:test_recipient) { user }
+ let(:recipient) { user }
it_behaves_like 'an email sent to a user'
it_behaves_like 'an email sent from GitLab'
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index cbbb22ad78c0f9f49684056eb8d0ccb57256fdd0..a190f29d677bf7f094bdc6f985ec096613ba3b2d 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -45,7 +45,7 @@ describe Notify do
context 'for a project' do
shared_examples 'an assignee email' do
- let(:test_recipient) { assignee }
+ let(:recipient) { assignee }
it_behaves_like 'an email sent to a user'
@@ -55,7 +55,7 @@ describe Notify do
aggregate_failures do
expect(sender.display_name).to eq(current_user.name)
expect(sender.address).to eq(gitlab_sender)
- expect(subject).to deliver_to(assignee.email)
+ expect(subject).to deliver_to(recipient.notification_email)
end
end
end
@@ -559,12 +559,13 @@ describe Notify do
let(:host) { Gitlab.config.gitlab.host }
context 'in discussion' do
- set(:first_note) { create(:discussion_note_on_issue) }
- set(:second_note) { create(:discussion_note_on_issue, in_reply_to: first_note) }
- set(:third_note) { create(:discussion_note_on_issue, in_reply_to: second_note) }
+ set(:first_note) { create(:discussion_note_on_issue, project: project) }
+ set(:second_note) { create(:discussion_note_on_issue, in_reply_to: first_note, project: project) }
+ set(:third_note) { create(:discussion_note_on_issue, in_reply_to: second_note, project: project) }
subject { described_class.note_issue_email(recipient.id, third_note.id) }
+ it_behaves_like 'an email sent to a user'
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
@@ -584,10 +585,11 @@ describe Notify do
end
context 'individual issue comments' do
- set(:note) { create(:note_on_issue) }
+ set(:note) { create(:note_on_issue, project: project) }
subject { described_class.note_issue_email(recipient.id, note.id) }
+ it_behaves_like 'an email sent to a user'
it_behaves_like 'appearance header and footer enabled'
it_behaves_like 'appearance header and footer not enabled'
@@ -616,13 +618,13 @@ describe Notify do
it_behaves_like 'a user cannot unsubscribe through footer link'
it 'has the correct subject and body' do
- is_expected.to have_referable_subject(project_snippet, reply: true)
+ is_expected.to have_referable_subject(project_snippet, include_group: true, reply: true)
is_expected.to have_body_text project_snippet_note.note
end
end
describe 'project was moved' do
- let(:test_recipient) { user }
+ let(:recipient) { user }
subject { described_class.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
it_behaves_like 'an email sent to a user'
@@ -823,7 +825,7 @@ describe Notify do
it 'has the correct subject and body' do
aggregate_failures do
- is_expected.to have_subject("Re: #{project.name} | #{commit.title} (#{commit.short_id})")
+ is_expected.to have_subject("Re: #{project.name} | #{project.group.name} | #{commit.title} (#{commit.short_id})")
is_expected.to have_body_text(commit.short_id)
end
end
@@ -849,7 +851,7 @@ describe Notify do
it 'has the correct subject and body' do
aggregate_failures do
- is_expected.to have_referable_subject(merge_request, reply: true)
+ is_expected.to have_referable_subject(merge_request, include_group: true, reply: true)
is_expected.to have_body_text note_on_merge_request_path
end
end
@@ -875,7 +877,7 @@ describe Notify do
it 'has the correct subject and body' do
aggregate_failures do
- is_expected.to have_referable_subject(issue, reply: true)
+ is_expected.to have_referable_subject(issue, include_group: true, reply: true)
is_expected.to have_body_text(note_on_issue_path)
end
end
@@ -939,7 +941,7 @@ describe Notify do
it_behaves_like 'appearance header and footer not enabled'
it 'has the correct subject' do
- is_expected.to have_subject "Re: #{project.name} | #{commit.title} (#{commit.short_id})"
+ is_expected.to have_subject "Re: #{project.name} | #{project.group.name} | #{commit.title} (#{commit.short_id})"
end
it 'contains a link to the commit' do
@@ -967,7 +969,7 @@ describe Notify do
it_behaves_like 'appearance header and footer not enabled'
it 'has the correct subject' do
- is_expected.to have_referable_subject(merge_request, reply: true)
+ is_expected.to have_referable_subject(merge_request, include_group: true, reply: true)
end
it 'contains a link to the merge request note' do
@@ -995,7 +997,7 @@ describe Notify do
it_behaves_like 'appearance header and footer not enabled'
it 'has the correct subject' do
- is_expected.to have_referable_subject(issue, reply: true)
+ is_expected.to have_referable_subject(issue, include_group: true, reply: true)
end
it 'contains a link to the issue note' do
diff --git a/spec/migrations/backport_enterprise_schema_spec.rb b/spec/migrations/backport_enterprise_schema_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8d2d9d4953a6816fd69f019f6ba6d140d615ac57
--- /dev/null
+++ b/spec/migrations/backport_enterprise_schema_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require Rails.root.join('db', 'migrate', '20190402150158_backport_enterprise_schema.rb')
+
+describe BackportEnterpriseSchema, :migration, schema: 20190329085614 do
+ include MigrationsHelpers
+
+ def drop_if_exists(table)
+ active_record_base.connection.drop_table(table) if active_record_base.connection.table_exists?(table)
+ end
+
+ describe '#up' do
+ it 'creates new EE tables' do
+ migrate!
+
+ expect(active_record_base.connection.table_exists?(:epics)).to be true
+ expect(active_record_base.connection.table_exists?(:geo_nodes)).to be true
+ end
+
+ context 'missing EE columns' do
+ before do
+ drop_if_exists(:epics)
+
+ active_record_base.connection.create_table "epics" do |t|
+ t.integer :group_id, null: false, index: true
+ t.integer :author_id, null: false, index: true
+ end
+ end
+
+ after do
+ drop_if_exists(:epics)
+ end
+
+ it 'flags an error' do
+ expect { migrate! }.to raise_error(/Your database is missing.*that is present for GitLab EE/)
+ end
+ end
+ end
+end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index a5c7e9db2a15b4d2a45f4447c5b4f5309b8af5d9..d5b016dc8f6eacb8e484766648432394d0d20781 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -862,4 +862,13 @@ describe Issue do
end
end
end
+
+ describe "#labels_hook_attrs" do
+ let(:label) { create(:label) }
+ let(:issue) { create(:labeled_issue, labels: [label]) }
+
+ it "returns a list of label hook attributes" do
+ expect(issue.labels_hook_attrs).to eq([label.hook_attrs])
+ end
+ end
end
diff --git a/spec/models/project_services/microsoft_teams_service_spec.rb b/spec/models/project_services/microsoft_teams_service_spec.rb
index c025d7c882ef7740032c8fddb7f6cfd7853abc5d..3ffe633868f42a917e4bb073271ed59df0dcbac4 100644
--- a/spec/models/project_services/microsoft_teams_service_spec.rb
+++ b/spec/models/project_services/microsoft_teams_service_spec.rb
@@ -289,6 +289,18 @@ describe MicrosoftTeamsService do
expect(result).to be_falsy
end
end
+
+ context 'when disabled' do
+ let(:pipeline) do
+ create(:ci_pipeline, :failed, project: project, ref: 'not-the-default-branch')
+ end
+
+ before do
+ chat_service.notify_only_default_branch = false
+ end
+
+ it_behaves_like 'call Microsoft Teams API'
+ end
end
end
end
diff --git a/spec/serializers/merge_request_widget_entity_spec.rb b/spec/serializers/merge_request_widget_entity_spec.rb
index a27c22191f4ec44e538a30dbdb84e6ae72d4b10b..ffbfac9b3269f12161e26cdb644ecf792c206fc3 100644
--- a/spec/serializers/merge_request_widget_entity_spec.rb
+++ b/spec/serializers/merge_request_widget_entity_spec.rb
@@ -32,6 +32,19 @@ describe MergeRequestWidgetEntity do
end
end
+ describe 'issues links' do
+ it 'includes issues links when requested' do
+ data = described_class.new(resource, request: request, issues_links: true).as_json
+
+ expect(data).to include(:issues_links)
+ expect(data[:issues_links]).to include(:assign_to_closing, :closing, :mentioned_but_not_closing)
+ end
+
+ it 'omits issue links by default' do
+ expect(subject).not_to include(:issues_links)
+ end
+ end
+
describe 'pipeline' do
let(:pipeline) { create(:ci_empty_pipeline, project: project, ref: resource.source_branch, sha: resource.source_branch_sha, head_pipeline_of: resource) }
diff --git a/spec/support/helpers/email_helpers.rb b/spec/support/helpers/email_helpers.rb
index ed049daba80d7cd3f67433ecc695914e6fda9fe4..a7175491fa0767bf2ca37fdbda43f664972ffae2 100644
--- a/spec/support/helpers/email_helpers.rb
+++ b/spec/support/helpers/email_helpers.rb
@@ -37,8 +37,19 @@ module EmailHelpers
ActionMailer::Base.deliveries.find { |d| d.to.include?(user.notification_email) }
end
- def have_referable_subject(referable, include_project: true, reply: false)
- prefix = (include_project && referable.project ? "#{referable.project.name} | " : '').freeze
+ def have_referable_subject(referable, include_project: true, include_group: false, reply: false)
+ context = []
+
+ context << referable.project.name if include_project && referable.project
+ context << referable.project.group.name if include_group && referable.project.group
+
+ prefix =
+ if context.any?
+ context.join(' | ') + ' | '
+ else
+ ''
+ end
+
prefix = "Re: #{prefix}" if reply
suffix = "#{referable.title} (#{referable.to_reference})"
diff --git a/spec/support/shared_examples/notify_shared_examples.rb b/spec/support/shared_examples/notify_shared_examples.rb
index 897c9106d772c1d062ca5080a0dee02afd50b931..4d43317e17ef861d9b0ca338b732a3f28cff15f5 100644
--- a/spec/support/shared_examples/notify_shared_examples.rb
+++ b/spec/support/shared_examples/notify_shared_examples.rb
@@ -45,18 +45,18 @@ shared_examples 'an email sent to a user' do
let(:group_notification_email) { 'user+group@example.com' }
it 'is sent to user\'s global notification email address' do
- expect(subject).to deliver_to(test_recipient.notification_email)
+ expect(subject).to deliver_to(recipient.notification_email)
end
context 'that is part of a project\'s group' do
it 'is sent to user\'s group notification email address when set' do
- create(:notification_setting, user: test_recipient, source: project.group, notification_email: group_notification_email)
+ create(:notification_setting, user: recipient, source: project.group, notification_email: group_notification_email)
expect(subject).to deliver_to(group_notification_email)
end
it 'is sent to user\'s global notification email address when no group email set' do
- create(:notification_setting, user: test_recipient, source: project.group, notification_email: '')
- expect(subject).to deliver_to(test_recipient.notification_email)
+ create(:notification_setting, user: recipient, source: project.group, notification_email: '')
+ expect(subject).to deliver_to(recipient.notification_email)
end
end
@@ -67,17 +67,17 @@ shared_examples 'an email sent to a user' do
it 'is sent to user\'s subgroup notification email address when set' do
# Set top-level group notification email address to make sure it doesn't get selected
- create(:notification_setting, user: test_recipient, source: group, notification_email: group_notification_email)
+ create(:notification_setting, user: recipient, source: group, notification_email: group_notification_email)
subgroup_notification_email = 'user+subgroup@example.com'
- create(:notification_setting, user: test_recipient, source: subgroup, notification_email: subgroup_notification_email)
+ create(:notification_setting, user: recipient, source: subgroup, notification_email: subgroup_notification_email)
expect(subject).to deliver_to(subgroup_notification_email)
end
it 'is sent to user\'s group notification email address when set and subgroup email address not set' do
- create(:notification_setting, user: test_recipient, source: subgroup, notification_email: '')
- expect(subject).to deliver_to(test_recipient.notification_email)
+ create(:notification_setting, user: recipient, source: subgroup, notification_email: '')
+ expect(subject).to deliver_to(recipient.notification_email)
end
end
end