Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
32205ec50f
commit
60b750213f
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ class IssueEmailParticipant < ApplicationRecord
|
|||
include BulkInsertSafe
|
||||
include Presentable
|
||||
include CaseSensitivity
|
||||
include EachBatch
|
||||
|
||||
belongs_to :issue
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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. |
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue