diff --git a/Gemfile b/Gemfile
index 8ca232fc1e624bb846c52eea3a4ff60c74e4f1e7..c554d509d0efb04ee3a32145b32c46347618c902 100644
--- a/Gemfile
+++ b/Gemfile
@@ -436,7 +436,7 @@ group :test do
   gem 'capybara-screenshot', '~> 1.0.22'
   gem 'selenium-webdriver', '~> 3.142'
 
-  gem 'shoulda-matchers', '~> 4.0.1', require: false
+  gem 'shoulda-matchers', '~> 5.1.0', require: false
   gem 'email_spec', '~> 2.2.0'
   gem 'webmock', '~> 3.9.1'
   gem 'rails-controller-testing'
diff --git a/Gemfile.lock b/Gemfile.lock
index 2c6a35fe072d5154011282de227e2e9704e54171..dd2b7196115a32a38599a0b1c685fdea292393dd 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1225,8 +1225,8 @@ GEM
     settingslogic (2.0.9)
     sexp_processor (4.15.1)
     shellany (0.0.1)
-    shoulda-matchers (4.0.1)
-      activesupport (>= 4.2.0)
+    shoulda-matchers (5.1.0)
+      activesupport (>= 5.2.0)
     sidekiq (6.4.0)
       connection_pool (>= 2.2.2)
       rack (~> 2.0)
@@ -1690,7 +1690,7 @@ DEPENDENCIES
   sentry-ruby (~> 5.1.1)
   sentry-sidekiq (~> 5.1.1)
   settingslogic (~> 2.0.9)
-  shoulda-matchers (~> 4.0.1)
+  shoulda-matchers (~> 5.1.0)
   sidekiq (~> 6.4)
   sidekiq-cron (~> 1.2)
   sigdump (~> 0.2.4)
diff --git a/app/models/incident_management/issuable_escalation_status.rb b/app/models/incident_management/issuable_escalation_status.rb
index fc881e62efdbb988252c0c119ad5d4bfd4aea2d2..3c581f0489add695a3d878e6482dca4b62065773 100644
--- a/app/models/incident_management/issuable_escalation_status.rb
+++ b/app/models/incident_management/issuable_escalation_status.rb
@@ -7,7 +7,7 @@ class IssuableEscalationStatus < ApplicationRecord
     self.table_name = 'incident_management_issuable_escalation_statuses'
 
     belongs_to :issue
-    has_one :project, through: :issue, inverse_of: :incident_management_issuable_escalation_status
+    has_one :project, through: :issue, inverse_of: :incident_management_issuable_escalation_statuses
 
     validates :issue, presence: true, uniqueness: true
 
diff --git a/app/models/project.rb b/app/models/project.rb
index ea227743855dca7149e4af6c3f71bb55d9ad12dc..110f400d3ece3ec1bdb31406b6f39c5ef08c775a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -260,6 +260,7 @@ def self.integration_association_name(name)
   has_many :merge_request_metrics, foreign_key: 'target_project', class_name: 'MergeRequest::Metrics', inverse_of: :target_project
   has_many :source_of_merge_requests, foreign_key: 'source_project_id', class_name: 'MergeRequest'
   has_many :issues
+  has_many :incident_management_issuable_escalation_statuses, through: :issues, inverse_of: :project, class_name: 'IncidentManagement::IssuableEscalationStatus'
   has_many :labels, class_name: 'ProjectLabel'
   has_many :integrations
   has_many :events
diff --git a/ee/app/models/ee/iteration.rb b/ee/app/models/ee/iteration.rb
index 0501b4b16cf772467433c7df96974f1e9fc29d98..c493b7ec8f007db82a5c9c832a8ae93998658ba8 100644
--- a/ee/app/models/ee/iteration.rb
+++ b/ee/app/models/ee/iteration.rb
@@ -37,6 +37,7 @@ def self.by_id(id)
       belongs_to :iterations_cadence, class_name: '::Iterations::Cadence', foreign_key: :iterations_cadence_id, inverse_of: :iterations
 
       has_many :issues, foreign_key: 'sprint_id'
+      has_many :labels, -> { distinct.reorder('labels.title') }, through: :issues
       has_many :merge_requests, foreign_key: 'sprint_id'
 
       has_internal_id :iid, scope: :project
diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml
index 5a1787218f54090c8b02e6d218e57e7a01d5ffa5..50ff6146174fb3337e40710e9058a984d5995925 100644
--- a/lib/gitlab/import_export/project/import_export.yml
+++ b/lib/gitlab/import_export/project/import_export.yml
@@ -761,6 +761,7 @@ excluded_attributes:
     - :exported_protected_branches
     - :repository_size_limit
     - :external_webhook_token
+    - :incident_management_issuable_escalation_statuses
   namespaces:
     - :runners_token
     - :runners_token_encrypted
@@ -819,6 +820,7 @@ excluded_attributes:
     - :upvotes_count
     - :work_item_type_id
     - :email_message_id
+    - :incident_management_issuable_escalation_status
   merge_request: &merge_request_excluded_definition
     - :milestone_id
     - :sprint_id
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 926347772514e007ca1073297ff7528a7be24a6a..6a49e47e7614b2cf5a5df59c2c6593ab76e9b2b0 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -603,6 +603,7 @@ project:
 - incident_management_oncall_schedules
 - incident_management_oncall_rotations
 - incident_management_escalation_policies
+- incident_management_issuable_escalation_statuses
 - debian_distributions
 - merge_request_metrics
 - security_orchestration_policy_configuration
diff --git a/spec/models/incident_management/issuable_escalation_status_spec.rb b/spec/models/incident_management/issuable_escalation_status_spec.rb
index f956be3a04e9bcf5b4fd2f8e432c033ca898b94d..39d1fb325f53cef8480862100b259c753a6dcd9b 100644
--- a/spec/models/incident_management/issuable_escalation_status_spec.rb
+++ b/spec/models/incident_management/issuable_escalation_status_spec.rb
@@ -11,7 +11,9 @@
 
   describe 'associations' do
     it { is_expected.to belong_to(:issue) }
-    it { is_expected.to have_one(:project).through(:issue) }
+    it do
+      is_expected.to have_one(:project).through(:issue).inverse_of(:incident_management_issuable_escalation_statuses)
+    end
   end
 
   describe 'validatons' do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index d2e281234fbb11667bf0802bccbac166fef163c9..80a37ff0d8060a80daa4ad001706fe0fed56a956 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -27,6 +27,7 @@
     it { is_expected.to have_many(:merge_requests) }
     it { is_expected.to have_many(:merge_request_metrics).class_name('MergeRequest::Metrics') }
     it { is_expected.to have_many(:issues) }
+    it { is_expected.to have_many(:incident_management_issuable_escalation_statuses).through(:issues).inverse_of(:project).class_name('IncidentManagement::IssuableEscalationStatus') }
     it { is_expected.to have_many(:milestones) }
     it { is_expected.to have_many(:iterations) }
     it { is_expected.to have_many(:project_members).dependent(:delete_all) }
diff --git a/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb b/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
index a2b4cdc33d057815853053eb90c2e583e9fbc26e..d06e8391a9a071d254b138013f7c8c35e449e123 100644
--- a/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
@@ -82,7 +82,7 @@
     it { is_expected.to belong_to(:group) }
     it { is_expected.to have_many(:issues) }
     it { is_expected.to have_many(:merge_requests) }
-    it { is_expected.to have_many(:labels) }
+    it { is_expected.to have_many(:labels).through(:issues) }
   end
 
   describe '#timebox_name' do