Skip to content

Commit

Permalink
feat: add more events in integrations (#4815)
Browse files Browse the repository at this point in the history
https://linear.app/unleash/issue/2-1253/add-support-for-more-events-in-the-slack-app-integration

Adds support for a lot more events in our integrations. Here is how the
full list looks like:

- ADDON_CONFIG_CREATED
- ADDON_CONFIG_DELETED
- ADDON_CONFIG_UPDATED
- API_TOKEN_CREATED
- API_TOKEN_DELETED
- CHANGE_ADDED
- CHANGE_DISCARDED
- CHANGE_EDITED
- CHANGE_REQUEST_APPLIED
- CHANGE_REQUEST_APPROVAL_ADDED
- CHANGE_REQUEST_APPROVED
- CHANGE_REQUEST_CANCELLED
- CHANGE_REQUEST_CREATED
- CHANGE_REQUEST_DISCARDED
- CHANGE_REQUEST_REJECTED
- CHANGE_REQUEST_SENT_TO_REVIEW
- CONTEXT_FIELD_CREATED
- CONTEXT_FIELD_DELETED
- CONTEXT_FIELD_UPDATED
- FEATURE_ARCHIVED
- FEATURE_CREATED
- FEATURE_DELETED
- FEATURE_ENVIRONMENT_DISABLED
- FEATURE_ENVIRONMENT_ENABLED
- FEATURE_ENVIRONMENT_VARIANTS_UPDATED
- FEATURE_METADATA_UPDATED
- FEATURE_POTENTIALLY_STALE_ON
- FEATURE_PROJECT_CHANGE
- FEATURE_REVIVED
- FEATURE_STALE_OFF
- FEATURE_STALE_ON
- FEATURE_STRATEGY_ADD
- FEATURE_STRATEGY_REMOVE
- FEATURE_STRATEGY_UPDATE
- FEATURE_TAGGED
- FEATURE_UNTAGGED
- GROUP_CREATED
- GROUP_DELETED
- GROUP_UPDATED
- PROJECT_CREATED
- PROJECT_DELETED
- SEGMENT_CREATED
- SEGMENT_DELETED
- SEGMENT_UPDATED
- SERVICE_ACCOUNT_CREATED
- SERVICE_ACCOUNT_DELETED
- SERVICE_ACCOUNT_UPDATED
- USER_CREATED
- USER_DELETED
- USER_UPDATED

I added the events that I thought were relevant based on my own
discretion. Know of any event we should add? Let me know and I'll add it
🙂

For now I only added these events to the new Slack App integration, but
we can add them to the other integrations as well since they are now
supported.

The event formatter was refactored and changed quite a bit in order to
make it easier to maintain and add new events in the future. As a
result, events are now posted with different text. Do we consider this a
breaking change? If so, I can keep the old event formatter around,
create a new one and only use it for the new Slack App integration.

I noticed we don't have good 404 behaviors in the UI for things that are
deleted in the meantime, that's why I avoided some links to specific
resources (like feature strategies, integration configurations, etc),
but we could add them later if we improve this.

This PR also tries to add some consistency to the the way we log events.
  • Loading branch information
nunogois committed Sep 29, 2023
1 parent a0571ce commit 521cc24
Show file tree
Hide file tree
Showing 20 changed files with 806 additions and 335 deletions.
Expand Up @@ -71,10 +71,12 @@ export const IntegrationForm: VFC<IntegrationFormProps> = ({
value: environment.name,
label: environment.name,
}));
const selectableEvents = provider?.events?.map(event => ({
value: event,
label: event,
}));
const selectableEvents = provider?.events
?.map(event => ({
value: event,
label: event,
}))
.sort((a, b) => a.label.localeCompare(b.label));
const { uiConfig } = useUiConfig();
const [formValues, setFormValues] = useState(initialValues);
const [errors, setErrors] = useState<{
Expand Down
12 changes: 6 additions & 6 deletions src/lib/addons/__snapshots__/datadog.test.ts.snap
@@ -1,16 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Should call datadog webhook for archived toggle 1`] = `"{"text":"%%% \\n some@user.com just archived feature toggle *[some-toggle](http://some-url.com/archive)* \\n %%% ","title":"Unleash notification update"}"`;
exports[`Should call datadog webhook for archived toggle 1`] = `"{"text":"%%% \\n *some@user.com* archived *some-toggle* in project ** \\n %%% ","title":"Unleash notification update"}"`;

exports[`Should call datadog webhook for archived toggle with project info 1`] = `"{"text":"%%% \\n some@user.com just archived feature toggle *[some-toggle](http://some-url.com/projects/some-project/archive)* \\n %%% ","title":"Unleash notification update"}"`;
exports[`Should call datadog webhook for archived toggle with project info 1`] = `"{"text":"%%% \\n *some@user.com* archived *some-toggle* in project *[some-project](http://some-url.com/projects/some-project)* \\n %%% ","title":"Unleash notification update"}"`;

exports[`Should call datadog webhook 1`] = `"{"text":"%%% \\n some@user.com created feature toggle [some-toggle](http://some-url.com/projects//features/some-toggle) in project *undefined* \\n %%% ","title":"Unleash notification update"}"`;
exports[`Should call datadog webhook 1`] = `"{"text":"%%% \\n *some@user.com* created *[some-toggle](http://some-url.com/projects//features/some-toggle)* in project ** \\n %%% ","title":"Unleash notification update"}"`;

exports[`Should call datadog webhook for toggled environment 1`] = `"{"text":"%%% \\n some@user.com *disabled* [some-toggle](http://some-url.com/projects/default/features/some-toggle) in *development* environment in project *default* \\n %%% ","title":"Unleash notification update"}"`;
exports[`Should call datadog webhook for toggled environment 1`] = `"{"text":"%%% \\n *some@user.com* disabled *[some-toggle](http://some-url.com/projects/default/features/some-toggle)* for the *development* environment in project *[default](http://some-url.com/projects/default)* \\n %%% ","title":"Unleash notification update"}"`;

exports[`Should call datadog webhook with JSON when template set 1`] = `"{"text":"{\\n \\"event\\": \\"feature-created\\",\\n \\"createdBy\\": \\"some@user.com\\"\\n}","title":"Unleash notification update"}"`;

exports[`Should include customHeaders in headers when calling service 1`] = `"{"text":"%%% \\n some@user.com *disabled* [some-toggle](http://some-url.com/projects/default/features/some-toggle) in *development* environment in project *default* \\n %%% ","title":"Unleash notification update"}"`;
exports[`Should include customHeaders in headers when calling service 1`] = `"{"text":"%%% \\n *some@user.com* disabled *[some-toggle](http://some-url.com/projects/default/features/some-toggle)* for the *development* environment in project *[default](http://some-url.com/projects/default)* \\n %%% ","title":"Unleash notification update"}"`;

exports[`Should include customHeaders in headers when calling service 2`] = `
{
Expand All @@ -20,7 +20,7 @@ exports[`Should include customHeaders in headers when calling service 2`] = `
}
`;

exports[`Should not include source_type_name when included in the config 1`] = `"{"text":"%%% \\n some@user.com *disabled* [some-toggle](http://some-url.com/projects/default/features/some-toggle) in *development* environment in project *default* \\n %%% ","title":"Unleash notification update","source_type_name":"my-custom-source-type"}"`;
exports[`Should not include source_type_name when included in the config 1`] = `"{"text":"%%% \\n *some@user.com* disabled *[some-toggle](http://some-url.com/projects/default/features/some-toggle)* for the *development* environment in project *[default](http://some-url.com/projects/default)* \\n %%% ","title":"Unleash notification update","source_type_name":"my-custom-source-type"}"`;

exports[`Should not include source_type_name when included in the config 2`] = `
{
Expand Down
183 changes: 183 additions & 0 deletions src/lib/addons/__snapshots__/feature-event-formatter-md.test.ts.snap
@@ -0,0 +1,183 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Should format specialised text for events when IPs 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 *remoteAddress* in *production* IPs from empty set of IPs to [127.0.0.1]; constraints from empty set of constraints to [appName is one of (x,y)]",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

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)]",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

exports[`Should format specialised text for events when default strategy updated 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from empty set of constraints to [appName is one of (x,y), appName not is one of (x)]",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated 2`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from empty set of constraints to [appName is not one of (x,y), appName not is not one of (x)]",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated 3`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from empty set of constraints to [appName is a string that contains (x,y), appName not is a string that contains (x)]",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated 4`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from empty set of constraints to [appName is a string that starts with (x,y), appName not is a string that starts with (x)]",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated 5`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from empty set of constraints to [appName is a string that ends with (x,y), appName not is a string that ends with (x)]",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint DATE_AFTER 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a date after 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint DATE_BEFORE 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a date before 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint NUM_EQ 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a number equal to 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint NUM_GT 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a number greater than 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint NUM_GTE 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a number greater than or equal to 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint NUM_LT 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a number less than 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint NUM_LTE 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a number less than or equal to 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint SEMVER_EQ 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a SemVer equal to 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint SEMVER_GT 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a SemVer greater than 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when default strategy updated with numeric constraint SEMVER_LT 1`] = `
{
"text": "*admin* updated *[aaa](unleashUrl/projects/default/features/aaa)* in project *[default](unleashUrl/projects/default)* by updating strategy *default* in *production* constraints from [appName is a SemVer less than 4] to empty set of constraints",
"url": "unleashUrl/projects/default/features/aaa",
}
`;

exports[`Should format specialised text for events when groupId 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* groupId from new-feature to different-feature",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

exports[`Should format specialised text for events when host names 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 *applicationHostname* in *production* hostNames from empty set of hostNames to [unleash.com]; constraints from empty set of constraints to [appName is one of (x,y)]",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

exports[`Should format specialised text for events when neither rollout percentage nor 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*",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

exports[`Should format specialised text for events when no specific text for strategy exists yet 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 *newStrategy* in *production*",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

exports[`Should format specialised text for events when rollout percentage 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* rollout from 67% to 32%",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

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",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

exports[`Should format specialised text for events when strategy added 1`] = `
{
"text": "*user@company.com* added strategy *flexibleRollout* to *[new-feature](unleashUrl/projects/my-other-project/features/new-feature)* for the *production* environment in project *[my-other-project](unleashUrl/projects/my-other-project)*",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

exports[`Should format specialised text for events when strategy removed 1`] = `
{
"text": "*user@company.com* removed strategy *default* from *[new-feature](unleashUrl/projects/my-other-project/features/new-feature)* for the *production* environment in project *[my-other-project](unleashUrl/projects/my-other-project)*",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

exports[`Should format specialised text for events when userIds 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 *userWithId* in *production* userIds from empty set of userIds to [a,b]; constraints from empty set of constraints to [appName is one of (x,y)]",
"url": "unleashUrl/projects/my-other-project/features/new-feature",
}
`;

0 comments on commit 521cc24

Please sign in to comment.