@@ -21,21 +21,27 @@ class Integration < ApplicationRecord
21
21
INTEGRATION_NAMES = %w[
22
22
asana assembla bamboo bugzilla buildkite campfire clickup confluence custom_issue_tracker
23
23
datadog diffblue_cover discord drone_ci emails_on_push ewm external_wiki
24
- gitlab_slack_application hangouts_chat harbor irker jira jira_cloud_app matrix
24
+ gitlab_slack_application hangouts_chat harbor irker jira matrix
25
25
mattermost mattermost_slash_commands microsoft_teams packagist phorge pipelines_email
26
26
pivotaltracker prometheus pumble pushover redmine slack slack_slash_commands squash_tm teamcity telegram
27
27
unify_circuit webex_teams youtrack zentao
28
28
] . freeze
29
29
30
- INSTANCE_SPECIFIC_INTEGRATION_NAMES = %w[
30
+ # Integrations that can only be enabled on the instance-level
31
+ INSTANCE_LEVEL_ONLY_INTEGRATION_NAMES = %w[
31
32
beyond_identity
32
33
] . freeze
33
34
34
- # See: https://gitlab.com/gitlab-org/gitlab/-/issues/345677
35
- PROJECT_SPECIFIC_INTEGRATION_NAMES = %w[
35
+ # Integrations that can only be enabled on the project-level
36
+ PROJECT_LEVEL_ONLY_INTEGRATION_NAMES = %w[
36
37
apple_app_store google_play jenkins
37
38
] . freeze
38
39
40
+ # Integrations that cannot be enabled on the instance-level
41
+ PROJECT_AND_GROUP_LEVEL_ONLY_INTEGRATION_NAMES = %w[
42
+ jira_cloud_app
43
+ ] . freeze
44
+
39
45
# Fake integrations to help with local development.
40
46
DEV_INTEGRATION_NAMES = %w[
41
47
mock_ci mock_monitoring
@@ -134,7 +140,7 @@ def properties=(props)
134
140
}
135
141
136
142
scope :for_instance , -> {
137
- types = available_integration_types ( include_project_specific : false , include_instance_specific : true )
143
+ types = available_integration_types ( include_project_specific : false , include_group_specific : false )
138
144
where ( instance : true , type : types )
139
145
}
140
146
@@ -285,14 +291,18 @@ def self.event_description(event)
285
291
end
286
292
287
293
def self . find_or_initialize_non_project_specific_integration ( name , instance : false , group_id : nil )
288
- return unless name . in? ( available_integration_names ( include_project_specific : false ,
294
+ return unless name . in? ( available_integration_names (
295
+ include_project_specific : false ,
296
+ include_group_specific : group_id . present? ,
289
297
include_instance_specific : instance ) )
290
298
291
299
integration_name_to_model ( name ) . find_or_initialize_by ( instance : instance , group_id : group_id )
292
300
end
293
301
294
302
def self . find_or_initialize_all_non_project_specific ( scope , include_instance_specific : false )
295
- scope + build_nonexistent_integrations_for ( scope , include_instance_specific : include_instance_specific )
303
+ scope + build_nonexistent_integrations_for ( scope ,
304
+ include_group_specific : !include_instance_specific ,
305
+ include_instance_specific : include_instance_specific )
296
306
end
297
307
298
308
def self . build_nonexistent_integrations_for ( ...)
@@ -304,11 +314,12 @@ def self.build_nonexistent_integrations_for(...)
304
314
305
315
# Returns a list of integration types that do not exist in the given scope.
306
316
# Example: ["AsanaService", ...]
307
- def self . nonexistent_integration_types_for ( scope , include_instance_specific : false )
317
+ def self . nonexistent_integration_types_for ( scope , include_group_specific : false , include_instance_specific : false )
308
318
# Using #map instead of #pluck to save one query count. This is because
309
319
# ActiveRecord loaded the object here, so we don't need to query again later.
310
320
available_integration_types (
311
321
include_project_specific : false ,
322
+ include_group_specific : include_group_specific ,
312
323
include_instance_specific : include_instance_specific
313
324
) - scope . map ( &:type )
314
325
end
@@ -317,12 +328,14 @@ def self.nonexistent_integration_types_for(scope, include_instance_specific: fal
317
328
# Returns a list of available integration names.
318
329
# Example: ["asana", ...]
319
330
def self . available_integration_names (
320
- include_project_specific : true , include_dev : true , include_instance_specific : true , include_disabled : false
331
+ include_project_specific : true , include_group_specific : true , include_instance_specific : true , include_dev : true ,
332
+ include_disabled : false
321
333
)
322
- names = integration_names
323
- names += project_specific_integration_names if include_project_specific
324
- names += dev_integration_names if include_dev
325
- names += instance_specific_integration_names if include_instance_specific
334
+ names = integration_names . dup
335
+ names . concat ( project_specific_integration_names ) if include_project_specific
336
+ names . concat ( dev_integration_names ) if include_dev
337
+ names . concat ( instance_specific_integration_names ) if include_instance_specific
338
+ names . concat ( project_and_group_specific_integration_names ) if include_project_specific || include_group_specific
326
339
names -= disabled_integration_names unless include_disabled
327
340
328
341
names . sort_by ( &:downcase )
@@ -336,13 +349,11 @@ def self.integration_names
336
349
names . delete ( 'gitlab_slack_application' )
337
350
end
338
351
339
- names . delete ( 'jira_cloud_app' ) unless Feature . enabled? ( :enable_jira_connect_configuration ) # rubocop:disable Gitlab/FeatureFlagWithoutActor -- flag must be global
340
-
341
352
names
342
353
end
343
354
344
355
def self . instance_specific_integration_names
345
- INSTANCE_SPECIFIC_INTEGRATION_NAMES
356
+ INSTANCE_LEVEL_ONLY_INTEGRATION_NAMES
346
357
end
347
358
348
359
def self . instance_specific_integration_types
@@ -356,7 +367,7 @@ def self.dev_integration_names
356
367
end
357
368
358
369
def self . project_specific_integration_names
359
- names = PROJECT_SPECIFIC_INTEGRATION_NAMES . dup
370
+ names = PROJECT_LEVEL_ONLY_INTEGRATION_NAMES . dup
360
371
361
372
if Feature . disabled? ( :gitlab_for_slack_app_instance_and_group_level , type : :beta ) &&
362
373
( Gitlab ::CurrentSettings . slack_app_enabled || Gitlab . dev_or_test_env? )
@@ -366,6 +377,13 @@ def self.project_specific_integration_names
366
377
names
367
378
end
368
379
380
+ def self . project_and_group_specific_integration_names
381
+ names = PROJECT_AND_GROUP_LEVEL_ONLY_INTEGRATION_NAMES . dup
382
+ names . delete ( 'jira_cloud_app' ) unless Feature . enabled? ( :enable_jira_connect_configuration ) # rubocop:disable Gitlab/FeatureFlagWithoutActor -- flag must be global
383
+ names
384
+ end
385
+ private_class_method :project_and_group_specific_integration_names
386
+
369
387
# Returns a list of available integration types.
370
388
# Example: ["Integrations::Asana", ...]
371
389
def self . available_integration_types ( ...)
0 commit comments