Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-11-11 21:14:18 +00:00
parent 32205ec50f
commit 60b750213f
9 changed files with 130 additions and 15 deletions

View File

@ -92,6 +92,8 @@ class Issue < ApplicationRecord
has_many :issue_assignees
has_many :issue_email_participants
alias_method :email_participants, :issue_email_participants
has_one :email
has_many :assignees, class_name: "User", through: :issue_assignees
has_many :zoom_meetings

View File

@ -4,6 +4,7 @@ class IssueEmailParticipant < ApplicationRecord
include BulkInsertSafe
include Presentable
include CaseSensitivity
include EachBatch
belongs_to :issue

View File

@ -5,6 +5,8 @@ module WorkItems
class EmailParticipants < Base
delegate :issue_email_participants, to: :work_item
alias_method :email_participants, :issue_email_participants
def self.quick_action_commands
[:add_email, :remove_email]
end

View File

@ -4,12 +4,27 @@ module WorkItems
module DataSync
module Widgets
class EmailParticipants < Base
def after_save_commit
# copy email participants
def after_create
return unless params[:operation] == :move
return unless target_work_item.get_widget(:email_participants)
work_item.email_participants.each_batch(of: BATCH_SIZE) do |email_participants_batch|
::IssueEmailParticipant.insert_all(new_work_item_email_participants(email_participants_batch))
end
end
def post_move_cleanup
# do it
work_item.email_participants.each_batch(of: BATCH_SIZE) do |email_participants_batch|
email_participants_batch.delete_all
end
end
private
def new_work_item_email_participants(email_participants_batch)
email_participants_batch.map do |email_participant|
email_participant.attributes.except("id").tap { |ep| ep["issue_id"] = target_work_item.id }
end
end
end
end

View File

@ -110,8 +110,8 @@ The following events are supported for integrations:
| Alert event | | `alert` | A a new, unique alert is recorded. |
| Commit event | ✓ | `commit` | A commit is created or updated. |
| [Deployment event](../../user/project/integrations/webhook_events.md#deployment-events) | | `deployment` | A deployment starts or finishes. |
| [Issue event](../../user/project/integrations/webhook_events.md#issue-events) | ✓ | `issue` | An issue is created, updated, or closed. |
| [Confidential issue event](../../user/project/integrations/webhook_events.md#issue-events) | ✓ | `confidential_issue` | A confidential issue is created, updated, or closed. |
| [Work item event](../../user/project/integrations/webhook_events.md#work-item-events) | ✓ | `issue` | An issue is created, updated, or closed. |
| [Confidential issue event](../../user/project/integrations/webhook_events.md#work-item-events) | ✓ | `confidential_issue` | A confidential issue is created, updated, or closed. |
| [Job event](../../user/project/integrations/webhook_events.md#job-events) | | `job` | |
| [Merge request event](../../user/project/integrations/webhook_events.md#merge-request-events) | ✓ | `merge_request` | A merge request is created, updated, or merged. |
| [Comment event](../../user/project/integrations/webhook_events.md#comment-events) | | `comment` | A new comment is added. |

View File

@ -843,7 +843,7 @@ Prerequisites:
[local Docker container registry](../../../packages/container_registry/index.md):
```plaintext
registry.gitlab.com/security-products/secrets:4
registry.gitlab.com/security-products/secrets:6
```
The pipeline secret detection analyzer's image is [periodically updated](../../index.md#vulnerability-scanner-maintenance)

View File

@ -20,15 +20,15 @@ Event type | Trigger
---------------------------------------------|-----------------------------------------------------------------------------
[Push event](#push-events) | A push is made to the repository.
[Tag event](#tag-events) | Tags are created or deleted in the repository.
[Issue event](#issue-events) | A new issue is created or an existing issue is updated, closed, or reopened.
[Work item event](#work-item-events) | A new work item is created or an existing one is edited, closed, or reopened.
[Comment event](#comment-events) | A new comment is made or edited on commits, merge requests, issues, and code snippets. <sup>1</sup>
[Merge request event](#merge-request-events) | A merge request is created, updated, merged, or closed, or a commit is added in the source branch.
[Wiki page event](#wiki-page-events) | A wiki page is created, updated, or deleted.
[Merge request event](#merge-request-events) | A merge request is created, edited, merged, or closed, or a commit is added in the source branch.
[Wiki page event](#wiki-page-events) | A wiki page is created, edited, or deleted.
[Pipeline event](#pipeline-events) | A pipeline status changes.
[Job event](#job-events) | A job status changes.
[Deployment event](#deployment-events) | A deployment starts, succeeds, fails, or is canceled.
[Feature flag event](#feature-flag-events) | A feature flag is turned on or off.
[Release event](#release-events) | A release is created, updated, or deleted.
[Release event](#release-events) | A release is created, edited, or deleted.
[Emoji event](#emoji-events) | An emoji reaction is added or removed.
[Project or group access token event](#project-and-group-access-token-events) | A project or group access token will expire in seven days.
@ -207,13 +207,16 @@ Payload example:
}
```
## Issue events
## Work item events
> - `type` attribute in `object_attributes` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/467415) in GitLab 17.2.
> - Support for epics [introduced](https://gitlab.com/groups/gitlab-org/-/epics/13056) in GitLab 17.3. Your administrator must have [enabled the new look for epics](../../group/epics/epic_work_items.md).
Issue events are triggered when an issue or work item is created, updated, closed, or reopened.
Work item events are triggered when a work item is created, edited, closed, or reopened.
The supported work item types are:
- [Epics](../../group/epics/index.md)
- [Issue](../../project/issues/index.md)
- [Tasks](../../tasks.md)
- [Incidents](../../../operations/incident_management/incidents.md)
- [Test cases](../../../ci/test_cases/index.md)
@ -223,6 +226,8 @@ The supported work item types are:
For issues and [Service Desk](../service_desk/index.md) issues, the `object_kind` is `issue`, and the `type` is `Issue`.
For all other work items, the `object_kind` field is `work_item`, and the `type` is the work item type.
For work item type `Epic`, to get events for changes, the webhook must be registered for the group.
The available values for `object_attributes.action` in the payload are:
- `open`

View File

@ -0,0 +1,78 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe WorkItems::DataSync::Widgets::EmailParticipants, feature_category: :team_planning do
let_it_be(:current_user) { create(:user) }
let_it_be_with_reload(:work_item) { create(:work_item) }
let_it_be(:target_work_item) { create(:work_item) }
let_it_be(:participant1) { create(:issue_email_participant, issue: work_item, email: 'user1@example.com') }
let_it_be(:participant2) { create(:issue_email_participant, issue: work_item, email: 'user2@example.com') }
let(:params) { { operation: :move } }
subject(:callback) do
described_class.new(
work_item: work_item, target_work_item: target_work_item, current_user: current_user, params: params
)
end
describe '#after_create' do
context 'when target work item has email_participants widget' do
before do
allow(target_work_item).to receive(:get_widget).with(:email_participants).and_return(true)
end
it 'copies email_participants from work_item to target_work_item' do
expect(callback).to receive(:new_work_item_email_participants).and_call_original
expect(::IssueEmailParticipant).to receive(:insert_all).and_call_original
callback.after_create
target_email_participants = target_work_item.reload.issue_email_participants.map(&:email)
expect(target_email_participants).to match_array([participant1, participant2].map(&:email))
end
end
context 'when operation is clone' do
let(:params) { { operation: :clone } }
it 'does not copy email_participants' do
expect(callback).not_to receive(:new_work_item_email_participants)
expect(::IssueEmailParticipant).not_to receive(:insert_all)
callback.after_create
expect(target_work_item.reload.issue_email_participants).to be_empty
end
end
context 'when target work item does not have email_participants widget' do
before do
target_work_item.reload
allow(target_work_item).to receive(:get_widget).with(:email_participants).and_return(false)
end
it 'does not copy email_participants' do
expect(callback).not_to receive(:new_work_item_email_participants)
expect(::IssueEmailParticipant).not_to receive(:insert_all)
callback.after_create
expect(target_work_item.reload.issue_email_participants).to be_empty
end
end
end
describe '#post_move_cleanup' do
it 'is defined and can be called' do
expect { callback.post_move_cleanup }.not_to raise_error
end
it 'removes original work item email_participants' do
callback.post_move_cleanup
expect(work_item.issue_email_participants).to be_empty
end
end
end

View File

@ -58,9 +58,8 @@ RSpec.shared_examples 'cloneable and moveable widget data' do
work_item.reload.award_emoji.pluck(:user_id, :name)
end
where(:widget_name, :eval_value, :expected_data, :operations) do
:assignees | :work_item_assignees | ref(:assignees) | [ref(:move), ref(:clone)]
:award_emoji | :work_item_award_emoji | ref(:award_emojis) | [ref(:move)]
def work_item_emails(work_item)
work_item.reload.email_participants.pluck(:email)
end
let(:move) { WorkItems::DataSync::MoveService }
@ -70,14 +69,27 @@ RSpec.shared_examples 'cloneable and moveable widget data' do
let_it_be(:milestone) { create(:milestone) }
let_it_be(:thumbs_ups) { create_list(:award_emoji, 2, name: 'thumbsup', awardable: original_work_item) }
let_it_be(:thumbs_downs) { create_list(:award_emoji, 2, name: 'thumbsdown', awardable: original_work_item) }
let_it_be(:participant2) { create(:issue_email_participant, issue: original_work_item, email: 'user2@example.com') }
let_it_be(:award_emojis) { original_work_item.reload.award_emoji.pluck(:user_id, :name) }
let_it_be(:emails) do
create_list(:issue_email_participant, 2, issue: original_work_item)
# create email participants on original work item and return emails as `expected_data` for later comparison.
original_work_item.reload.email_participants.map(&:email)
end
let_it_be(:assignees) do
original_work_item.assignee_ids = users.map(&:id)
# set assignees and return assigned users as `expected_data` for later comparison.
users
end
where(:widget_name, :eval_value, :expected_data, :operations) do
:assignees | :work_item_assignees | ref(:assignees) | [ref(:move), ref(:clone)]
:award_emoji | :work_item_award_emoji | ref(:award_emojis) | [ref(:move)]
:email_participants | :work_item_emails | ref(:emails) | [ref(:move)]
end
with_them do
context "with widget" do
it 'clones and moves widget data' do