diff --git a/docs/docs/administration-and-security/access-control/rbac.md b/docs/docs/administration-and-security/access-control/rbac.md index 61e8add86e04..2890cc2067be 100644 --- a/docs/docs/administration-and-security/access-control/rbac.md +++ b/docs/docs/administration-and-security/access-control/rbac.md @@ -172,6 +172,10 @@ Permissions can be assigned at four levels: user group, organisation, project, a | Delete feature | Allows deleting features from all environments. | Yes | | Manage segments | Grants write access to segments in this project. | | | View audit log | Allows viewing all audit log entries for this project. | | +| Manage tags | Allows managing tags in this project. | | +| Create project level change requests | Allows creating project-level (segment) change requests. | | +| Approve project level change requests | Allows approving project-level (segment) change requests. | | +| Manage project level change requests | Allows managing and publishing project-level (segment) change requests. | | ### Environment diff --git a/docs/docs/administration-and-security/governance-and-compliance/change-requests.md b/docs/docs/administration-and-security/governance-and-compliance/change-requests.md index 6c33b3ab8e49..f74699abf9b7 100644 --- a/docs/docs/administration-and-security/governance-and-compliance/change-requests.md +++ b/docs/docs/administration-and-security/governance-and-compliance/change-requests.md @@ -4,104 +4,131 @@ sidebar_label: Change Requests sidebar_position: 10 --- -You can use Change Requests to ensure that, for example, a change to a flag in Production has to be approved by another team member. They work in a similar way to Pull Requests in git. This guide explains how to use Change Requests to add workflow control to changing flag values. You will learn how to set up, create, approve, and publish Change Requests. +Change Requests (for both feature and segments) are available only with our Scale-Up and Enterprise plans. -## Prerequisites +## Feature Change Requests -- Change Requests are available only with our Scale-Up and Enterprise plans. Make sure you are subscribed to one of these. +Feature Change Requests help creating a four-eyes workflow (create, approve, publish) to updating feature flags, +similarly to Pull Requests in GitHub. -## Set Up Change Requests +### Enable Feature Change Requests -Change Requests are configured at the environment level. To enable and set up Change Requests: +![Enable Feature Change Requests](/img/change-requests/enable-feature-change-requests.png) -1. Go to the **Environment Settings Page**. -2. Enable the **Change Request** setting. -3. Select the required number of approvals for each Change Request to be applied. +1. Go to the **Environment Settings** page. +1. Enable the **Feature Change Requests** setting. +1. Select the required number of approvals for each Change Request to be applied. -## Scope of Change Requests +### Create a Feature Change Request -Change Requests apply to **environment-level** and **segment-level** flag changes only. The workflow does not apply to identity-level overrides. +Once an environment is configured with Feature Change Requests enabled, a Change Request will be required when updating +an environment default for a feature flag, or when creating or updating a segment override. **Identity overrides are +applied immediately**. -| Feature state type | Scoped to | Requires a Change Request? | -| ------------------- | ------------------------------- | -------------------------- | -| Environment default | All users in an environment | ✅ Yes | -| Segment override | Users matching a segment | ✅ Yes | -| Identity override | A single specific identity | ❌ No — live immediately | +When creating a Feature Change Request, you will need to provide it a **title** and, optionally, a **description**. -**Identity overrides are intentionally excluded.** They do not participate in -Flagsmith's versioning system, which is what the CR workflow is built on. -Changes to an identity override take effect the moment they are saved, with -no approval step. +![A Feature Change Request](/img/change-requests/feature-change-request.png) -:::tip -If your team requires approval gates on all flag changes, prefer -**segment-based targeting** (e.g. a `qa-team` segment) over individual -identity overrides. Segment overrides are subject to the full Change Request -workflow. -::: +### Approve a Feature Change Request -## Create a Change Request +Change Requests awaiting approval are listed in the **Environments** tab: -Once an environment is configured with Change Requests enabled, attempting to -change an environment default or segment override will prompt you to create a -new Change Request. +1. Click **Feature Change Requests**. +1. Select a Change Request to review. +1. Review the current and new Flag values. +1. Click **Approve** to record your decision. -When creating a Change Request, you will need to provide the following: +### Publish a Feature Change Request -* The **title** of the Change Request. -* An **optional description** of the reason for the Change Request. -* Any number of **assignees**. These individuals will receive an email - notification about the Change Request. +When the required number of approvals have been made, you will be able to publish the Feature Change Request. -## Approve a Change Request +### Notifications -Change Requests awaiting approval are listed in the **Change Request** area. +Flagsmith sends email notifications at the following points in the Change Request lifecycle: -1. Click on a **Change Request** to view its details. -2. Review the current and new Flag values. -3. Click **Approve** to record your decision. +| Event | Who is notified | +| --------------------------------------------- | ---------------------------------------------------------------------------- | +| A Change Request is assigned to an individual | The assignee receives an email informing them that their approval is pending | +| A Change Request is approved | The CR author receives an email confirming the approval | +| A Change Request is assigned to a group | All members of the group receive a notification via background task | -## Publish a Change Request +:::note **Self-hosting?** To ensure these email notifications are delivered correctly, you must configure the +[self-hosted email setup](https://docs.flagsmith.com/deployment-self-hosting/core-configuration/email-setup). ::: -When the required number of approvals have been made, you will be able to -publish the Change Request. The Change Request will immediately come into -effect once the **Publish Change** button is clicked. +**What does not trigger a notification:** -## Notifications +- **Committing a Change Request** — no email is sent when a CR is published. Only audit log entries are created for the + affected feature states. +- **Rejecting a Change Request** — there is no first-class rejection flow. Closing a CR means deleting it, and no email + is sent on deletion. -Flagsmith sends email notifications at the following points in the Change -Request lifecycle: +### Feature Change Request Permissions -| Event | Who is notified | -| ----- | --------------- | -| A Change Request is assigned to an individual | The assignee receives an email informing them that their approval is pending | -| A Change Request is approved | The CR author receives an email confirming the approval | -| A Change Request is assigned to a group | All members of the group receive a notification via background task | +| Action | Required permission | +| ------------------------ | ---------------------- | +| Create a Change Request | Create change request | +| Approve a Change Request | Approve change request | +| Publish a Change Request | Update feature state | -:::note -**Self-hosting?** To ensure these email notifications are delivered correctly, you must configure the [self-hosted email setup](https://docs.flagsmith.com/deployment-self-hosting/core-configuration/email-setup). -::: +These permissions can be configured at both the project level and the environment level. For example, you might allow +all developers to create change requests in Production, but only senior engineers to approve and publish them. See +[Role-based access control](/administration-and-security/access-control/rbac) for details on configuring permissions. -**What does not trigger a notification:** +## Segment Change Requests + +Segment Change Requests apply the same four-eyes workflow (create, approve, publish) to changes to a **segment's +definition** — its rules and conditions. Because segments are defined once for the whole project and a single rule +change can affect identities in multiple environments, these Change Requests are scoped to the **project** rather than +to a single environment. + +### Enable Segment Change Requests + +![Enable Segment Change Requests](/img/change-requests/enable-segment-change-requests.png) + +1. Go to the **Project Settings** page. +1. Enable the **Segment Change Requests** setting. +1. Select the required number of approvals for each Change Request to be applied. + +### Create a Segment Change Request + +Once a project is configured with Segment Change Requests enabled, **editing an existing segment** will require a Change +Request to be submitted. + +While creating a new segment (including rules and conditions) is not gated, a segment only affects identities once +feature overrides are added to it. Adding segment overrides to a feature can be gated by +[Feature Change Requests](#feature-change-requests). + +When creating a Segment Change Request, you will need to provide it a **title** and, optionally, a **description**. + +![A Segment Change Request](/img/change-requests/segment-change-request.png) + +While a Change Request for a segment is open, your edits are held as a draft version of the segment. The live segment +keeps its current rules, so flag evaluation is unaffected until the Change Request is published. + +### Approve a Segment Change Request + +Segment Change Requests awaiting approval are listed under the **Segment Change Requests** tab. + +1. Select a Change Request to review. +1. Review the proposed segment rules and conditions. +1. Click **Approve** to record your decision. + +### Publish a Segment Change Request + +When the required number of approvals have been made, you will be able to publish the Segment Change Request. On +publish, Flagsmith takes a revision of the current live segment — preserving the previous rules for history — and then +applies the proposed rules to the live segment. + +### Segment Change Request Permissions + +Segment Change Requests use **project-level** permissions, which are separate from the environment-level permissions +used by Feature Change Requests: + +| Action | Required permission | +| ------------------------ | -------------------------------------------------------- | +| Create a Change Request | Create project level change requests | +| Approve a Change Request | Approve project level change requests | +| Publish a Change Request | Manage segments and Manage project level change requests | -- **Committing a Change Request** — no email is sent when a CR is published. - Only audit log entries are created for the affected feature states. -- **Rejecting a Change Request** — there is no first-class rejection flow. - Closing a CR means deleting it, and no email is sent on deletion. -- **Webhook events** — there are no webhook events for CR lifecycle changes. - The organisation webhook receives audit log events only. - -## Permissions - -| Action | Required permission | -| ------------------------ | ------------------------- | -| Create a Change Request | Create change request | -| Approve a Change Request | Approve change request | -| Publish a Change Request | Update feature state | - -These permissions can be configured at both the project level and the -environment level. For example, you might allow all developers to create -change requests in Production, but only senior engineers to approve and -publish them. See -[Role-based access control](/administration-and-security/access-control/rbac) -for details on configuring permissions. +See [Role-based access control](/administration-and-security/access-control/rbac) for details on configuring +permissions. diff --git a/docs/static/img/change-requests/enable-feature-change-requests.png b/docs/static/img/change-requests/enable-feature-change-requests.png new file mode 100644 index 000000000000..c08627a897d5 Binary files /dev/null and b/docs/static/img/change-requests/enable-feature-change-requests.png differ diff --git a/docs/static/img/change-requests/enable-segment-change-requests.png b/docs/static/img/change-requests/enable-segment-change-requests.png new file mode 100644 index 000000000000..ad4f1bc66f0f Binary files /dev/null and b/docs/static/img/change-requests/enable-segment-change-requests.png differ diff --git a/docs/static/img/change-requests/feature-change-request.png b/docs/static/img/change-requests/feature-change-request.png new file mode 100644 index 000000000000..c0dd23405c91 Binary files /dev/null and b/docs/static/img/change-requests/feature-change-request.png differ diff --git a/docs/static/img/change-requests/segment-change-request.png b/docs/static/img/change-requests/segment-change-request.png new file mode 100644 index 000000000000..a457ef25f0a8 Binary files /dev/null and b/docs/static/img/change-requests/segment-change-request.png differ diff --git a/frontend/e2e/helpers/e2e-helpers.playwright.ts b/frontend/e2e/helpers/e2e-helpers.playwright.ts index 543efe790b67..73602f42614d 100644 --- a/frontend/e2e/helpers/e2e-helpers.playwright.ts +++ b/frontend/e2e/helpers/e2e-helpers.playwright.ts @@ -1034,7 +1034,7 @@ export class E2EHelpers { log(`Create change request: ${title}`); // Click the update/create change request button - // When 4-eyes is enabled, this button says "Create Change Request" + // When four-eyes is enabled, this button says "Create Change Request" await this.click('#update-feature-btn'); await this.page.waitForTimeout(1000); diff --git a/frontend/e2e/tests/change-request-test.pw.ts b/frontend/e2e/tests/change-request-test.pw.ts index d58cc1af6e44..f1b681acb30c 100644 --- a/frontend/e2e/tests/change-request-test.pw.ts +++ b/frontend/e2e/tests/change-request-test.pw.ts @@ -8,7 +8,7 @@ import { } from '../config' test.describe('Change Request Tests', () => { - test('Change requests can be created, approved, and published with 4-eyes approval @enterprise', async ({ + test('Change requests can be created, approved, and published with four-eyes approval @enterprise', async ({ page, }, testInfo) => { const { diff --git a/frontend/web/components/PlanBasedAccess.tsx b/frontend/web/components/PlanBasedAccess.tsx index e816e165a71a..e2d56803b3cf 100644 --- a/frontend/web/components/PlanBasedAccess.tsx +++ b/frontend/web/components/PlanBasedAccess.tsx @@ -22,12 +22,12 @@ export const featureDescriptions: Record = { title: 'Two-Factor Authentication', }, '4_EYES': { - description: 'Add a 4-eyes approval mechanism to your feature changes.', + description: 'Add a four-eyes approval mechanism to your feature changes.', docs: 'https://docs.flagsmith.com/advanced-use/change-requests', title: 'Feature Change Requests', }, '4_EYES_PROJECT': { - description: 'Add a 4-eyes approval mechanism to your segment changes.', + description: 'Add a four-eyes approval mechanism to your segment changes.', docs: 'https://docs.flagsmith.com/advanced-use/change-requests', title: 'Segment Change Requests', }, diff --git a/frontend/web/components/ProjectChangeRequestsLink.tsx b/frontend/web/components/ProjectChangeRequestsLink.tsx index 7a52ef651c73..d6179767fceb 100644 --- a/frontend/web/components/ProjectChangeRequestsLink.tsx +++ b/frontend/web/components/ProjectChangeRequestsLink.tsx @@ -33,7 +33,7 @@ const ProjectChangeRequestsLink: FC = ({ id={`segments-link`} to={`/project/${projectId}/change-requests`} > - Change Requests{' '} + Segment Change Requests{' '} {changeRequests ? ( {changeRequests} ) : null} diff --git a/frontend/web/components/SegmentOverrides.js b/frontend/web/components/SegmentOverrides.js index 7c731dc30dc9..0231bcd92428 100644 --- a/frontend/web/components/SegmentOverrides.js +++ b/frontend/web/components/SegmentOverrides.js @@ -14,7 +14,6 @@ import FeatureListStore from 'common/stores/feature-list-store' import CreateSegmentModal from './modals/CreateSegment' import SegmentSelect from './SegmentSelect' import JSONReference from './JSONReference' -import InfoMessage from './InfoMessage' import Permission from 'common/providers/Permission' import Constants from 'common/constants' import Icon from './icons/Icon' @@ -795,23 +794,6 @@ class TheComponent extends Component {
{!this.props.id && (
- - Segment overrides override the environment defaults, - prioritise them by dragging it to the top of the list. - Segment overrides will only apply when you identify via - the SDK, any identity overrides will take priority.{' '} - - Check the Docs for more details - - . - = ({ return ( <> - + + +
+ + Identity Overrides{' '} + + + } + place='top' + > + {Constants.strings.IDENTITY_OVERRIDES_DESCRIPTION} + +
+ {!isEdge && ( + + )} +
+
+ Identity Overrides apply to all individual identities listed here.{' '} + + Learn more + +
+ + Identity Overrides are not subject to Change Requests and apply + immediately.{' '} + + Learn more + + - - Identity Overrides{' '} - - - } - place='top' - > - {Constants.strings.IDENTITY_OVERRIDES_DESCRIPTION} - -
- - Identity overrides override feature values for individual - identities. The overrides take priority over an segment - overrides and environment defaults. Identity overrides will - only apply when you identify via the SDK.{' '} - - Check the Docs for more details - - . - -
- - } - action={ - !isEdge && ( - - ) - } + className='no-pad' items={data?.results} paging={{ ...data, currentPage: page }} renderSearchWithNoResults diff --git a/frontend/web/components/modals/create-feature/tabs/SegmentOverridesTab.tsx b/frontend/web/components/modals/create-feature/tabs/SegmentOverridesTab.tsx index d3474605759a..b1009a0e8f02 100644 --- a/frontend/web/components/modals/create-feature/tabs/SegmentOverridesTab.tsx +++ b/frontend/web/components/modals/create-feature/tabs/SegmentOverridesTab.tsx @@ -175,6 +175,22 @@ const SegmentOverridesTab: FC = ({ )} +
+

+ Segment Overrides apply when the identity traits match the segment + rules. +

{' '} +

+ Identity Overrides always override Segment Overrides.{' '} + + Learn more + +

{' '} +
{segmentOverrides ? ( <> @@ -206,6 +222,9 @@ const SegmentOverridesTab: FC = ({ {!showCreateSegment && } {!showCreateSegment && (
+

+ Drag overrides to adjust priority. +

{is4Eyes && isVersioned ? 'This will create a change request with any value and segment override changes for the environment' diff --git a/frontend/web/components/navigation/navbars/EnvironmentNavbar.tsx b/frontend/web/components/navigation/navbars/EnvironmentNavbar.tsx index 3c834ad5303e..fe200af02c82 100644 --- a/frontend/web/components/navigation/navbars/EnvironmentNavbar.tsx +++ b/frontend/web/components/navigation/navbars/EnvironmentNavbar.tsx @@ -116,7 +116,7 @@ const EnvironmentNavbar: FC = ({ to={`/project/${projectId}/environment/${environmentId}/change-requests/`} >

- Change Requests{' '} + Feature Change Requests{' '} {changeRequests ? ( {changeRequests} diff --git a/frontend/web/components/pages/ChangeRequestDetailPage.tsx b/frontend/web/components/pages/ChangeRequestDetailPage.tsx index c46df3e5d965..e5b683e093c0 100644 --- a/frontend/web/components/pages/ChangeRequestDetailPage.tsx +++ b/frontend/web/components/pages/ChangeRequestDetailPage.tsx @@ -328,7 +328,7 @@ const ChangeRequestDetailPage: FC = ({ match }) => { = ({