From 984d88eac91c762084f8c677458391fef238876f Mon Sep 17 00:00:00 2001 From: JeromeJu Date: Tue, 17 Oct 2023 21:20:35 +0000 Subject: [PATCH] Add Per-feature Flag Struct for New Features This commit adds the per-feature flag struct and documentations for new features in TektonCD pipeline. part of: TEP-0138 --- api_compatibility_policy.md | 17 +++++++++++++- docs/developers/feature-versioning.md | 33 +++++++++++++++++++++++++++ pkg/apis/config/feature_flags.go | 25 +++++++++++++++++--- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/api_compatibility_policy.md b/api_compatibility_policy.md index 5d2cc231003..696ef8d44fb 100644 --- a/api_compatibility_policy.md +++ b/api_compatibility_policy.md @@ -90,7 +90,22 @@ For more information on support windows, see the [deprecations table](./docs/dep ## Feature Gates -Stability levels of feature gates are independent from CRD apiVersions. Features enabled by API fields at different levels of stability can be enabled using the flag `enable-api-fields`: +Stability levels of feature gates are independent from CRD apiVersions. + +[TEP0138](https://github.com/tektoncd/community/blob/main/teps/0138-decouple-api-and-feature-versioning.md) has introduced per-feature flags for new API-driven features and the migration plan for `enable-api-fields`. Please refer to the table below for the API-driven features validation changes: + +| Releases | Features | API-driven Features Validation | +| ---------------------- | ----------------------------- | ---------------------------------- | +| Prior to v0.53.0 | All features | `enable-api-fields` **only** | +| After v0.53.0 | [Existing features](#snapshot-of-existent-beta-and-alpha-api-driven-features-as-of-v0530httpsgithubcomtektoncdpipelinereleasestagv0530) till v0.53.0 | `enable-api-fields` | +| After v0.53.0 | New features after v0.53.0 | Per-feature flags | +| ... | | | +| Future release | All [existing features](#snapshot-of-existent-beta-and-alpha-api-driven-features-as-of-v0530httpsgithubcomtektoncdpipelinereleasestagv0530) stabilized or deprecated | Sunset ~~`enable-api-fields`~~ | +| ... | All features | Per-feature flags **only** | + +With per-feature flags, cluster operators are able to enable a single new feature with their dedicated feature flags. For instructions on how to add a per-feature flag, please check the [developer feature versioning guide](./docs/developers/feature-versioning.md#per-feature-flag). + +Note that the `enable-api-fields` feature flag will continue to validate all existing [beta](https://github.com/tektoncd/pipeline/blob/release-v0.52.x/docs/additional-configs.md#beta-features) and [alpha](https://github.com/tektoncd/pipeline/blob/release-v0.52.x/docs/additional-configs.md#alpha-features) features till [v0.53.0](https://github.com/tektoncd/pipeline/tree/release-v0.52.x): * `stable` - This value indicates that only fields of the highest stability level are enabled; i.e. `alpha` and `beta` fields are not enabled. diff --git a/docs/developers/feature-versioning.md b/docs/developers/feature-versioning.md index 78c401b8448..c5241f295b4 100644 --- a/docs/developers/feature-versioning.md +++ b/docs/developers/feature-versioning.md @@ -4,6 +4,39 @@ The stability levels of features (feature versioning) are independent of CRD API ## Adding feature gated API fields for API-driven features title API-driven features are features that are enabled via a specific field in pipeline API. They comply to the [feature gates](../../api_compatibility_policy.md#feature-gates) and the [feature graduation process](../../api_compatibility_policy.md#feature-graduation-process) specified in the [API compatibility policy](../../api_compatibility_policy.md). For example, [remote tasks](https://github.com/tektoncd/pipeline/blob/454bfd340d102f16f4f2838cf4487198537e3cfa/docs/taskruns.md#remote-tasks) is an API-driven feature. + +## Adding feature gated API fields for API-driven features +### Per-feature flag + +All new features added after [v0.53.0](https://github.com/tektoncd/pipeline/releases/tag/v0.53.0) will be enabled by their dedicated feature flags. To introduce a new per-feature flag, we will proceed as follows: +- Add default values to the new per-feature flag for the new API-driven feature following the `PerFeatureFlag` struct in [feature_flags.go](./../../pkg/apis/config/feature_flags.go). +- Write unit tests to verify the new feature flag and update all test cases that require the configMap setting, such as those related to provenance propagation. +- To add integration tests: + - First, add the tests to `pull-tekton-pipeline-alpha-integration-test` by enabling the newly-introduced per-feature flag at [alpha test Prow environment](./../../test/e2e-tests-kind-prow-alpha.env). + - When the flag is promoted to `beta` stability level, change the test to use [beta Prow environment setup](./../../test/e2e-tests-kind-prow-beta.env). + - To add additional CI tests for combinations of feature flags, add tests for all alpha feature flags being turned on, with one alpha feature turned off at a time. +- Add the tested new per-feature flag key value to the [the pipeline configMap](./../../config/config-feature-flags.yaml). +- Update documentations for the new alpha feature at [alpha-stability-level](./../additional-configs.md#alpha-features). + +#### Example of adding a new Per-feature flag +1. Add the default value following the Per-Feature flag struct +```golang +const enableExampleNewFeatureKey = 'example-new-feature' + +var DefaultExampleNewFeatre = PerFeatureFlag { + Name: enableExampleNewFeatureKey, + Stability: AlphaAPIFields, + Enabled: DefaultAlphaFeatureEnabled, +} +``` +2. Add unit tests with the newly-introduced yamls `feature-flags-example-new-feature` and `feature-flags-invalid-example-new-feature` according to the existing testing framework. + +3. For integration tests, add `example-new-feature: true` to [alpha test Prow environment](./../../test/e2e-tests-kind-prow-alpha.env). + +4. Add `example-new-feature: false` to [the pipeline configMap](./../../config/config-feature-flags.yaml) with a release note. + +5. Update documentations for the new alpha feature at [alpha-stability-level](./../additional-configs.md#alpha-features). + ### `enable-api-fields` We've introduced a feature-flag called `enable-api-fields` to the diff --git a/pkg/apis/config/feature_flags.go b/pkg/apis/config/feature_flags.go index 6b4940c0880..adfa562bbe2 100644 --- a/pkg/apis/config/feature_flags.go +++ b/pkg/apis/config/feature_flags.go @@ -27,12 +27,18 @@ import ( ) const ( - // StableAPIFields is the value used for "enable-api-fields" when only stable APIs should be usable. + // StableAPIFields is the value used for API-driven features of stable stability level. StableAPIFields = "stable" - // AlphaAPIFields is the value used for "enable-api-fields" when alpha APIs should be usable as well. + // AlphaAPIFields is the value used for API-driven features of alpha stability level. AlphaAPIFields = "alpha" - // BetaAPIFields is the value used for "enable-api-fields" when beta APIs should be usable as well. + // BetaAPIFields is the value used for API-driven features of beta stability level. BetaAPIFields = "beta" + // Features of "alpha" stability level are disabled by default + DefaultAlphaFeatureEnabled = false + // Features of "beta" stability level are disabled by default + DefaultBetaFeatureEnabled = false + // Features of "stable" stability level are enabled by default + DefaultStableFeatureEnabled = true // FailNoMatchPolicy is the value used for "trusted-resources-verification-no-match-policy" to fail TaskRun or PipelineRun // when no matching policies are found FailNoMatchPolicy = "fail" @@ -358,3 +364,16 @@ func GetVerificationNoMatchPolicy(ctx context.Context) string { func IsSpireEnabled(ctx context.Context) bool { return FromContextOrDefaults(ctx).FeatureFlags.EnforceNonfalsifiability == EnforceNonfalsifiabilityWithSpire } + +type PerFeatureFlag struct { + // Name of the feature flag + Name string + // Stability level of the feature, one of StableAPIFields, BetaAPIFields or AlphaAPIFields + Stability string + // Enabled is whether the feature is turned on + Enabled bool + // Deprecated indicates whether the feature is deprecated + // +optional + //nolint:gocritic + Deprecated bool +}