diff --git a/README.md b/README.md index 37a25461dbed..029559451829 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ Check out [the CONTRIBUTING.md file](./CONTRIBUTING.md) for contribution guideli - 2 [environments](https://docs.getunleash.io/reference/environments) - Organize feature flags using [tags](https://docs.getunleash.io/reference/feature-toggles#tags) - Out-of-the-box integrations with popular tools ([Slack](https://docs.getunleash.io/addons/slack), [Microsoft Teams](https://docs.getunleash.io/addons/teams), [Datadog](https://docs.getunleash.io/addons/datadog)) + integrate with anything with [webhooks](https://docs.getunleash.io/addons/webhook) -- [Dashboard for managing technical debt](https://docs.getunleash.io/reference/technical-debt) and [stale flags](https://docs.getunleash.io/reference/technical-debt#stale-and-potentially-stale-toggles) +- [Insights for managing technical debt](https://docs.getunleash.io/reference/technical-debt) and [stale flags](https://docs.getunleash.io/reference/technical-debt#stale-and-potentially-stale-flags) - API-first: _everything_ can be automated. No exceptions. - [12 official client SDKs](https://docs.getunleash.io/reference/sdks#official-sdks), and 10 [community-contributed client SDKs](https://docs.getunleash.io/reference/sdks#community-sdks) - Run it via Docker with the [official Docker image](https://hub.docker.com/r/unleashorg/unleash-server) or as a pure Node.js application diff --git a/frontend/src/component/featureTypes/FeatureTypeEdit/FeatureTypeForm/FeatureTypeForm.tsx b/frontend/src/component/featureTypes/FeatureTypeEdit/FeatureTypeForm/FeatureTypeForm.tsx index 5bd994bf3178..d978c060eb1d 100644 --- a/frontend/src/component/featureTypes/FeatureTypeEdit/FeatureTypeForm/FeatureTypeForm.tsx +++ b/frontend/src/component/featureTypes/FeatureTypeEdit/FeatureTypeForm/FeatureTypeForm.tsx @@ -151,7 +151,7 @@ export const FeatureTypeForm: VFC = ({


diff --git a/frontend/src/component/project/Project/ProjectHealth/ReportTable/ReportCard/ReportCard.tsx b/frontend/src/component/project/Project/ProjectHealth/ReportTable/ReportCard/ReportCard.tsx index e8e516012f0c..ed9965c418b6 100644 --- a/frontend/src/component/project/Project/ProjectHealth/ReportTable/ReportCard/ReportCard.tsx +++ b/frontend/src/component/project/Project/ProjectHealth/ReportTable/ReportCard/ReportCard.tsx @@ -88,7 +88,7 @@ export const ReportCard = ({ healthReport }: IReportCardProps) => { it will be marked as potentially stale. diff --git a/src/lib/features/feature-toggle/feature-toggle-controller.ts b/src/lib/features/feature-toggle/feature-toggle-controller.ts index fabe2591a51f..2a30b16a6e37 100644 --- a/src/lib/features/feature-toggle/feature-toggle-controller.ts +++ b/src/lib/features/feature-toggle/feature-toggle-controller.ts @@ -571,7 +571,7 @@ export default class ProjectFeaturesController extends Controller { tags: ['Features'], operationId: 'staleFeatures', summary: 'Mark features as stale / not stale', - description: `This endpoint marks the provided list of features as either [stale](https://docs.getunleash.io/reference/technical-debt#stale-and-potentially-stale-toggles) or not stale depending on the request body you send. Any provided features that don't exist are ignored.`, + description: `This endpoint marks the provided list of features as either [stale](https://docs.getunleash.io/reference/technical-debt#stale-and-potentially-stale-flags) or not stale depending on the request body you send. Any provided features that don't exist are ignored.`, requestBody: createRequestSchema('batchStaleSchema'), responses: { 202: emptyResponse, diff --git a/src/lib/openapi/spec/deprecated-project-overview-schema.ts b/src/lib/openapi/spec/deprecated-project-overview-schema.ts index 61c78427526d..f1e1c52e1656 100644 --- a/src/lib/openapi/spec/deprecated-project-overview-schema.ts +++ b/src/lib/openapi/spec/deprecated-project-overview-schema.ts @@ -75,7 +75,7 @@ export const deprecatedProjectOverviewSchema = { type: 'number', example: 50, description: - "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#health-rating) on a scale from 0 to 100", + "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100", }, environments: { type: 'array', diff --git a/src/lib/openapi/spec/health-overview-schema.ts b/src/lib/openapi/spec/health-overview-schema.ts index 1eec1ad8b762..5224495e9394 100644 --- a/src/lib/openapi/spec/health-overview-schema.ts +++ b/src/lib/openapi/spec/health-overview-schema.ts @@ -75,7 +75,7 @@ export const healthOverviewSchema = { health: { type: 'integer', description: - 'The overall [health rating](https://docs.getunleash.io/reference/technical-debt#health-rating) of the project.', + 'The overall [health rating](https://docs.getunleash.io/reference/technical-debt#project-status) of the project.', example: 95, }, environments: { diff --git a/src/lib/openapi/spec/personal-dashboard-schema.ts b/src/lib/openapi/spec/personal-dashboard-schema.ts index fe3717676ff6..f5d0b35199b7 100644 --- a/src/lib/openapi/spec/personal-dashboard-schema.ts +++ b/src/lib/openapi/spec/personal-dashboard-schema.ts @@ -103,7 +103,7 @@ export const personalDashboardSchema = { example: 50, minimum: 0, description: - "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#health-rating) on a scale from 0 to 100", + "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100", }, memberCount: { type: 'integer', diff --git a/src/lib/openapi/spec/project-insights-schema.ts b/src/lib/openapi/spec/project-insights-schema.ts index 10f24bafa3fc..d86a0515f117 100644 --- a/src/lib/openapi/spec/project-insights-schema.ts +++ b/src/lib/openapi/spec/project-insights-schema.ts @@ -28,7 +28,7 @@ export const projectInsightsSchema = { rating: { type: 'integer', description: - "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#health-rating) on a scale from 0 to 100", + "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100", example: 95, }, activeCount: { diff --git a/src/lib/openapi/spec/project-overview-schema.ts b/src/lib/openapi/spec/project-overview-schema.ts index 49ff96f33a0a..3c4a7e5a8f95 100644 --- a/src/lib/openapi/spec/project-overview-schema.ts +++ b/src/lib/openapi/spec/project-overview-schema.ts @@ -76,7 +76,7 @@ export const projectOverviewSchema = { type: 'number', example: 50, description: - "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#health-rating) on a scale from 0 to 100", + "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100", }, environments: { type: 'array', diff --git a/src/lib/openapi/spec/project-schema.ts b/src/lib/openapi/spec/project-schema.ts index 21d1edd55ffc..5851db969c19 100644 --- a/src/lib/openapi/spec/project-schema.ts +++ b/src/lib/openapi/spec/project-schema.ts @@ -29,7 +29,7 @@ export const projectSchema = { type: 'number', example: 50, description: - "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#health-rating) on a scale from 0 to 100", + "An indicator of the [project's health](https://docs.getunleash.io/reference/technical-debt#project-status) on a scale from 0 to 100", }, featureCount: { type: 'number', diff --git a/src/lib/routes/admin-api/project/health-report.ts b/src/lib/routes/admin-api/project/health-report.ts index 77740cbae3a1..88291f023449 100644 --- a/src/lib/routes/admin-api/project/health-report.ts +++ b/src/lib/routes/admin-api/project/health-report.ts @@ -48,7 +48,7 @@ export default class ProjectHealthReport extends Controller { operationId: 'getProjectHealthReport', summary: 'Get a health report for a project.', description: - 'This endpoint returns a health report for the specified project. This data is used for [the technical debt dashboard](https://docs.getunleash.io/reference/technical-debt#the-technical-debt-dashboard)', + 'This endpoint returns a health report for the specified project. This data is used for [the technical debt insights](https://docs.getunleash.io/reference/technical-debt)', responses: { 200: createResponseSchema('healthReportSchema'), ...getStandardResponses(401, 403, 404), diff --git a/website/docs/reference/change-requests.mdx b/website/docs/reference/change-requests.mdx index 026ccdacc35d..e0ff79a58abf 100644 --- a/website/docs/reference/change-requests.mdx +++ b/website/docs/reference/change-requests.mdx @@ -10,61 +10,56 @@ import VideoContent from '@site/src/components/VideoContent.jsx'; ::: +## Overview - - - -Feature flagging is a powerful tool, and because it's so powerful, you sometimes need to practice caution. The ability to have complete control over your production environment comes at the cost of the potential to make mistakes in production. Change requests were introduced in version 4.19.0 to alleviate this fear. Change requests allow you to group changes together and apply them to production at the same time, instead of applying changes directly to production. This allows you to make multiple changes to feature flags and their configuration and status (on/off) all at once, reducing the risk of errors in production. +Change requests allow you to require an additional approval step before any changes can be made in an environment. This functionality supports the "four-eyes principle", ensuring compliance in industries with strict legal or regulatory requirements. + +Change requests also allow you to group changes and [apply them at a specific point in time](#scheduled-change-requests). -Our goal is developer efficiency, but we also recognize that we have users and customers in highly regulated industries, governed by law and strict requirements. Therefore, we have added a capability to change requests that will allow you to enforce the _4 eyes principle_. +Change requests can be enabled on a per-project and per-environment basis. This allows you to differentiate your configurations across different environments, such as production and development. -## Change request configuration +You can require up to 10 approvals for a change request. -The change request configuration can be set up per project, per environment. This means that you can have different change request configurations for different environments, such as production and development. This is useful because different environments may have different requirements, so you can customize the change request configuration to fit those requirements. However, this also means that you cannot change flags across projects in the same change request. - -Currently there are two configuration options for change requests: -* **Enable change requests** - This is a boolean value that enables or disables change requests for the project and environment. -* **Required approvals** - This is an integer value that indicates how many approvals are required before a change request can be applied. Specific permissions are required to approve and apply change requests. - -The change request configuration can be set up in the project settings page: + -![Change request configuration](/img/change-request-configuration.png) +## Change request permissions +Anyone with project access can create a change request; however, only users with specific permissions can approve, apply, or skip them. None of the predefined roles have any change request permissions, so you must create [custom project roles](/reference/rbac#custom-project-roles). -## Change request flow +The **skip change requests** [permission](/reference/rbac#environment-permissions) allows users to bypass the change request flow. With this permission in place, you can quickly turn a flag on or off in case you experience issues with a release. This permission alone does not grant access to any other resource, so the user still needs additional permissions, such as to turn a flag on or off. -Once a change request flow is configured for a project and environment, you can no longer directly change the status of a flag. Instead, you will be asked to put your changes into a draft. The change request flow handles the following scenarios: +Admin users also see the change request flow, but they can approve and apply their own changes. -* Updating the status of a flag in the environment -* Adding a strategy to the feature flag in the environment -* Updating a strategy of a feature flag in the environment -* Deleting a strategy from a feature flag in the environment +## Enable change requests for a project and environment -The flow can be summarized as follows: +To enable change requests for a project, do the following: -![Change request flow](/img/change-request-flow.png) +1. Open the project and go to **Settings > Change request configuration**. +2. Toggle **Status** for the environment where you want to enable change requests. +3. Select the required number of approvals. -Once a change is added to a draft, the draft needs to be completed before another change request can be opened. The draft is personal to the user that created the change request draft, until it is sent for review. Once changes are added to draft, the user will have a banner in the top of the screen indicating that a draft exists. The state of a change request can be one of the following: +![Change request configuration](/img/change-request-configuration.png) -* **Draft** - The change request is in draft mode, and can be edited by the user that created the draft. -* **In review** - The change request is in review mode, and can be edited by the user that created the draft. If editing occurs, all current approvals are revoked -* **Approved** - The change request has been approved by the required number of users. -* **Scheduled** - The change request has been scheduled and will be applied at the scheduled time (unless there are conflicts, as described in the section on [scheduling change requests](#scheduled-changes)). -* **Applied** - The change request has been applied to the environment. The feature flag configuration is updated. -* **Cancelled** - The change request has been cancelled by the change request author or by an admin. -* **Rejected** - The change request has been rejected by the reviewer or by an admin. +## Change request flow -![Change request banner](/img/change-request-banner.png) +Once change requests are enabled for a project and environment, you cannot directly change the status and configuration of a feature flag. Instead, changes are grouped into a change request draft. -Once a change request is sent to review by the user who created it, it becomes available for everyone in the change request tab in the project. +![Change request overview](/img/change-request-overview.svg) -From here, you can navigate to the change request overview page. This page will give you information about the changes the change request contains, the state the change request is in, and what action needs to be taken next. +Once you make the first modification in an environment that has change requests enabled, any subsequent changes must be added to the same draft. This draft remains private to its author until it's submitted for review. While a draft is active, a banner at the top of the screen informs the author that changes are pending. -![Change request banner](/img/change-request-overview.png) +A change request can go through the following states: +* **Draft** - The change request is pending, only visible to the author, and can still be edited. +* **In review** - The change request has been submitted for review. The author can still make edits, but doing so will revoke any existing approvals. +* **Approved** - The change request has received the required number of approvals. +* **Scheduled** - The change request is scheduled to be applied at a future time (assuming no [conflicts](#scheduling-errors)). +* **Applied** - The changes have been successfully applied to the environment. +* **Cancelled** - The change request has been canceled by the author or by an admin. +* **Rejected** - The change request has been rejected by a reviewer or by an admin. -From here, if you have the correct permissions, you can approve and schedule or apply the change request. Once applied, the changes will be live in production. +Once submitted, the change request appears in the project's **Change requests** tab. From there, you can view details of the proposed changes, the current status of the request, and the next steps required. Users with sufficient permissions can approve or reject, and apply or [schedule](#scheduled-change-requests) the changes. -### Scheduled changes +## Scheduled change requests :::note Availability @@ -72,76 +67,30 @@ From here, if you have the correct permissions, you can approve and schedule or ::: -When a change request is approved, you can schedule it to be applied at a later time. This allows you to group changes together and apply them at a time that is convenient for you, such as during a maintenance window, or at a time when you know there will be less traffic to your application. - -Scheduled changes can be rescheduled, applied immediately, or rejected. They can not be edited or moved back to any of the previous states. - -When a scheduled change request is applied, the person who scheduled it and the person who created it will each receive a notification. - -#### Conflicts - -If a change request contains changes that affect a flag that has been archived or a strategy that has been deleted, the change request can not be applied. Unleash will warn you ahead of time if you make changes that conflict with a scheduled change request. - -Further, if a strategy, project segment, or [environment-level variant](feature-toggle-variants) configuration that is updated in a scheduled change request is updated before the scheduled application time (for instance by a different change request being applied or by updates that circumvent the change request flow), Unleash will suspend the scheduled change request. - -The reason for this is that the scheduled change request would overwrite the recent changes made to the strategy, segment, or environment variants. This could cause unwanted changes to occur, so we require you to take manual action. - -If a change request has been suspended because a strategy, segment, or environment-level variant configuration has been updated, you can still reschedule, apply, or reject the change request. Any of these actions will put the change request back into the regular flow. You **cannot** edit the changes of a scheduled change request, so if you want to include the recent changes with the changes in your scheduled change request, you will need to create a new change request. - -Again, please be aware that if a strategy, segment, or environment variants affected by a scheduled change request are updated after the change request was scheduled, the application of the scheduled change request will overwrite those changes with the state in the scheduled change request. - -If you make one of the changes mentioned in this section, Unleash send out emails to the change request author and to the person who scheduled the change request, letting them know what has happened. - -#### Application failure - -If Unleash fails to apply a scheduled change request, the change request will remain in the scheduled state. You can reschedule it and try to apply it again later, or you can reject it. Note that if a strategy in the change request has been deleted or a flag has been archived, the change request can not be applied, so rescheduling it will not help. In these cases, you can either reject the change request, or if the flag has been archived, revive the flag and reschedule it. +When a change request is approved, you can schedule it to be applied later. This allows you to group and apply them at a specific time, such as during a maintenance window or periods of low traffic. -If a scheduled change request can not be applied, Unleash will send a notification to the person who scheduled it and to the person who created the change request. +Scheduled changes can be rescheduled, applied immediately, or rejected, but they cannot be edited or moved back to a previous state. -#### Edge cases: what happens when ...? +Scheduling changes using change requests gives you a centralized view of changes across multiple flags and strategies, making it easy to reschedule or reject them. However, [potential conflicts](#scheduling-errors) can cause the scheduling to fail. -If the user who scheduled a change request is deleted from the Unleash users list before the scheduled time, the changes will **not** be applied. Instead, the schedule will be put into a special **suspended state**. A change request with suspended schedule will not be applied at its scheduled time. A user with the required permission can reschedule, apply, or reject the change request. Any of these actions will put the change request back into the regular flow. +Alternatively, you can use constraints or segments with the `DATE_AFTER` [operator](/reference/activation-strategies#date-and-time-operators). This approach avoids conflicts, ensures SDKs are aware of changes in advance, and allows them to apply the changes even if they temporarily fail to connect to Unleash. -If a change request has been scheduled and change requests are then disabled for the project and environment, the change request **will still be applied** according to schedule. To prevent this, you can reject the scheduled change request. +### Scheduling errors +Unleash suspends a scheduled change request if: +- The change request includes updates to a flag that has been archived or a strategy that has been deleted. +- The change request includes a strategy, segment, or variant that has been updated. +- The user who scheduled a change request is deleted from the users list before the scheduled time. -#### Different ways to schedule changes +You must manually review suspended change requests to reschedule, apply, or reject them. -Unleash currently offers two distinct ways to schedule changes. Each method has its own pros and cons, and you can also combine the methods for maximum flexibility. +For any suspended or failed change requests, Unleash sends out email notifications to the change request author and to the person who scheduled the change request. Additionally, Unleash displays warnings for flag or strategy deletions that conflict with existing scheduled change requests. -The first method is through scheduled change requests, as we have explained in the preceding sections. Scheduled change requests make it easy to see all the changes across multiple flags and strategies in one view and makes it easy to reschedule or reject them. However, because scheduled changes rely on flags and strategy configurations, conflicts can arise causing the schedule to fail. +If Unleash fails to apply a scheduled change request, the change request remains in the scheduled state. You can either reschedule and attempt to apply it again or reject it. -The second method uses Unleash's [constraints](activation-strategies#constraints) and the [DATE_AFTER operator](activation-strategies#date-and-time-operators) to encode when changes should take effect. The pros of this method is that because these changes can be applied immediately, you won't run into any conflicts when they happen. The cons are that you'll need to apply the same constraints to all the parts that you want to change and that there is no easy way to see all the changes in one view. You also can not scheduled changes to a segment in this way. When using this option, we recommend that you use [segments](segments) if you want to schedule multiple changes, so that their application time stays in sync. +If a change request is scheduled and change requests are later disabled for the project or environment, the request will still be applied as scheduled. To prevent this, you must reject the scheduled change request. -Another important distinction is how these changes affect your connected SDKs. If you use constraints (or segments), then any connected SDK will be aware of the schedule ahead of time. That means that even if the SDK can not connect to Unleash at the scheduled time, it will still activate the changes because it's encoded in its constraints. On the other hand, if you use change requests to schedule changes, SDKs **must** update their configuration after the scheduled time to be aware of the changes. - -## Change request permissions - -Change requests have their own set of environment-specific permissions that can be applied to [custom project roles](rbac#custom-project-roles). These permissions let users - -- approve/reject change requests -- apply change requests -- skip the change request flow - -None of the predefined roles have any change request permissions, so you must create your own project roles to take advantage of change requests. In other words, even a user with the project "owner" role can not approve or apply change requests. - -There is no permission to create change requests: **Anyone can create change requests**, even Unleash users with the [root viewer role](rbac#predefined-roles). Change requests don't cause any changes until approved and applied by someone with the correct permissions. - -You can prevent non-project members from submitting change requests by setting a [protected project collaboration mode](project-collaboration-mode). - -### Circumventing change requests - -The **skip change requests** permission allows users to bypass the change request flow. Users with this permission can change feature flags directly (they are of course still limited by any other permissions they have). - -The skip change requests permission was designed to make it possible to quickly turn something off in the event that a feature release didn't go as expected or was causing issues. - -The skip change requests permission does **not** grant any other permissions, so to be allowed to do things as enabling/disabling a flag, the user will still need the explicit permissions to do that too. - -In the UI non-admin users with **skip change requests** permission and explicit permission to perform the actual action will be able to make changes directly without change requests. - -Admin users will always see the change request UI so that they can test the change request flow. Admin users can however self-approve and self-apply their own changes. - -## Change Request for segments +## Change requests for segments :::note Availability @@ -149,32 +98,14 @@ Admin users will always see the change request UI so that they can test the chan ::: -Changes to project [segments](segments) (as opposed to global segments) also go through the change request process. This is to prevent a backdoor in the change request process. - -Since projects segments are not environment specific and change requests are always environment specific we allow to attach segment change to any environment with change requests enabled. -When you make changes though the Change Request UI it will automatically select first environment with change requests enabled, giving priority to [production](environments#environment-types) environments. - -Changes to segments can be only circumvented by admin users through the API calls. - -## Change Request Preview Playground - -To verify that a change request is correct, you can preview the result of change request's application in a change request [playground](playground). - -![Change request preview](/img/change-request-preview.png) - -From the change request overview page, go to the corresponding [playground](playground) and evaluate all your flags in the project and environment that your change request applies too. - -![Change request playground evaluation](/img/change-request-playground-evaluation.png) +Changes to project [segments](/reference#segments), unlike global segments, also go through the change request process. -[Unleash context](playground#the-unleash-context) can be adjusted in the same way as in a regular playground, but the project and environment cannot be changed as they are derived from the change request itself. -Once the evaluation results confirm the changes in your change request are correct, go back to the change request overview and proceed with the approval or rejection. +While change requests are environment-specific, project segments are not. For this reason, Unleash allows you to attach segment changes to any environment where change requests are enabled. By default, Unleash selects the first available environment with change requests enabled, prioritizing [production](/reference/environments#environment-types) environments. +Only Admin users can bypass the change request process for project segments through API calls. -Change request preview simulates the application of changes in a non-persistent transaction. -You still need to apply the changes to persist them for the SDKs to see the changes. -A change request can only be previewed when the change request is In Review, Approved, or Scheduled. -It cannot be previewed when the change request is in Draft, Applied, Cancelled, or Rejected status. +## Change request preview +To verify a change request, you can preview the changes in [Playground](/reference/playground) by clicking **Preview changes**. You can adjust [Unleash context](/reference/playground#the-unleash-context), but the project and environment remain fixed as they are determined by the change request. -Change request preview does not require special permissions like approve/reject change requests or apply change requests. -It allows more users to provide feedback on the correctness of the changes. +You can only preview a change request in **In Review**, **Approved**, or **Scheduled** states. \ No newline at end of file diff --git a/website/docs/reference/feature-toggles.mdx b/website/docs/reference/feature-toggles.mdx index bfc3d9d62409..d32761261a77 100644 --- a/website/docs/reference/feature-toggles.mdx +++ b/website/docs/reference/feature-toggles.mdx @@ -43,10 +43,10 @@ Variants can also include payloads such as JSON, CSV, or strings to provide user ::: -Feature flags have a type to indicate their use case and help you manage and sort your flags. A feature flag's type determines its [expected lifetime](#expected-lifetime) and its visual appearance in the Admin UI. +Feature flags have a type to indicate their use case and help you manage and sort your flags. A feature flag's type determines its expected lifetime and its visual appearance in the Admin UI. -The following is a list of feature flag types: +The following is a list of feature flag types, their purpose, and expected lifetime: | Feature flag type | Used to | Expected lifetime | |---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------| @@ -60,7 +60,7 @@ To learn more, visit [Types of feature flags](../what-is-a-feature-flag#types-of ## Feature flag state -A feature flag can have one of the following states: _active_, _potentially stale_, or _stale_. Unleash marks all flags as _potentially stale_ automatically once they pass their [expected lifetime](#expected-lifetime). +A feature flag can have one of the following states: _active_, _potentially stale_, or _stale_. Unleash marks all flags as _potentially stale_ automatically once they pass their expected lifetime. State gives you an indication of when to [clean up a feature flag in code](./technical-debt). @@ -70,7 +70,7 @@ You can also manually change the state on a feature flag's page by going to **Ov Marking a flag as stale helps you deprecate a feature flag without removing the active configuration for connected applications. -You can use this to signal to your team to stop using the feature in your applications. Stale flags will show as stale in the [technical debt dashboard](./technical-debt). +You can use this to signal to your team to stop using the feature in your applications. Stale flags will show as stale in the [project status dashboard](./technical-debt#project-health). Marking a flag as stale generates the `feature-stale-on` [event](/reference/events#feature-stale-on). You can use [an integration](/reference/integrations) to trigger automated workflows, such as posting notifications in a Slack channel, breaking project builds if the code contains stale flags, or automatically opening pull requests to remove stale flags from the code. @@ -187,15 +187,17 @@ Once archived, the flag is no longer available to client SDKs. ### View archived flags -To view an archived feature flag, open the project that contains the flag and select the **Archived flags** tab. +To view archived feature flags in a project, use the **Show only archived** filter in the **Feature flags** list. ### Revive a feature flag -You can revive archived flags by navigating to the [feature flag archive](#view-archived-flags) and clicking **Revive feature flag**. Revived flags are in an inactive state by default. +To revive an archived flag, use [filters](#view-archived-flags) to find the flag and click **Revive feature flag**. Revived flags are in an inactive state by default. + +![Archive a feature flag](/img/revive-archived-flag.png) ### Delete a feature flag -You can delete archived flags by navigating to the [feature flag archive](#view-archived-flags) and clicking **Delete feature flag**. +To delete an archived flag, use [filters](#view-archived-flags) to find the flag and click **Delete feature flag**. However, we recommend not deleting feature flags unless they are completely removed from your codebase. If you delete a flag and later create a new one with the same name, it might unintentionally reactivate old code that still references the original flag. diff --git a/website/docs/reference/projects.mdx b/website/docs/reference/projects.mdx index e58b3d6dfb63..4be0f719b103 100644 --- a/website/docs/reference/projects.mdx +++ b/website/docs/reference/projects.mdx @@ -38,7 +38,7 @@ To create a new project: You can update all aspects of a project except its ID. -To update a project, go to **Projects** and select the project you'd like to edit. In the **Project settings** tab, you can update general settings such as project name, description, [stickiness](./stickiness), [collaboration mode](./project-collaboration-mode), and more. You can also configure user and API access, [change requests](./change-requests), and [actions](./actions), add [segments](./segments) and [environments](./environments), and update the [default strategy](#project-default-strategy). +To update a project, go to **Projects** and select the project you'd like to edit. In **Settings > Project settings**, you can update general settings such as project name, description, [stickiness](./stickiness), [collaboration mode](./project-collaboration-mode), and more. You can also configure user and API access, [change requests](./change-requests), and [actions](./actions), add [segments](./segments) and [environments](./environments), and update the [default strategy](#project-default-strategy). The available project settings depend on a user's [root and project roles](./rbac). @@ -56,9 +56,10 @@ Before archiving a project, you must archive all feature flags within it. Archiv To archive a project: -1. Go to **Projects > Project settings > Settings**. -2. Go to the **Archive project** section and click **Archive project**. -3. Confirm by clicking **Yes, I'm sure**. +1. Open the project and go to the **Settings** tab. +2. In **Project settings**, go to the **Archive project** section. +3. Click **Archive project**. +4. Confirm by clicking **Yes, I'm sure**. ### Revive a project diff --git a/website/docs/reference/rbac.md b/website/docs/reference/rbac.md index 984a68418caf..b0d998cf76b5 100644 --- a/website/docs/reference/rbac.md +++ b/website/docs/reference/rbac.md @@ -192,7 +192,7 @@ You can assign the following permissions on a per-environment level within the p | **update variants** | Lets the user create, edit and remove variants within the environment. | | **approve a change request** | Lets the user approve [change requests](./change-requests) in the environment. | | **apply a change request** | Lets the user apply change requests in the environment. | -| **skip change requests** | Lets the user ignore change request requirements. This applies **only when using the API** directly; when using the admin UI, users with this permission will still need to go through the normal change request flow. You can find more details in the section on [circumventing change requests](./change-requests#circumventing-change-requests). | +| **skip change requests** | Lets the user skip the change request process for a project and environment where change requests are enabled. | ## Multiple Project Roles diff --git a/website/docs/reference/technical-debt.md b/website/docs/reference/technical-debt.md index 95e27f9fa9cb..ba4254fb8e8b 100644 --- a/website/docs/reference/technical-debt.md +++ b/website/docs/reference/technical-debt.md @@ -3,48 +3,37 @@ title: Technical Debt pagination_next: reference/insights --- -At Unleash we care deeply about code quality. Technical debt creeps up over time and slowly builds to the point where it really starts to hurt. At that point it's too late. Feature flags that have outlived their feature and are not cleaned up represent technical debt that you should remove from your code. +## Overview -## Stale and potentially stale toggles +Feature flag technical debt accumulates when you don’t manage or retire feature flags after their intended use. Over time, the codebase becomes cluttered with outdated flags, making the code more complex and harder to maintain. This can slow productivity as developers spend more time understanding and navigating the code. -When a flag is no longer useful, we say that it has become _stale_. A stale flag is a flag that has served its purpose and that you should remove from the code base. For a flag to become stale, you have to explicitly mark it as such. You can mark a flag as stale in the [technical debt dashboard](#the-technical-debt-dashboard). +[Stale feature flags](#stale-and-potentially-stale-flags) can also introduce risks, such as security vulnerabilities, by unintentionally exposing sensitive features or data. Additionally, the presence of stale or conflicting feature flags can lead to unexpected application behavior, increasing the risk of downtime and affecting overall stability. Managing feature flags effectively minimizes these risks and ensures a healthier development process. -Unleash also has a concept of _potentially_ stale flags. These are flags that have lived longer than what Unleash expects them to based on their [feature flag type](../reference/feature-toggles#feature-flag-types). However, Unleash can't know for sure whether a flag is actually stale or not, so it's up to you to make the decision on whether to mark it as stale or to keep it as an active flag. -A flag being (potentially) stale, does not affect how it performs in your application; it's only there to make it easier for you to manage your flags. +## Stale and potentially stale flags -## The technical debt dashboard +A feature flag can have one of the following states: _active_, _potentially stale_, or _stale_. Unleash marks all flags as potentially stale automatically once they pass their [expected lifetime](/reference/feature-toggles#feature-flag-types). This gives you an indication of when to review and clean up a feature flag in code. -In order to assist with removing unused feature flags, Unleash provides project health dashboards for each project. The health dashboard is listed as one of a project's tabs. +You can also manually mark a feature flag as stale if you know it has served its intended purpose. To do so, click **Toggle stale state** on the flag's details page. -![Three UI elements describing the health rating of the project. The first card has info on the project, including its name. The second is the "report card", containing the project's overall health rating, a flag report, and potential actions. The last card is a list of all the project's flags with data on when it was last seen, when it was created, when it expired, its status and a report.](/img/reporting.png) +![Marking a feature flag as stale](/img/mark-flag-stale.png) -The dashboard includes a health report card, and a list of flags that can be filtered on different parameters. +Alternatively, you can mark one or more flags as stale from the project overview page. In the **Feature flags** list, select the affected flags and click **Mark as stale**. -### Report card {#report-card} +![Mark a flag as stale in a project](/img/stale-flag-project.png) -![The project's health report card. It lists the project's health rating and when it was last updated; a flag report containing the number of active flags in the project; and potential actions, in this case asking the user to review potentially stale flags.](/img/reportcard.png) +Marking a flag as stale allows you to deprecate a feature flag without removing the active configuration for connected applications. You can use this to signal to your team to stop using the feature in your applications. Stale flags will show as stale in the [project status dashboard](#project-status). -The report card includes some statistics of your application. It lists the overall amount of your active flags, the overall amount of stale flags, and lastly, the flags that Unleash believes should be stale. This calculation is performed on the basis of flag types: +Marking a flag as stale generates a `feature-stale-on` [event](/reference/events#feature-stale-on). You can use [an integration](/reference/integrations) to trigger automated workflows, such as posting notifications in a Slack channel, breaking project builds if the code contains stale flags, or automatically opening pull requests to remove stale flags from the code. -- **Release** - Used to enable trunk-based development for teams practicing Continuous Delivery. _Expected lifetime 40 days_ -- **Experiment** - Used to perform multivariate or A/B testing. _Expected lifetime 40 days_ -- **Operational** - Used to control operational aspects of the system's behavior. _Expected lifetime 7 days_ -- **Kill switch** - Used to to gracefully degrade system functionality. _(permanent)_ -- **Permission** - Used to change the features or product experience that certain users receive. _(permanent)_ +To find stale and potentially stale flags in a project, apply the **State** filter in the **Feature flags** list. -If your flag exceeds the expected lifetime of its flag type it will be marked as _potentially stale_. +While a flag's state does not affect its behavior in applications, using states to manage flags helps reduce technical debt and maintain a cleaner codebase. -One thing to note is that the report card and corresponding list are showing stats related to the currently selected project. If you have more than one project, you will be provided with a project selector in order to swap between the projects. +## Project status -### Health rating +Each project has a **Project status** dashboard, where you can view its health status and the total number of unhealthy flags. All active flags are considered healthy, while stale and potentially stale flags are considered unhealthy. To keep your project in a healthy state, [archive stale feature flags](/reference/feature-toggles#archive-a-feature-flag) and remove code from your codebase. -Unleash calculates a project's health rating based on the project's total number of active flags and how many of those active flags are stale or potentially stale. When you archive a flag, it no longer counts towards your project's health rating. +![Project status dashboard](/img/project-status-dashboard.png) -The health rating updates once every hour, so there may be some lag if you have recently added, removed, or changed the status of a flag. - -### Flag list {#toggle-list} - -![A table of the flags in the current project with their health reports. The table has the following columns: name, last seen, created, expired, status, and report.](/img/togglelist.png) - -The flag list gives an overview over all of your flags and their status. In this list you can sort the flags by their name, last seen, created, expired, status and report. This will allow you to quickly get an overview over which flags may be worth deprecating and removing from the code. +Your overall project health rating is the percentage of healthy flags in your project. To view your project health over time, go to [Insights](/reference/insights). \ No newline at end of file diff --git a/website/static/img/change-request-configuration.png b/website/static/img/change-request-configuration.png index 45a02acfc078..8ba41184335c 100644 Binary files a/website/static/img/change-request-configuration.png and b/website/static/img/change-request-configuration.png differ diff --git a/website/static/img/change-request-overview.png b/website/static/img/change-request-overview.png index 739f76739deb..0ce09df962d4 100644 Binary files a/website/static/img/change-request-overview.png and b/website/static/img/change-request-overview.png differ diff --git a/website/static/img/change-request-overview.svg b/website/static/img/change-request-overview.svg new file mode 100644 index 000000000000..b64d8bbc3e6b --- /dev/null +++ b/website/static/img/change-request-overview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/static/img/project-status-dashboard.png b/website/static/img/project-status-dashboard.png new file mode 100644 index 000000000000..1b020446e71c Binary files /dev/null and b/website/static/img/project-status-dashboard.png differ diff --git a/website/static/img/revive-archived-flag.png b/website/static/img/revive-archived-flag.png new file mode 100644 index 000000000000..4bb5496da164 Binary files /dev/null and b/website/static/img/revive-archived-flag.png differ diff --git a/website/static/img/stale-flag-project.png b/website/static/img/stale-flag-project.png new file mode 100644 index 000000000000..805857e87bd4 Binary files /dev/null and b/website/static/img/stale-flag-project.png differ