Delete the issue_email_participants feature flag
This feature flag was introduced in 13.8, which is more than 4 milestones ago.
As part of our process we want to ensure feature flags don't stay too long in the codebase.
Rollout issue: #350460
Remaining mentions of the feature flag (click to expand)
app/services/issue_email_participants/create_service.rb
10: return error_feature_flag unless Feature.enabled?(:issue_email_participants, target.project)
app/services/service_desk_settings/update_service.rb
12: # No longer need to apply feature flag restrictions for issue_email_participants
29: return if feature_flag != :issue_email_participants && Feature.enabled?(feature_flag, project)
30: return unless params.include?(field) && feature_flag != :issue_email_participants
doc/user/project/service_desk/external_participants.md
131:- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350460) in GitLab 13.8 [with a flag](../../feature_flags.md) named `issue_email_participants`. Enabled by default.
163:- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350460) in GitLab 13.8 [with a flag](../../feature_flags.md) named `issue_email_participants`. Enabled by default.
spec/features/projects/settings/service_desk_setting_spec.rb
106: # The test for the removed feature flag 'issue_email_participants' is no longer needed
.rubocop_todo/gitlab/bounded_contexts.yml
1582: - 'app/services/issue_email_participants/base_service.rb'
1583: - 'app/services/issue_email_participants/create_service.rb'
1584: - 'app/services/issue_email_participants/destroy_service.rb'
CHANGELOG.md
2517:- [Add NOT NULL for sharding key on issue_email_participants](https://gitlab.com/gitlab-org/gitlab/-/commit/58ceeb4876c4dc88f889f402e6fef9502cc6ebb2) ([merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/189213))
6972:- [Add and backfill namespace_id for issue_email_participants](https://gitlab.com/gitlab-org/gitlab/-/commit/123cce5cd0c2672a79ee1182a82a1363e909f935) ([merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/174506))
app/assets/javascripts/notes/components/comment_field_layout.vue
63: return this.noteableData.issue_email_participants?.map(({ email }) => email) || [];
app/assets/javascripts/notes/components/note_form.vue
377: return this.getNoteableData.issue_email_participants?.length;
app/assets/javascripts/work_items/components/notes/work_item_comment_form.vue
195: issue_email_participants: this.emailParticipants,
app/graphql/types/work_items/widgets/email_participants_type.rb
19: method: :issue_email_participants
app/mailers/emails/service_desk.rb
155: issue_email_participant = @issue.issue_email_participants.find_by_email(@issue.external_author)
app/models/issue.rb
93: has_many :issue_email_participants
94: alias_method :email_participants, :issue_email_participants
746: issue_email_participants.pluck(:email)
750: issue_email_participants.pluck(IssueEmailParticipant.arel_table[:email].lower)
app/models/work_items/widgets/email_participants.rb
6: delegate :issue_email_participants, to: :work_item
8: alias_method :email_participants, :issue_email_participants
app/presenters/issue_presenter.rb
34: delegator_override :issue_email_participants
35: def issue_email_participants
36: issue.issue_email_participants.present(current_user: current_user)
app/presenters/note_presenter.rb
40: return text if object.system_note_metadata&.action != 'issue_email_participants'
app/serializers/issue_entity.rb
91: expose :issue_email_participants do |issue|
94: presented_issue.issue_email_participants.map do |participant|
app/services/issue_email_participants/create_service.rb
10: return error_feature_flag unless Feature.enabled?(:issue_email_participants, target.project)
43: new_participant = target.issue_email_participants.create(email: email)
app/services/issue_email_participants/destroy_service.rb
23: .issue_email_participants
app/services/notification_service.rb
909: recipients = issue.issue_email_participants
app/services/service_desk_settings/update_service.rb
12: # No longer need to apply feature flag restrictions for issue_email_participants
29: return if feature_flag != :issue_email_participants && Feature.enabled?(feature_flag, project)
30: return unless params.include?(field) && feature_flag != :issue_email_participants
app/services/system_notes/issuables_service.rb
445: create_note(NoteSummary.new(noteable, project, author, body, action: 'issue_email_participants'))
changelogs/archive-13.md
2568:- Populate and migrate issue_email_participants. !48711 (Lee Tickett @leetickett)
5017:- Add issue_email_participants table and related model. !42943
db/docs/batched_background_migrations/backfill_issue_email_participants_namespace_id.yml
3:description: Backfills sharding key `issue_email_participants.namespace_id` from `issues`.
db/docs/issue_email_participants.yml
2:table_name: issue_email_participants
db/init_structure.sql
10135:CREATE TABLE issue_email_participants (
10144:CREATE SEQUENCE issue_email_participants_id_seq
10151:ALTER SEQUENCE issue_email_participants_id_seq OWNED BY issue_email_participants.id;
19060:ALTER TABLE ONLY issue_email_participants ALTER COLUMN id SET DEFAULT nextval('issue_email_participants_id_seq'::regclass);
21238:ALTER TABLE ONLY issue_email_participants
21239: ADD CONSTRAINT issue_email_participants_pkey PRIMARY KEY (id);
25471:CREATE UNIQUE INDEX index_issue_email_participants_on_issue_id_and_lower_email ON issue_email_participants USING btree (issue_id, lower(email));
29986: ADD CONSTRAINT fk_7d7663e36a FOREIGN KEY (issue_email_participant_id) REFERENCES issue_email_participants(id) ON DELETE SET NULL NOT VALID;
30759:ALTER TABLE ONLY issue_email_participants
db/migrate/20241203075616_add_namespace_id_to_issue_email_participants.rb
7: add_column :issue_email_participants, :namespace_id, :bigint
db/post_migrate/20240709014000_fix_sequence_owners_for_ci_builds.rb
317: ['issue_email_participants_id_seq', 'issue_email_participants.id'],
db/post_migrate/20241203075617_index_issue_email_participants_on_namespace_id.rb
7: INDEX_NAME = 'index_issue_email_participants_on_namespace_id'
10: add_concurrent_index :issue_email_participants, :namespace_id, name: INDEX_NAME
14: remove_concurrent_index_by_name :issue_email_participants, INDEX_NAME
db/post_migrate/20241203075618_add_issue_email_participants_namespace_id_fk.rb
8: add_concurrent_foreign_key :issue_email_participants, :namespaces, column: :namespace_id, on_delete: :cascade
13: remove_foreign_key :issue_email_participants, column: :namespace_id
db/post_migrate/20241203075619_add_issue_email_participants_namespace_id_trigger.rb
8: table: :issue_email_participants,
18: table: :issue_email_participants,
db/post_migrate/20241203075620_queue_backfill_issue_email_participants_namespace_id.rb
15: :issue_email_participants,
30: :issue_email_participants,
db/post_migrate/20250421231526_finalize_hk_backfill_issue_email_participants_namespace_id.rb
13: table_name: :issue_email_participants,
db/post_migrate/20250424180146_add_issue_email_participants_namespace_id_not_null.rb
8: add_not_null_constraint :issue_email_participants, :namespace_id
12: remove_not_null_constraint :issue_email_participants, :namespace_id
db/post_migrate/20250425082347_fix_seq_ownership_for_build_metadata.rb
352: ['issue_email_participants_id_seq', 'issue_email_participants.id'],
db/post_migrate/20250612143426_add_partitioned_fk_to_sent_notifications_issue_email_participant_id.rb
12: :issue_email_participants,
22: :issue_email_participants,
doc-locale/ja-jp/user/project/quick_actions.md
59:| `/add_email email1 email2` | {{< icon name="check-circle" >}} はい | {{< icon name="dotted-circle" >}} いいえ | {{< icon name="dotted-circle" >}} いいえ | 最大6人の[メール参加者](service_desk/external_participants.md)を追加します。このアクションは、機能フラグ `issue_email_participants` の背後にあります。[イシューテンプレート](description_templates.md)ではサポートされていません。 |
109:| `/remove_email email1 email2` | {{< icon name="check-circle" >}} はい | {{< icon name="dotted-circle" >}} いいえ | {{< icon name="dotted-circle" >}} いいえ | 最大6人の[メール参加者](service_desk/external_participants.md)を削除します。このアクションは、機能フラグ `issue_email_participants` の背後にあります。イシューテンプレート、マージリクエスト、またはエピックではサポートされていません。 |
doc/user/project/quick_actions.md
158:> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/350460) in GitLab 18.4. Feature flag `issue_email_participants` removed.
doc/user/project/service_desk/external_participants.md
131:- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350460) in GitLab 13.8 [with a flag](../../feature_flags.md) named `issue_email_participants`. Enabled by default.
132:> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/350460) in GitLab 18.4. Feature flag `issue_email_participants` removed.
163:- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350460) in GitLab 13.8 [with a flag](../../feature_flags.md) named `issue_email_participants`. Enabled by default.
164:> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/350460) in GitLab 18.4. Feature flag `issue_email_participants` removed.
lib/gitlab/background_migration/backfill_issue_email_participants_namespace_id.rb
6: operation_name :backfill_issue_email_participants_namespace_id
lib/gitlab/email/handler/service_desk_handler.rb
230: @issue.issue_email_participants.create(email: from_address)
lib/gitlab/quick_actions/issue_actions.rb
253: quick_action_target.issue_email_participants.any?
spec/controllers/projects/issues_controller_spec.rb
183: 'issue_email_participants' => contain_exactly(
196: expect(json_response).to include('issue_email_participants' => [])
spec/controllers/sent_notifications_controller_spec.rb
15: issue.issue_email_participants.create!(email: email)
95: expect { force_unsubscribe }.not_to change { issue.issue_email_participants.count }
111: expect { perform_request }.to change { issue.issue_email_participants.count }.by(-1)
129: expect { perform_request }.to change { issue.issue_email_participants.count }.by(-1)
139: expect { perform_request }.not_to change { issue.issue_email_participants.count }
217: expect { unsubscribe }.not_to change { issue.issue_email_participants.count }
388: expect { unsubscribe }.not_to change { issue.issue_email_participants.count }
spec/features/projects/settings/service_desk_setting_spec.rb
106: # The test for the removed feature flag 'issue_email_participants' is no longer needed
spec/frontend/notes/components/comment_field_layout_spec.js
117: issue_email_participants: [
146: issue_email_participants: [{ email: 'someone@gitlab.com' }],
spec/frontend/work_items/components/notes/work_item_comment_form_spec.js
170: issue_email_participants: [],
245: expect(findCommentFieldLayout().props('noteableData').issue_email_participants).toEqual([
256: expect(findCommentFieldLayout().props('noteableData').issue_email_participants).toEqual(
spec/graphql/types/notes/note_type_spec.rb
57: context 'when system note with issue_email_participants action', feature_category: :service_desk do
66: let_it_be(:system_note_metadata) { create(:system_note_metadata, note: note, action: :issue_email_participants) }
spec/lib/gitlab/background_migration/backfill_issue_email_participants_namespace_id_spec.rb
9: let(:batch_table) { :issue_email_participants }
spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
21: let(:issue_email_participants_count) { 1 }
58: expect(new_issue.issue_email_participants.count).to eq(issue_email_participants_count)
59: expect(new_issue.issue_email_participants.first.email).to eq(author_email)
74: .exactly(issue_email_participants_count - 1).times
161: expect(Issue.last.issue_email_participants.map(&:email)).to match_array(%w[from@example.com])
170: let(:issue_email_participants_count) { 3 }
204: let(:issue_email_participants_count) { 6 }
304: it 'creates issue_email_participants for author and reply author' do
309: expect(Issue.last.issue_email_participants.map(&:email))
337: expect(Issue.last.issue_email_participants.map(&:email))
spec/lib/gitlab/import_export/all_models.yml
70:- issue_email_participants
spec/mailers/emails/service_desk_spec.rb
93: issue.issue_email_participants.create!(email: email)
199: other_issue.issue_email_participants.create!(email: email)
spec/migrations/20241203075620_queue_backfill_issue_email_participants_namespace_id_spec.rb
17: table_name: :issue_email_participants,
spec/models/issue_spec.rb
38: it { is_expected.to have_many(:issue_email_participants) }
1707: participant1 = issue.issue_email_participants.create!(email: 'a@gitlab.com')
1708: participant2 = issue.issue_email_participants.create!(email: 'b@gitlab.com')
spec/models/work_items/widgets/email_participants_spec.rb
33: describe '#issue_email_participants' do
34: subject { described_class.new(work_item).issue_email_participants }
36: it { is_expected.to match_array(work_item.issue_email_participants) }
spec/presenters/issue_presenter_spec.rb
179: describe '#issue_email_participants' do
182: subject { described_class.new(participants_issue, current_user: user).issue_email_participants }
188: participants_issue.issue_email_participants.create!(email: email)
spec/presenters/note_presenter_spec.rb
11: let_it_be(:system_note_metadata) { create(:system_note_metadata, note: note, action: :issue_email_participants) }
spec/requests/api/graphql/notes/note_spec.rb
67: context 'with issue_email_participants action' do
70: let_it_be(:issue_email_participants_system_note) do
76: create(:system_note_metadata, note: issue_email_participants_system_note, action: :issue_email_participants)
80: let(:note_params) { { 'id' => global_id_of(issue_email_participants_system_note) } }
85: expect(note_data['id']).to eq(global_id_of(issue_email_participants_system_note).to_s)
95: expect(note_data['id']).to eq(global_id_of(issue_email_participants_system_note).to_s)
spec/requests/api/notes_spec.rb
52: context 'when system note with issue_email_participants action' do
59: let!(:system_note_metadata) { create(:system_note_metadata, note: note, action: :issue_email_participants) }
spec/serializers/issue_entity_spec.rb
168: resource.issue_email_participants.create!(email: email)
176: expect(response[:issue_email_participants]).to eq([{ email: obfuscated_email }])
183: expect(subject[:issue_email_participants]).to eq([{ email: obfuscated_email }])
198: expect(response[:issue_email_participants]).to eq([{ email: obfuscated_email }])
213: expect(response[:issue_email_participants]).to eq([{ email: email }])
spec/serializers/note_entity_spec.rb
31: context 'when system note with issue_email_participants action', feature_category: :service_desk do
35: let_it_be(:system_note_metadata) { create(:system_note_metadata, note: note, action: :issue_email_participants) }
spec/services/issue_email_participants/create_service_spec.rb
23: expect(note.system_note_metadata.action).to eq('issue_email_participants')
83: issue.issue_email_participants.create!(email: emails.first)
128: issue.issue_email_participants.create!(email: emails.first)
spec/services/issue_email_participants/destroy_service_spec.rb
68: issue.issue_email_participants.create!(email: 'user@example.com')
95: issue.issue_email_participants.create!(email: 'user@example.com')
135: issue.issue_email_participants.create!(email: emails.first)
144: issue.issue_email_participants.create!(email: email)
158: issue.issue_email_participants.create!(email: email)
spec/services/issues/convert_to_ticket_service_spec.rb
22: external_participant = issue.issue_email_participants.last
spec/services/notification_service_spec.rb
1022: describe 'issue_email_participants' do
1062: let!(:issue_email_participant) { issue.issue_email_participants.create!(email: 'service.desk@example.com') }
1087: let!(:other_external_participant) { issue.issue_email_participants.create!(email: 'user@example.com') }
1154: let!(:issue_email_participant) { issue.issue_email_participants.create!(email: 'service.desk@example.com') }
spec/services/quick_actions/interpret_service_spec.rb
2756: issuable.issue_email_participants.create!(email: "a@gitlab.com")
2774: expect { add_emails }.to change { issue.issue_email_participants.count }.by(2)
2791: expect { add_emails }.to change { issue.issue_email_participants.count }.by(1)
2799: issue.issue_email_participants.create!(email: 'existing@gitlab.com')
2801: expect { add_emails }.to change { issue.issue_email_participants.count }.by(1)
2805: issue.issue_email_participants.create!(email: 'EXISTING@gitlab.com')
2807: expect { add_emails }.to change { issue.issue_email_participants.count }.by(1)
2815: expect { add_emails }.to change { issue.issue_email_participants.count }.by(1)
2823: expect { add_emails }.to change { issue.issue_email_participants.count }.by(6)
2829: issue.issue_email_participants.create!(email: 'user@example.com')
2847: expect { add_emails }.to change { issue.issue_email_participants.count }.by(1)
2892: issuable.issue_email_participants.create!(email: "user@example.com")
2902: expect { remove_email }.to change { issue.issue_email_participants.count }.by(-1)
2909: issuable.issue_email_participants.create!(email: "FirstLast@GitLab.com")
2919: expect { remove_email }.to change { issue.issue_email_participants.count }.by(-1)
2927: expect { remove_email }.to change { issue.issue_email_participants.count }.by(-1)
2947: issuable.issue_email_participants.create!(email: "user1@example.com")
2951: expect { remove_email }.to change { issue.issue_email_participants.count }.by(-1)
spec/services/work_items/data_sync/widgets/email_participants_spec.rb
32: target_email_participants = target_work_item.reload.issue_email_participants.map(&:email)
46: expect(target_work_item.reload.issue_email_participants).to be_empty
62: expect(target_work_item.reload.issue_email_participants).to be_empty
75: expect(work_item.issue_email_participants).to be_empty
Currently the feature flag is enabled on production
It is possible that this MR will still need some changes to remove references to the feature flag in the code.
At the moment the gitlab-housekeeper is not always capable of removing all references so you must check the diff and pipeline failures to confirm if there are any issues.
It is the responsibility of groupproject management to push those changes to this branch.
Note: If you do not want to remove this feature flag at this time, you can add an intended_to_rollout_by_date attribute in the feature flag YAML file to prevent automated removal.
TODO for the reviewers before merging this MR
-
See the status of the rollout by checking #350460, https://gitlab.com/gitlab-com/gl-infra/feature-flag-log/-/issues/?search=issue_email_participants&sort=created_date&state=all&label_name%5B%5D=host%3A%3Agitlab.com -
Verify the feature flag status via chatops by running /chatops run feature get issue_email_participants. -
Search for references to IssueEmailParticipantsin frontend part of code -
Search for references to issue_email_participantsin code -
Check if we need to remove any Gem or other related code by looking at the changes in !49264 (merged)
This change was generated by
gitlab-housekeeper
in CI using the Keeps::DeleteOldFeatureFlags keep.
To provide feedback on your experience with gitlab-housekeeper please create an issue with the
label GitLab Housekeeper and consider pinging the author of this keep.