From 2e1790985c3924c7df12beb99960070a840b1537 Mon Sep 17 00:00:00 2001 From: andreas-unleash Date: Thu, 23 Nov 2023 15:00:24 +0200 Subject: [PATCH] feat: Handle scheduled request events in addons (#5403) - Create 2 new events to replace the SCHEDULED_CHANGE_REQUEST_EXECUTED event - Handle the 3 events in slack-app and webhook addon definitions 3 events handled: - CHANGE_REQUEST_SCHEDULED - CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS - CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE Closes # [1-1555](https://linear.app/unleash/issue/1-1555/update-change-request-scheduled-and-scheduled-change-request-executed) Note: SCHEDULED_CHANGE_REQUEST_EXECUTED will be removed in follow up PR not to break current enterprise build --------- Signed-off-by: andreas-unleash --- .../feature-event-formatter-md.test.ts.snap | 21 ++++++++ .../addons/feature-event-formatter-md.test.ts | 54 +++++++++++++++++++ src/lib/addons/feature-event-formatter-md.ts | 15 ++++++ src/lib/addons/slack-app-definition.ts | 6 +++ src/lib/addons/webhook-definition.ts | 6 +++ src/lib/types/events.ts | 8 ++- 6 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/lib/addons/__snapshots__/feature-event-formatter-md.test.ts.snap b/src/lib/addons/__snapshots__/feature-event-formatter-md.test.ts.snap index 86170f3590..77278bad78 100644 --- a/src/lib/addons/__snapshots__/feature-event-formatter-md.test.ts.snap +++ b/src/lib/addons/__snapshots__/feature-event-formatter-md.test.ts.snap @@ -7,6 +7,13 @@ exports[`Should format specialised text for events when IPs changed 1`] = ` } `; +exports[`Should format specialised text for events when change request is scheduled 1`] = ` +{ + "text": "*user@company.com* scheduled change request *[#1](unleashUrl/projects/my-other-project/change-requests/1)* for feature toggle *[new-feature](unleashUrl/projects/my-other-project/features/new-feature)* in *production* environment in project *[my-other-project](unleashUrl/projects/my-other-project)* to be applied at in project *my-other-project*", + "url": "unleashUrl/projects/my-other-project/change-requests/1", +} +`; + exports[`Should format specialised text for events when constraints and rollout percentage and stickiness changed 1`] = ` { "text": "*user@company.com* updated *[new-feature](unleashUrl/projects/my-other-project/features/new-feature)* in project *[my-other-project](unleashUrl/projects/my-other-project)* by updating strategy *flexibleRollout* in *production* stickiness from default to random; rollout from 67% to 32%; constraints from empty set of constraints to [appName is one of (x,y)]", @@ -154,6 +161,20 @@ exports[`Should format specialised text for events when rollout percentage chang } `; +exports[`Should format specialised text for events when scheduled change request fails 1`] = ` +{ + "text": "*Failed* to apply the scheduled change request *[#1](unleashUrl/projects/my-other-project/change-requests/1)* for feature toggle *[new-feature](unleashUrl/projects/my-other-project/features/new-feature)* in *production* environment in project *[my-other-project](unleashUrl/projects/my-other-project)* by *user@company.com* in project *my-other-project*.", + "url": "unleashUrl/projects/my-other-project/change-requests/1", +} +`; + +exports[`Should format specialised text for events when scheduled change request succeeds 1`] = ` +{ + "text": "*Successfully* applied the scheduled change request *[#1](unleashUrl/projects/my-other-project/change-requests/1)* for feature toggle *[new-feature](unleashUrl/projects/my-other-project/features/new-feature)* in *production* environment in project *[my-other-project](unleashUrl/projects/my-other-project)* by *user@company.com* in project *my-other-project*.", + "url": "unleashUrl/projects/my-other-project/change-requests/1", +} +`; + exports[`Should format specialised text for events when stickiness changed 1`] = ` { "text": "*user@company.com* updated *[new-feature](unleashUrl/projects/my-other-project/features/new-feature)* in project *[my-other-project](unleashUrl/projects/my-other-project)* by updating strategy *flexibleRollout* in *production* stickiness from default to random", diff --git a/src/lib/addons/feature-event-formatter-md.test.ts b/src/lib/addons/feature-event-formatter-md.test.ts index 0a7a090fa1..f64eaf2b64 100644 --- a/src/lib/addons/feature-event-formatter-md.test.ts +++ b/src/lib/addons/feature-event-formatter-md.test.ts @@ -1,4 +1,7 @@ import { + CHANGE_REQUEST_SCHEDULED, + CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE, + CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS, FEATURE_STRATEGY_ADD, FEATURE_STRATEGY_REMOVE, FEATURE_STRATEGY_UPDATE, @@ -481,6 +484,57 @@ const testCases: [string, IEvent][] = [ environment: 'production', }, ], + [ + 'when change request is scheduled', + { + id: 920, + type: CHANGE_REQUEST_SCHEDULED, + createdBy: 'user@company.com', + createdAt: new Date('2022-06-01T10:03:11.549Z'), + data: { + changeRequestId: 1, + }, + preData: {}, + tags: [], + featureName: 'new-feature', + project: 'my-other-project', + environment: 'production', + }, + ], + [ + 'when scheduled change request succeeds ', + { + id: 920, + type: CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS, + createdBy: 'user@company.com', + createdAt: new Date('2022-06-01T10:03:11.549Z'), + data: { + changeRequestId: 1, + }, + preData: {}, + tags: [], + featureName: 'new-feature', + project: 'my-other-project', + environment: 'production', + }, + ], + [ + 'when scheduled change request fails ', + { + id: 920, + type: CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE, + createdBy: 'user@company.com', + createdAt: new Date('2022-06-01T10:03:11.549Z'), + data: { + changeRequestId: 1, + }, + preData: {}, + tags: [], + featureName: 'new-feature', + project: 'my-other-project', + environment: 'production', + }, + ], ]; testCases.forEach(([description, event]) => diff --git a/src/lib/addons/feature-event-formatter-md.ts b/src/lib/addons/feature-event-formatter-md.ts index bcd6d8b50c..76dbf488a7 100644 --- a/src/lib/addons/feature-event-formatter-md.ts +++ b/src/lib/addons/feature-event-formatter-md.ts @@ -55,6 +55,9 @@ import { USER_CREATED, USER_DELETED, USER_UPDATED, + CHANGE_REQUEST_SCHEDULED, + CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS, + CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE, } from '../types'; interface IEventData { @@ -140,6 +143,18 @@ const EVENT_MAP: Record = { action: '*{{user}}* sent to review change request {{changeRequest}}', path: '/projects/{{event.project}}/change-requests/{{event.data.changeRequestId}}', }, + [CHANGE_REQUEST_SCHEDULED]: { + action: '*{{user}}* scheduled change request {{changeRequest}} to be applied at {{event.data.scheduledDate}} in project *{{event.project}}*', + path: '/projects/{{event.project}}/change-requests/{{event.data.changeRequestId}}', + }, + [CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS]: { + action: '*Successfully* applied the scheduled change request {{changeRequest}} by *{{user}}* in project *{{event.project}}*.', + path: '/projects/{{event.project}}/change-requests/{{event.data.changeRequestId}}', + }, + [CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE]: { + action: '*Failed* to apply the scheduled change request {{changeRequest}} by *{{user}}* in project *{{event.project}}*.', + path: '/projects/{{event.project}}/change-requests/{{event.data.changeRequestId}}', + }, [CONTEXT_FIELD_CREATED]: { action: '*{{user}}* created context field *{{event.data.name}}*', path: '/context', diff --git a/src/lib/addons/slack-app-definition.ts b/src/lib/addons/slack-app-definition.ts index 1d97d2e96f..71f2877974 100644 --- a/src/lib/addons/slack-app-definition.ts +++ b/src/lib/addons/slack-app-definition.ts @@ -52,6 +52,9 @@ import { BANNER_CREATED, BANNER_UPDATED, BANNER_DELETED, + CHANGE_REQUEST_SCHEDULED, + CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS, + CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE, } from '../types/events'; import { IAddonDefinition } from '../types/model'; @@ -104,6 +107,9 @@ const slackAppDefinition: IAddonDefinition = { CHANGE_REQUEST_DISCARDED, CHANGE_REQUEST_REJECTED, CHANGE_REQUEST_SENT_TO_REVIEW, + CHANGE_REQUEST_SCHEDULED, + CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS, + CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE, CONTEXT_FIELD_CREATED, CONTEXT_FIELD_DELETED, CONTEXT_FIELD_UPDATED, diff --git a/src/lib/addons/webhook-definition.ts b/src/lib/addons/webhook-definition.ts index e92dc6892a..8b7388f58e 100644 --- a/src/lib/addons/webhook-definition.ts +++ b/src/lib/addons/webhook-definition.ts @@ -25,6 +25,9 @@ import { CHANGE_REQUEST_SENT_TO_REVIEW, CHANGE_REQUEST_APPLIED, FEATURE_POTENTIALLY_STALE_ON, + CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS, + CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE, + CHANGE_REQUEST_SCHEDULED, } from '../types/events'; import { IAddonDefinition } from '../types/model'; @@ -117,6 +120,9 @@ const webhookDefinition: IAddonDefinition = { CHANGE_REQUEST_CANCELLED, CHANGE_REQUEST_SENT_TO_REVIEW, CHANGE_REQUEST_APPLIED, + CHANGE_REQUEST_SCHEDULED, + CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS, + CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE, FEATURE_POTENTIALLY_STALE_ON, ], }; diff --git a/src/lib/types/events.ts b/src/lib/types/events.ts index 8b81658afe..a2e02eab89 100644 --- a/src/lib/types/events.ts +++ b/src/lib/types/events.ts @@ -128,8 +128,12 @@ export const CHANGE_REQUEST_SENT_TO_REVIEW = 'change-request-sent-to-review' as const; export const CHANGE_REQUEST_APPLIED = 'change-request-applied' as const; export const SCHEDULED_CHANGE_REQUEST_EXECUTED = - 'scheduled-change-request-executed' as const; + 'scheduled-change-request-executed' as const; //This will be removed in follow up PR export const CHANGE_REQUEST_SCHEDULED = 'change-request-scheduled' as const; +export const CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS = + 'change-request-scheduled-application-success' as const; +export const CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE = + 'change-request-scheduled-application-failure' as const; export const API_TOKEN_CREATED = 'api-token-created' as const; export const API_TOKEN_UPDATED = 'api-token-updated' as const; @@ -252,6 +256,8 @@ export const IEventTypes = [ SCHEDULED_CHANGE_REQUEST_EXECUTED, CHANGE_REQUEST_APPLIED, CHANGE_REQUEST_SCHEDULED, + CHANGE_REQUEST_SCHEDULED_APPLICATION_SUCCESS, + CHANGE_REQUEST_SCHEDULED_APPLICATION_FAILURE, API_TOKEN_CREATED, API_TOKEN_UPDATED, API_TOKEN_DELETED,