diff --git a/notifier/.rubocop.yml b/notifier/.rubocop.yml index 51789bd034ec9bbaceee82f768d7eed1748c51a8..f47462ca976fca63e304b04ba54dc4cacc26d8a4 100644 --- a/notifier/.rubocop.yml +++ b/notifier/.rubocop.yml @@ -12,7 +12,7 @@ Performance/OpenStruct: Enabled: false RSpec/MultipleMemoizedHelpers: - Max: 12 + Max: 13 # This is due to a bug in RuboCop. # I filed an issue with the maintainer of RuboCop: https://github.com/rubocop/rubocop/issues/13458 diff --git a/notifier/spec/table_size_service_spec.rb b/notifier/spec/table_size_service_spec.rb index 65a86cd930e98ac65f0cd35cd2a60c9fd6574145..2faa8ae046721078f5badddeb179b7f298d1d72e 100644 --- a/notifier/spec/table_size_service_spec.rb +++ b/notifier/spec/table_size_service_spec.rb @@ -82,10 +82,14 @@ RSpec.describe TableSizeService do end context 'when issue already exists' do - let(:issue_double) { instance_double('issue', iid: 1, state: 'opened', labels: 'label') } + let(:issue_double) do + instance_double('issue', iid: 1, state: 'opened', labels: 'label', description: 'description') + end + let(:issues) { instance_double('issues', any?: true, first: issue_double) } let(:gitlab_response) { [issue_double] } let(:state_param) { { state: 'opened' } } + let(:note_response) { instance_double('note', noteable_iid: 1) } include_examples 'when making gitlab issues request', state: 'opened' @@ -97,6 +101,23 @@ RSpec.describe TableSizeService do ) execute end + + context 'when classification has escalated' do + before do + allow(service).to receive(:classification_escalated?).with(issue_double, anything).and_return(true) + allow(gitlab_client).to receive(:create_issue_note).and_return(note_response) + end + + it 'adds a note about classification escalation' do + expect(gitlab_client).to receive(:create_issue_note).with( + project_path, + issue_double.iid, + include('Table Size Classification Escalated') + ) + + execute + end + end end context 'when closed issue exists' do diff --git a/notifier/table_size_service.rb b/notifier/table_size_service.rb index 83fb6b8204ec216283b5ee9722c10587c941cc58..81b867400af644217ebcbca5369dd257e2a4e792 100644 --- a/notifier/table_size_service.rb +++ b/notifier/table_size_service.rb @@ -10,6 +10,12 @@ class TableSizeService large: 'severity::3', medium: 'severity::4' }.freeze + CLASSIFICATION_RANKING = { + medium: 1, + large: 2, + over_limit: 3 + }.freeze + CLASSIFICATION_PATTERN = /\|\s*`([^`]+)`\s*\|\s*$/.freeze Issue = Struct.new(:table_metadata) do def title @@ -43,6 +49,7 @@ class TableSizeService next if already_closed?(gitlab_issue.first) response = edit_issue(gitlab_issue.first, issue.description, table_metadata) + add_note(gitlab_issue.first, table_metadata) if classification_escalated?(gitlab_issue.first, table_metadata) puts "Issue updated successfully for #{table_metadata['table_name']} " \ "at https://gitlab.com/gitlab-org/gitlab/-/issues/#{response.iid}\n" @@ -114,4 +121,52 @@ class TableSizeService def search_identifier(identifier) OpenSSL::Digest::SHA256.hexdigest(identifier) end + + def extract_classification_from_description(description) + return nil unless description + return unless match = description.match(CLASSIFICATION_PATTERN) + + match[1] + end + + def classification_escalated?(issue, table_metadata) + old_classification = extract_classification_from_description(issue.description) + new_classification = table_metadata['classification'] + + return false unless old_classification && new_classification + + old_rank = CLASSIFICATION_RANKING[old_classification.to_sym] || 0 + new_rank = CLASSIFICATION_RANKING[new_classification.to_sym] || 0 + + new_rank > old_rank + end + + def add_note(issue, table_metadata) + old_classification = extract_classification_from_description(issue.description) + new_classification = table_metadata['classification'] + + note_text = <<~TEXT + ## 🔔 Table Size Classification Escalated + + The classification for table `uploads` has escalated from `#{old_classification}` to `#{new_classification}`. + + ### Recommended Actions + + - Review recent growth patterns + - Implement retention policies + - Consider data optimization techniques + + Need help? Contact us in [#database-sustainability](https://gitlab.enterprise.slack.com/archives/C08GQHWGM0S). + + cc @gitlab-org/database-team/triage + TEXT + + response = gitlab_client.create_issue_note( + project_path, + issue.iid, + note_text + ) + + puts "Classification escalated for issue https://gitlab.com/gitlab-org/gitlab/-/issues/#{response.noteable_iid}\n" + end end