diff options
45 files changed, 414 insertions, 172 deletions
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml index 76fae2f00cd..d296604bc68 100644 --- a/.gitlab/ci/frontend.gitlab-ci.yml +++ b/.gitlab/ci/frontend.gitlab-ci.yml @@ -106,6 +106,7 @@ retrieve-frontend-fixtures: script: - source scripts/utils.sh - source scripts/gitlab_component_helpers.sh + - install_gitlab_gem - export_fixtures_sha_for_download - | if check_fixtures_download; then @@ -131,6 +132,7 @@ retrieve-frontend-fixtures: script: - source scripts/utils.sh - source scripts/gitlab_component_helpers.sh + - install_gitlab_gem - export_fixtures_sha_for_download - | if check_fixtures_download; then diff --git a/app/assets/javascripts/feature_flags/components/feature_flags.vue b/app/assets/javascripts/feature_flags/components/feature_flags.vue index 93510870915..34e0b94af3b 100644 --- a/app/assets/javascripts/feature_flags/components/feature_flags.vue +++ b/app/assets/javascripts/feature_flags/components/feature_flags.vue @@ -187,7 +187,7 @@ export default { data-testid="feature-flags-tab-title" class="page-title gl-font-size-h-display gl-my-0" > - {{ s__('FeatureFlags|Feature Flags') }} + {{ s__('FeatureFlags|Feature flags') }} </h2> <gl-badge v-if="count" class="gl-ml-4">{{ count }}</gl-badge> </div> diff --git a/app/assets/javascripts/feature_flags/components/feature_flags_table.vue b/app/assets/javascripts/feature_flags/components/feature_flags_table.vue index 286b214b511..dee1d239c9f 100644 --- a/app/assets/javascripts/feature_flags/components/feature_flags_table.vue +++ b/app/assets/javascripts/feature_flags/components/feature_flags_table.vue @@ -108,7 +108,7 @@ export default { {{ s__('FeatureFlags|Status') }} </div> <div class="table-section section-20" role="columnheader"> - {{ s__('FeatureFlags|Feature Flag') }} + {{ s__('FeatureFlags|Feature flag') }} </div> <div class="table-section section-40" role="columnheader"> {{ s__('FeatureFlags|Environment Specs') }} @@ -148,7 +148,7 @@ export default { <div class="table-section section-20" role="gridcell"> <div class="table-mobile-header" role="rowheader"> - {{ s__('FeatureFlags|Feature Flag') }} + {{ s__('FeatureFlags|Feature flag') }} </div> <div class="table-mobile-content d-flex flex-column js-feature-flag-title"> <div class="gl-display-flex gl-align-items-center"> diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 227151ff538..9aab1d96083 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -706,6 +706,7 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord attr_encrypted :telesign_customer_xid, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) attr_encrypted :telesign_api_key, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) attr_encrypted :product_analytics_clickhouse_connection_string, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) + attr_encrypted :openai_api_key, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) validates :disable_feed_token, inclusion: { in: [true, false], message: N_('must be a boolean value') } diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb index d01fa29d8d4..b1ffd006795 100644 --- a/app/services/users/refresh_authorized_projects_service.rb +++ b/app/services/users/refresh_authorized_projects_service.rb @@ -92,5 +92,3 @@ module Users end end end - -Users::RefreshAuthorizedProjectsService.prepend_mod diff --git a/app/views/projects/feature_flags/edit.html.haml b/app/views/projects/feature_flags/edit.html.haml index 121dcd31a13..28a8f8729dd 100644 --- a/app/views/projects/feature_flags/edit.html.haml +++ b/app/views/projects/feature_flags/edit.html.haml @@ -1,7 +1,7 @@ - @gfm_form = true -- add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- add_to_breadcrumbs s_('FeatureFlags|Feature flags'), project_feature_flags_path(@project) - breadcrumb_title @feature_flag.name -- page_title s_('FeatureFlags|Edit Feature Flag'), @feature_flag.name +- page_title s_('FeatureFlags|Edit Feature flag'), @feature_flag.name #js-edit-feature-flag{ data: edit_feature_flag_data } diff --git a/app/views/projects/feature_flags/index.html.haml b/app/views/projects/feature_flags/index.html.haml index a6eaeacc61f..e473a6f3cfd 100644 --- a/app/views/projects/feature_flags/index.html.haml +++ b/app/views/projects/feature_flags/index.html.haml @@ -1,4 +1,4 @@ -- page_title s_('FeatureFlags|Feature Flags') +- page_title s_('FeatureFlags|Feature flags') #feature-flags-vue{ data: { endpoint: project_feature_flags_path(@project, format: :json), "project-id" => @project.id, diff --git a/app/views/projects/feature_flags/new.html.haml b/app/views/projects/feature_flags/new.html.haml index c91487ad198..3a32a249d1e 100644 --- a/app/views/projects/feature_flags/new.html.haml +++ b/app/views/projects/feature_flags/new.html.haml @@ -1,7 +1,7 @@ - @breadcrumb_link = new_project_feature_flag_path(@project) -- add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- add_to_breadcrumbs s_('FeatureFlags|Feature flags'), project_feature_flags_path(@project) - breadcrumb_title s_('FeatureFlags|New') -- page_title s_('FeatureFlags|New Feature Flag') +- page_title s_('FeatureFlags|New feature flag') #js-new-feature-flag{ data: { endpoint: project_feature_flags_path(@project, format: :json), feature_flags_path: project_feature_flags_path(@project), diff --git a/app/views/projects/feature_flags_user_lists/edit.html.haml b/app/views/projects/feature_flags_user_lists/edit.html.haml index 1ff488ff0f0..417b6354ec0 100644 --- a/app/views/projects/feature_flags_user_lists/edit.html.haml +++ b/app/views/projects/feature_flags_user_lists/edit.html.haml @@ -1,4 +1,4 @@ -- add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- add_to_breadcrumbs s_('FeatureFlags|Feature flags'), project_feature_flags_path(@project) - add_to_breadcrumbs s_('FeatureFlags|User Lists'), project_feature_flags_user_lists_path(@project) - breadcrumb_title s_('FeatureFlags|Edit User List') - page_title s_('FeatureFlags|Edit User List') diff --git a/app/views/projects/feature_flags_user_lists/index.html.haml b/app/views/projects/feature_flags_user_lists/index.html.haml index f0e3c36992a..c0e98b27d29 100644 --- a/app/views/projects/feature_flags_user_lists/index.html.haml +++ b/app/views/projects/feature_flags_user_lists/index.html.haml @@ -1,6 +1,6 @@ -- add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- add_to_breadcrumbs s_('FeatureFlags|Feature flags'), project_feature_flags_path(@project) - breadcrumb_title s_('FeatureFlags|User Lists') -- page_title s_('FeatureFlags|Feature Flag User Lists') +- page_title s_('FeatureFlags|Feature flag User Lists') #js-user-lists{ data: { project_id: @project.id, feature_flags_help_page_path: help_page_path("operations/feature_flags"), diff --git a/app/views/projects/feature_flags_user_lists/new.html.haml b/app/views/projects/feature_flags_user_lists/new.html.haml index f2e1ea38d9c..cea55c0ca2a 100644 --- a/app/views/projects/feature_flags_user_lists/new.html.haml +++ b/app/views/projects/feature_flags_user_lists/new.html.haml @@ -1,5 +1,5 @@ - @breadcrumb_link = new_project_feature_flags_user_list_path(@project) -- add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- add_to_breadcrumbs s_('FeatureFlags|Feature flags'), project_feature_flags_path(@project) - add_to_breadcrumbs s_('FeatureFlags|User Lists'), project_feature_flags_user_lists_path(@project) - breadcrumb_title s_('FeatureFlags|New User List') - page_title s_('FeatureFlags|New User List') diff --git a/app/views/projects/feature_flags_user_lists/show.html.haml b/app/views/projects/feature_flags_user_lists/show.html.haml index 2c88f3da66b..5c4e93e7707 100644 --- a/app/views/projects/feature_flags_user_lists/show.html.haml +++ b/app/views/projects/feature_flags_user_lists/show.html.haml @@ -1,7 +1,7 @@ -- add_to_breadcrumbs s_('FeatureFlags|Feature Flags'), project_feature_flags_path(@project) +- add_to_breadcrumbs s_('FeatureFlags|Feature flags'), project_feature_flags_path(@project) - add_to_breadcrumbs s_('FeatureFlags|User Lists'), project_feature_flags_user_lists_path(@project) - breadcrumb_title s_('FeatureFlags|List details') -- page_title s_('FeatureFlags|Feature Flag User List Details') +- page_title s_('FeatureFlags|Feature flag user list details') #js-edit-user-list{ data: { project_id: @project.id, user_list_iid: @user_list.iid, diff --git a/config/feature_flags/development/openai_experimentation.yml b/config/feature_flags/development/openai_experimentation.yml new file mode 100644 index 00000000000..b3585038c07 --- /dev/null +++ b/config/feature_flags/development/openai_experimentation.yml @@ -0,0 +1,8 @@ +--- +name: openai_experimentation +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116364 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/403855 +milestone: '15.11' +type: development +group: group::ai_enablement +default_enabled: false diff --git a/db/migrate/20230331142006_add_open_ai_api_key_application_setting.rb b/db/migrate/20230331142006_add_open_ai_api_key_application_setting.rb new file mode 100644 index 00000000000..735cb414c99 --- /dev/null +++ b/db/migrate/20230331142006_add_open_ai_api_key_application_setting.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class AddOpenAiApiKeyApplicationSetting < Gitlab::Database::Migration[2.1] + def change + add_column :application_settings, :encrypted_openai_api_key, :binary + add_column :application_settings, :encrypted_openai_api_key_iv, :binary + end +end diff --git a/db/schema_migrations/20230331142006 b/db/schema_migrations/20230331142006 new file mode 100644 index 00000000000..be84e6af217 --- /dev/null +++ b/db/schema_migrations/20230331142006 @@ -0,0 +1 @@ +73b3a7fa20bb22756e9e16f489c0743920c3342c6fc5a70cffafad84016873ab
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 097df5b5e32..4af994590ad 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -11754,6 +11754,8 @@ CREATE TABLE application_settings ( gitlab_dedicated_instance boolean DEFAULT false NOT NULL, update_runner_versions_enabled boolean DEFAULT true NOT NULL, database_apdex_settings jsonb, + encrypted_openai_api_key bytea, + encrypted_openai_api_key_iv bytea, CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)), CONSTRAINT app_settings_container_registry_pre_import_tags_rate_positive CHECK ((container_registry_pre_import_tags_rate >= (0)::numeric)), CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)), diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md index f89521bdbbd..bc3edee908f 100644 --- a/doc/administration/monitoring/prometheus/gitlab_metrics.md +++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md @@ -173,7 +173,7 @@ The following metrics are available: The following metrics can be controlled by feature flags: -| Metric | Feature Flag | +| Metric | Feature flag | |:---------------------------------------------------------------|:-------------------------------------------------------------------| | `gitlab_view_rendering_duration_seconds` | `prometheus_metrics_view_instrumentation` | diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md index 6c04a73a760..7304c0a86be 100644 --- a/doc/api/api_resources.md +++ b/doc/api/api_resources.md @@ -44,8 +44,8 @@ The following API resources are available in the project context: | [Environments](environments.md) | `/projects/:id/environments` | | [Error Tracking](error_tracking.md) | `/projects/:id/error_tracking/settings` | | [Events](events.md) | `/projects/:id/events` (also available for users and standalone) | -| [Feature Flag User Lists](feature_flag_user_lists.md) | `/projects/:id/feature_flags_user_lists` | -| [Feature Flags](feature_flags.md) | `/projects/:id/feature_flags` | +| [Feature flag User Lists](feature_flag_user_lists.md) | `/projects/:id/feature_flags_user_lists` | +| [Feature flags](feature_flags.md) | `/projects/:id/feature_flags` | | [Freeze Periods](freeze_periods.md) | `/projects/:id/freeze_periods` | | [Go Proxy](packages/go_proxy.md) | `/projects/:id/packages/go` | | [Helm repository](packages/helm.md) | `/projects/:id/packages/helm_repository` | diff --git a/doc/api/feature_flag_user_lists.md b/doc/api/feature_flag_user_lists.md index c7a8fc0ec32..ee8ec3f9595 100644 --- a/doc/api/feature_flag_user_lists.md +++ b/doc/api/feature_flag_user_lists.md @@ -9,9 +9,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205409) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.10. > - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) to GitLab Free in 13.5. -API for accessing GitLab Feature Flag User Lists. +API for accessing GitLab feature flag user lists. -Users with Developer or higher [permissions](../user/permissions.md) can access the Feature Flag User Lists API. +Users with Developer or higher [permissions](../user/permissions.md) can access the feature flag user lists API. NOTE: `GET` requests return twenty results at a time because the API results diff --git a/doc/ci/caching/index.md b/doc/ci/caching/index.md index d7c5b089116..4be6c261c65 100644 --- a/doc/ci/caching/index.md +++ b/doc/ci/caching/index.md @@ -65,7 +65,7 @@ For runners to work with caches efficiently, you must do one of the following: ## Use multiple caches > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32814) in GitLab 13.10. -> - [Feature Flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/321877), in GitLab 13.12. +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/321877), in GitLab 13.12. You can have a maximum of four caches: diff --git a/doc/ci/index.md b/doc/ci/index.md index b3a441dc87d..bcc00fcd435 100644 --- a/doc/ci/index.md +++ b/doc/ci/index.md @@ -95,7 +95,7 @@ GitLab CI/CD features, grouped by DevOps stage, include: | [Building Docker images](docker/using_docker_build.md) | Maintain Docker-based projects using GitLab CI/CD. | | [Canary Deployments](../user/project/canary_deployments.md) | Ship features to only a portion of your pods and let a percentage of your user base to visit the temporarily deployed feature. | | [Deploy boards](../user/project/deploy_boards.md) | Check the current health and status of each CI/CD environment running on Kubernetes. | -| [Feature Flags](../operations/feature_flags.md) | Deploy your features behind Feature Flags. | +| [Feature flags](../operations/feature_flags.md) | Deploy your features behind Feature flags. | | [GitLab Pages](../user/project/pages/index.md) | Deploy static websites. | | [GitLab Releases](../user/project/releases/index.md) | Add release notes to Git tags. | | [Cloud deployment](cloud_deployment/index.md) | Deploy your application to a main cloud provider. | diff --git a/doc/ci/testing/accessibility_testing.md b/doc/ci/testing/accessibility_testing.md index ee833ea4a74..5999b8d85ba 100644 --- a/doc/ci/testing/accessibility_testing.md +++ b/doc/ci/testing/accessibility_testing.md @@ -30,7 +30,7 @@ As of [GitLab 14.5](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73309) ## Accessibility merge request widget > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39425) in GitLab 13.0 behind the disabled [feature flag](../../administration/feature_flags.md) `:accessibility_report_view`. -> - [Feature Flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/217372) in GitLab 13.1. +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/217372) in GitLab 13.1. GitLab displays an **Accessibility Report** in the merge request widget area: diff --git a/doc/development/feature_flags/controls.md b/doc/development/feature_flags/controls.md index f8a592f98f5..0e88c68cc99 100644 --- a/doc/development/feature_flags/controls.md +++ b/doc/development/feature_flags/controls.md @@ -40,7 +40,7 @@ easier to measure the impact of both separately. The GitLab feature library (using [Flipper](https://github.com/jnunemaker/flipper), and covered in the -[Feature Flags process](https://about.gitlab.com/handbook/product-development-flow/feature-flag-lifecycle/) guide) supports rolling out changes to a percentage of +[Feature flags process](https://about.gitlab.com/handbook/product-development-flow/feature-flag-lifecycle/) guide) supports rolling out changes to a percentage of time to users. This in turn can be controlled using [GitLab ChatOps](../../ci/chatops/index.md). For an up to date list of feature flag commands please see @@ -115,13 +115,13 @@ incidents or in-progress change issues, for example: 2021-06-29 Canary deployment failing QA tests ``` -Before enabling a feature flag, verify that you are not violating any [Production Change Lock periods](https://about.gitlab.com/handbook/engineering/infrastructure/change-management/#production-change-lock-pcl) and are in compliance with the [Feature Flags and the Change Management Process](https://about.gitlab.com/handbook/engineering/infrastructure/change-management/#feature-flags-and-the-change-management-process). +Before enabling a feature flag, verify that you are not violating any [Production Change Lock periods](https://about.gitlab.com/handbook/engineering/infrastructure/change-management/#production-change-lock-pcl) and are in compliance with the [Feature flags and the Change Management Process](https://about.gitlab.com/handbook/engineering/infrastructure/change-management/#feature-flags-and-the-change-management-process). The following `/chatops` commands should be performed in the Slack `#production` channel. When you begin to enable the feature, please link to the relevant -Feature Flag Rollout Issue within a Slack thread of the first `/chatops` +feature flag rollout issue within a Slack thread of the first `/chatops` command you make so people can understand the change if they need to. To enable a feature for 25% of the time, run the following in Slack: @@ -358,7 +358,7 @@ After turning on the feature flag, you need to [monitor the relevant graphs](htt In this illustration, you can see that the Apdex score started to decline after the feature flag was enabled at `09:46`. The feature flag was then deactivated at `10:31`, and the service returned to the original value: -![Feature Flag Metrics](../img/feature-flag-metrics.png) +![Feature flag metrics](../img/feature-flag-metrics.png) ### Feature flag change logging diff --git a/doc/development/feature_flags/index.md b/doc/development/feature_flags/index.md index 9b6876ac0bc..40a5d2a2abc 100644 --- a/doc/development/feature_flags/index.md +++ b/doc/development/feature_flags/index.md @@ -83,7 +83,7 @@ used for deploying unfinished code to production. Most feature flags used at GitLab are the `development` type. A `development` feature flag must have a rollout issue -created from the [Feature Flag Roll Out template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/Feature%20Flag%20Roll%20Out.md). +created from the [Feature flag Roll Out template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/issue_templates/Feature%20Flag%20Roll%20Out.md). The format for `development` feature flags is `Feature.<state>(:<dev_flag_name>)`. To enable and disable them, run on the GitLab Rails console: @@ -252,7 +252,7 @@ deleting feature flags. ## Develop with a feature flag -There are two main ways of using Feature Flags in the GitLab codebase: +There are two main ways of using feature flags in the GitLab codebase: - [Backend code (Rails)](#backend) - [Frontend code (VueJS)](#frontend) diff --git a/doc/development/gitaly.md b/doc/development/gitaly.md index 4aec08add4e..408f3d5fa3c 100644 --- a/doc/development/gitaly.md +++ b/doc/development/gitaly.md @@ -239,7 +239,7 @@ Re-run steps 2-5 each time you want to try out new changes. [Return to Development documentation](index.md) -## Wrapping RPCs in Feature Flags +## Wrapping RPCs in feature flags Here are the steps to gate a new feature in Gitaly behind a feature flag. diff --git a/doc/development/pages/index.md b/doc/development/pages/index.md index d5b18ee80fb..4769dbf427d 100644 --- a/doc/development/pages/index.md +++ b/doc/development/pages/index.md @@ -255,7 +255,7 @@ incidents and downtime. To add a new feature flag to GitLab Pages: 1. Create the feature flag in [`internal/feature/feature.go`](https://gitlab.com/gitlab-org/gitlab-pages/-/blob/master/internal/feature/feature.go), which must be **off** by default. -1. Create an issue to track the feature flag using the `Feature Flag` template. +1. Create an issue to track the feature flag using the `Feature flag` template. 1. Add the `~"feature flag"` label to any merge requests that handle feature flags. For GitLab Pages, the feature flags are controlled by environment variables at a global level. diff --git a/doc/development/redis/new_redis_instance.md b/doc/development/redis/new_redis_instance.md index c1f69f4d103..00cc102b427 100644 --- a/doc/development/redis/new_redis_instance.md +++ b/doc/development/redis/new_redis_instance.md @@ -119,7 +119,7 @@ Migration Requirements: - No downtime. - No loss of stored data until the TTL for storing data expires. -- Partial rollout using Feature Flags or ENV vars or combinations of both. +- Partial rollout using feature flags or ENV vars or combinations of both. - Monitoring of the switch. - Prometheus metrics in place. - Easy rollback without downtime in case the new instance or logic does not behave as expected. diff --git a/doc/development/testing_guide/testing_levels.md b/doc/development/testing_guide/testing_levels.md index 2a5c303217f..c349e53b5c8 100644 --- a/doc/development/testing_guide/testing_levels.md +++ b/doc/development/testing_guide/testing_levels.md @@ -65,7 +65,7 @@ that is not directly perceivable by a user. graph RL plain[Plain JavaScript]; Vue[Vue Components]; - feature-flags[Feature Flags]; + feature-flags[Feature flags]; license-checks[License Checks]; plain---Vuex; @@ -149,7 +149,7 @@ Component tests cover the state of a single component that is perceivable by a u graph RL plain[Plain JavaScript]; Vue[Vue Components]; - feature-flags[Feature Flags]; + feature-flags[Feature flags]; license-checks[License Checks]; plain---Vuex; @@ -243,7 +243,7 @@ Their abstraction level is comparable to how a user would interact with the UI. graph RL plain[Plain JavaScript]; Vue[Vue Components]; - feature-flags[Feature Flags]; + feature-flags[Feature flags]; license-checks[License Checks]; plain---Vuex; @@ -371,7 +371,7 @@ See also: graph RL plain[Plain JavaScript]; Vue[Vue Components]; - feature-flags[Feature Flags]; + feature-flags[Feature flags]; license-checks[License Checks]; plain---Vuex; diff --git a/doc/operations/feature_flags.md b/doc/operations/feature_flags.md index 213685676a7..a3874b54ccd 100644 --- a/doc/operations/feature_flags.md +++ b/doc/operations/feature_flags.md @@ -38,7 +38,7 @@ with GitLab, so it's up to developers to use a compatible client library and To create and enable a feature flag: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Feature Flags**. +1. On the left sidebar, select **Deployments > Feature flags**. 1. Select **New feature flag**. 1. Enter a name that starts with a letter and contains only lowercase letters, digits, underscores (`_`), or dashes (`-`), and does not end with a dash (`-`) or underscore (`_`). @@ -85,7 +85,7 @@ and the supported strategies are: - [User List](#user-list) Strategies can be added to feature flags when [creating a feature flag](#create-a-feature-flag), -or by editing an existing feature flag after creation by navigating to **Deployments > Feature Flags** +or by editing an existing feature flag after creation by navigating to **Deployments > Feature flags** and selecting **Edit** (**{pencil}**). ### All users @@ -181,7 +181,7 @@ For example: To create a user list: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Feature Flags**. +1. On the left sidebar, select **Deployments > Feature flags**. 1. Select **View user lists** 1. Select **New user list**. 1. Enter a name for the list. @@ -197,7 +197,7 @@ When viewing a list, you can rename it by selecting **Edit** (**{pencil}**). To add users to a user list: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Feature Flags**. +1. On the left sidebar, select **Deployments > Feature flags**. 1. Select **Edit** (**{pencil}**) next to the list you want to add users to. 1. Select **Add Users**. 1. Enter the user IDs as a comma-separated list of values. For example, @@ -211,7 +211,7 @@ To add users to a user list: To remove users from a user list: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Feature Flags**. +1. On the left sidebar, select **Deployments > Feature flags**. 1. Select **Edit** (**{pencil}**) next to the list you want to change. 1. Select **Remove** (**{remove}**) next to the ID you want to remove. @@ -225,7 +225,7 @@ code so that you can clean it up when it's time to remove the feature flag. To search for code references of a feature flag: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Feature Flags**. +1. On the left sidebar, select **Deployments > Feature flags**. 1. Edit the feature flag you want to remove. 1. Select **More actions** (**{ellipsis_v}**). 1. Select **Search code references**. @@ -236,7 +236,7 @@ In [GitLab 13.0 and earlier](https://gitlab.com/gitlab-org/gitlab/-/issues/8621) to disable a feature flag for a specific environment: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Feature Flags**. +1. On the left sidebar, select **Deployments > Feature flags**. 1. For the feature flag you want to disable, select **Edit** (**{pencil}**). 1. To disable the flag: @@ -251,7 +251,7 @@ to disable a feature flag for a specific environment: To disable a feature flag for all environments: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Feature Flags**. +1. On the left sidebar, select **Deployments > Feature flags**. 1. For the feature flag you want to disable, slide the Status toggle to **Disabled**. The feature flag is displayed on the **Disabled** tab. @@ -266,7 +266,7 @@ Then prepare your application with a client library. To get the access credentials that your application needs to communicate with GitLab: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Deployments > Feature Flags**. +1. On the left sidebar, select **Deployments > Feature flags**. 1. Select **Configure** to view the following: - **API URL**: URL where the client (application) connects to get a list of feature flags. - **Instance ID**: Unique token that authorizes the retrieval of the feature flags. diff --git a/doc/operations/index.md b/doc/operations/index.md index d4a5f895947..56b27af316b 100644 --- a/doc/operations/index.md +++ b/doc/operations/index.md @@ -76,4 +76,4 @@ an environment. - Deploy to different [environments](../ci/environments/index.md). - Connect your project to a [Kubernetes cluster](../user/infrastructure/clusters/index.md). -- Create, toggle, and remove [Feature Flags](feature_flags.md). +- Create, toggle, and remove [feature flags](feature_flags.md). diff --git a/doc/user/permissions.md b/doc/user/permissions.md index ab08f5b4767..002797b386a 100644 --- a/doc/user/permissions.md +++ b/doc/user/permissions.md @@ -137,7 +137,7 @@ The following table lists project permissions available for each role: | [Package registry](packages/index.md):<br>Delete a package | | | | ✓ | ✓ | | [Package registry](packages/index.md):<br>Delete a file associated with a package | | | | ✓ | ✓ | | [Project operations](../operations/index.md):<br>View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ | -| [Project operations](../operations/index.md):<br>Manage [Feature Flags](../operations/feature_flags.md) | | | ✓ | ✓ | ✓ | +| [Project operations](../operations/index.md):<br>Manage [Feature flags](../operations/feature_flags.md) | | | ✓ | ✓ | ✓ | | [Project operations](../operations/index.md):<br>Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ | | [Projects](project/index.md):<br>Download project | ✓ (1) | ✓ | ✓ | ✓ | ✓ | | [Projects](project/index.md):<br>Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ | diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md index 42387535100..3ead11d3a9e 100644 --- a/doc/user/project/settings/index.md +++ b/doc/user/project/settings/index.md @@ -94,7 +94,7 @@ Use the toggles to enable or disable features in the project. | **Metrics Dashboard** | ✓ | Control access to [metrics dashboard](../integrations/prometheus.md). | | **Releases** | ✓ | Control access to [Releases](../releases/index.md). | | **Environments** | ✓ | Control access to [Environments and Deployments](../../../ci/environments/index.md). | -| **Feature flags** | ✓ | Control access to [Feature Flags](../../../operations/feature_flags.md). | +| **Feature flags** | ✓ | Control access to [Feature flags](../../../operations/feature_flags.md). | | **Monitor** | ✓ | Control access to [Monitor](../../../operations/index.md) features. | | **Infrastructure** | ✓ | Control access to [Infrastructure](../../infrastructure/index.md) features. | diff --git a/lib/sidebars/projects/menus/deployments_menu.rb b/lib/sidebars/projects/menus/deployments_menu.rb index e415c4ce2bd..19612fcee85 100644 --- a/lib/sidebars/projects/menus/deployments_menu.rb +++ b/lib/sidebars/projects/menus/deployments_menu.rb @@ -47,7 +47,7 @@ module Sidebars end ::Sidebars::MenuItem.new( - title: _('Feature Flags'), + title: s_('FeatureFlags|Feature flags'), link: project_feature_flags_path(context.project), super_sidebar_parent: ::Sidebars::Projects::SuperSidebarMenus::BuildMenu, active_routes: { controller: :feature_flags }, diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 2000aabe8f9..5d5209f5e33 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -17853,7 +17853,7 @@ msgstr "" msgid "FeatureFlags|Description" msgstr "" -msgid "FeatureFlags|Edit Feature Flag" +msgid "FeatureFlags|Edit Feature flag" msgstr "" msgid "FeatureFlags|Edit User List" @@ -17865,25 +17865,25 @@ msgstr "" msgid "FeatureFlags|Environment Specs" msgstr "" -msgid "FeatureFlags|Feature Flag" +msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}." msgstr "" -msgid "FeatureFlags|Feature Flag User List Details" +msgid "FeatureFlags|Feature Flag has no strategies" msgstr "" -msgid "FeatureFlags|Feature Flag User Lists" +msgid "FeatureFlags|Feature flag" msgstr "" -msgid "FeatureFlags|Feature Flag behavior is built up by creating a set of rules to define the status of target environments. A default wildcard rule %{codeStart}*%{codeEnd} for %{boldStart}All Environments%{boldEnd} is set, and you are able to add as many rules as you need by choosing environment specs below. You can toggle the behavior for each of your rules to set them %{boldStart}Active%{boldEnd} or %{boldStart}Inactive%{boldEnd}." +msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?" msgstr "" -msgid "FeatureFlags|Feature Flag has no strategies" +msgid "FeatureFlags|Feature flag User Lists" msgstr "" -msgid "FeatureFlags|Feature Flags" +msgid "FeatureFlags|Feature flag user list details" msgstr "" -msgid "FeatureFlags|Feature flag %{name} will be removed. Are you sure?" +msgid "FeatureFlags|Feature flags" msgstr "" msgid "FeatureFlags|Feature flags allow you to configure your code into different flavors by dynamically toggling certain functionality." @@ -17925,9 +17925,6 @@ msgstr "" msgid "FeatureFlags|New" msgstr "" -msgid "FeatureFlags|New Feature Flag" -msgstr "" - msgid "FeatureFlags|New User List" msgstr "" diff --git a/qa/qa/page/project/sub_menus/super_sidebar/operations.rb b/qa/qa/page/project/sub_menus/super_sidebar/operations.rb index f47c113083a..91b9cba1b3e 100644 --- a/qa/qa/page/project/sub_menus/super_sidebar/operations.rb +++ b/qa/qa/page/project/sub_menus/super_sidebar/operations.rb @@ -21,7 +21,7 @@ module QA end def go_to_feature_flags - open_operations_submenu('Feature Flags') + open_operations_submenu('Feature flags') end def go_to_releases diff --git a/scripts/gitlab_component_helpers.sh b/scripts/gitlab_component_helpers.sh index cf9b042b529..301d4fb5d37 100644 --- a/scripts/gitlab_component_helpers.sh +++ b/scripts/gitlab_component_helpers.sh @@ -163,7 +163,7 @@ function check_fixtures_download() { return 1 fi - # Note: Currently, reusing frontend fixtures is only supported in EE. + # Note: Currently, reusing frontend fixtures is only supported in EE. # Other projects will be supported through this issue in the future: https://gitlab.com/gitlab-org/gitlab/-/issues/393615. if [[ "${CI_PROJECT_NAME}" != "gitlab" ]] || [[ "${CI_JOB_NAME}" =~ "foss" ]]; then return 1 @@ -172,7 +172,7 @@ function check_fixtures_download() { if [[ -z "${CI_MERGE_REQUEST_IID:-}" ]]; then return 1 else - if only_js_files_changed && ! fixtures_archive_doesnt_exist; then + if tooling/bin/find_only_js_changes && ! fixtures_archive_doesnt_exist; then return 0 else return 1 @@ -221,30 +221,6 @@ function fixtures_directory_exists() { fi } -function only_js_files_changed { - local target_branch_sha="${CI_MERGE_REQUEST_TARGET_BRANCH_SHA:-}" - local source_branch_sha="${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA:-}" - - if [[ -z "${target_branch_sha}" || -z "${source_branch_sha}" ]]; then - echoinfo "The commit hash(es) provided are missing or are empty." - echoinfo "Please provide valid commit hash(es)." - return 1 - fi - - local changed_files - changed_files=$(git diff --name-only "${target_branch_sha}..${source_branch_sha}") - - for file in $changed_files; do - if [[ ! $file = *.js ]]; then - echoinfo "Changes were made to files other than JS files" - return 1 - fi - done - - echoinfo "Only JS files were changed" - return 0 -} - function upload_fixtures_package() { upload_package "${FIXTURES_PACKAGE}" "${FIXTURES_PACKAGE_URL}" } diff --git a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js index 0812be9745e..d8a848f0a2e 100644 --- a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js +++ b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js @@ -760,7 +760,7 @@ describe('Settings Panel', () => { expect(findEnvironmentsSettings().exists()).toBe(true); }); }); - describe('Feature Flags', () => { + describe('Feature flags', () => { it('should show the feature flags toggle', () => { wrapper = mountComponent({}); diff --git a/spec/lib/sidebars/projects/menus/deployments_menu_spec.rb b/spec/lib/sidebars/projects/menus/deployments_menu_spec.rb index 5065c261cf8..a63acdb5dc2 100644 --- a/spec/lib/sidebars/projects/menus/deployments_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/deployments_menu_spec.rb @@ -51,7 +51,7 @@ RSpec.describe Sidebars::Projects::Menus::DeploymentsMenu, feature_category: :na end end - describe 'Feature Flags' do + describe 'Feature flags' do let(:item_id) { :feature_flags } it_behaves_like 'access rights checks' diff --git a/spec/support/helpers/feature_flag_helpers.rb b/spec/support/helpers/feature_flag_helpers.rb index 4e57002a7c6..5a1c5a6bdab 100644 --- a/spec/support/helpers/feature_flag_helpers.rb +++ b/spec/support/helpers/feature_flag_helpers.rb @@ -95,6 +95,6 @@ module FeatureFlagHelpers end def expect_user_to_see_feature_flags_index_page - expect(page).to have_text('Feature Flags') + expect(page).to have_text('Feature flags') end end diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb index 866a97b0e3c..e28da0bc365 100644 --- a/spec/support/shared_contexts/navbar_structure_context.rb +++ b/spec/support/shared_contexts/navbar_structure_context.rb @@ -68,7 +68,7 @@ RSpec.shared_context 'project navbar structure' do nav_item: _('Deployments'), nav_sub_items: [ _('Environments'), - _('Feature Flags'), + s_('FeatureFlags|Feature flags'), _('Releases') ] }, diff --git a/spec/tooling/lib/tooling/find_changes_spec.rb b/spec/tooling/lib/tooling/find_changes_spec.rb new file mode 100644 index 00000000000..3616732e328 --- /dev/null +++ b/spec/tooling/lib/tooling/find_changes_spec.rb @@ -0,0 +1,216 @@ +# frozen_string_literal: true + +require_relative '../../../../tooling/lib/tooling/find_changes' +require_relative '../../../support/helpers/stub_env' +require 'json' + +RSpec.describe Tooling::FindChanges, feature_category: :tooling do + include StubENV + + let(:instance) do + described_class.new( + output_file: output_file, + matched_tests_file: matched_tests_file, + frontend_fixtures_mapping_path: frontend_fixtures_mapping_path + ) + end + + let(:gitlab_client) { double('GitLab') } # rubocop:disable RSpec/VerifiedDoubles + let(:output_file) { 'output.txt' } + let(:output_file_content) { 'first_file second_file' } + let(:matched_tests_file) { 'matched_tests.txt' } + let(:frontend_fixtures_mapping_path) { 'frontend_fixtures_mapping.json' } + let(:file_changes) { ['file1.rb', 'file2.rb'] } + + before do + stub_env( + 'CI_API_V4_URL' => 'gitlab_api_url', + 'CI_MERGE_REQUEST_IID' => '1234', + 'CI_MERGE_REQUEST_PROJECT_PATH' => 'dummy-project', + 'PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE' => 'dummy-token', + 'RSPEC_TESTS_MAPPING_PATH' => '/tmp/does-not-exist.out' + ) + + allow(instance).to receive(:gitlab).and_return(gitlab_client) + allow(File).to receive(:exist?).and_call_original + allow(File).to receive(:read).and_call_original + allow(File).to receive(:write) + end + + describe '#execute' do + subject { instance.execute } + + context 'when there is no output file' do + let(:output_file) { nil } + + it 'raises an ArgumentError' do + expect { subject }.to raise_error(ArgumentError, "An path to an output file must be given as first argument.") + end + end + + context 'when an output file is provided' do + before do + allow(File).to receive(:exist?).with(output_file).and_return(true) + allow(File).to receive(:read).with(output_file).and_return(output_file_content) + end + + it 'does not call GitLab API to retrieve the MR diff' do + expect(gitlab_client).not_to receive(:merge_request_changes) + + subject + end + + context 'when there are no file changes' do + let(:output_file_content) { '' } + + it 'writes an empty string to output file' do + expect(File).to receive(:write).with(output_file, '') + + subject + end + end + + context 'when there are file changes' do + let(:output_file_content) { 'first_file_changed second_file_changed' } + + it 'writes file changes to output file' do + expect(File).to receive(:write).with(output_file, output_file_content) + + subject + end + end + + context 'when there is no matched tests file' do + let(:matched_tests_file) { '' } + + it 'does not add frontend fixtures mapping to the output file' do + expect(File).to receive(:write).with(output_file, output_file_content) + + subject + end + end + + context 'when there is no frontend fixture files' do + let(:frontend_fixtures_mapping_path) { '' } + + it 'does not add frontend fixtures mapping to the output file' do + expect(File).to receive(:write).with(output_file, output_file_content) + + subject + end + end + + context 'when the matched tests file and frontend fixture files are provided' do + before do + allow(File).to receive(:exist?).with(matched_tests_file).and_return(true) + allow(File).to receive(:exist?).with(frontend_fixtures_mapping_path).and_return(true) + + allow(File).to receive(:read).with(matched_tests_file).and_return(matched_tests) + allow(File).to receive(:read).with(frontend_fixtures_mapping_path).and_return(frontend_fixtures_mapping_json) + end + + context 'when there are no mappings for the matched tests' do + let(:matched_tests) { 'match_spec1 match_spec_2' } + let(:frontend_fixtures_mapping_json) do + { other_spec: ['other_mapping'] }.to_json + end + + it 'does not add frontend fixtures mapping to the output file' do + expect(File).to receive(:write).with(output_file, output_file_content) + + subject + end + end + + context 'when there are available mappings for the matched tests' do + let(:matched_tests) { 'match_spec1 match_spec_2' } + let(:spec_mappings) { %w[spec1_mapping1 spec1_mapping2] } + let(:frontend_fixtures_mapping_json) do + { match_spec1: spec_mappings }.to_json + end + + it 'adds the frontend fixtures mappings to the output file' do + expect(File).to receive(:write).with(output_file, "#{output_file_content} #{spec_mappings.join(' ')}") + + subject + end + end + end + end + end + + describe '#only_js_files_changed' do + subject { instance.only_js_files_changed } + + let(:mr_changes_array) { [] } + + before do + # The class from the GitLab gem isn't public, so we cannot use verified doubles for it. + # + # rubocop:disable RSpec/VerifiedDoubles + allow(gitlab_client).to receive(:merge_request_changes) + .with('dummy-project', '1234') + .and_return(double(changes: mr_changes_array)) + # rubocop:enable RSpec/VerifiedDoubles + end + + context 'when a file is passed as an argument' do + let(:output_file) { 'output_file.out' } + + it 'does not read the output file' do + expect(File).not_to receive(:read).with(output_file) + + subject + end + + it 'calls GitLab API anyways' do + expect(gitlab_client).to receive(:merge_request_changes) + .with('dummy-project', '1234') + + subject + end + end + + context 'when there are no file changes' do + let(:mr_changes_array) { [] } + + it 'returns false' do + expect(subject).to be false + end + end + + context 'when there are changes to files other than JS files' do + let(:mr_changes_array) do + [ + { + "new_path" => "scripts/gitlab_component_helpers.sh", + "old_path" => "scripts/gitlab_component_helpers.sh" + }, + { + "new_path" => "scripts/test.js", + "old_path" => "scripts/test.js" + } + ] + end + + it 'returns false' do + expect(subject).to be false + end + end + + context 'when there are changes only to JS files' do + let(:mr_changes_array) do + [ + { + "new_path" => "scripts/test.js", + "old_path" => "scripts/test.js" + } + ] + end + + it 'returns true' do + expect(subject).to be true + end + end + end +end diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb index 0df490f9b41..502f103af00 100644 --- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb +++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb @@ -334,12 +334,12 @@ RSpec.describe 'layouts/nav/sidebar/_project', feature_category: :navigation do describe 'Deployments' do let(:page) { Nokogiri::HTML.parse(rendered) } - describe 'Feature Flags' do + describe 'Feature flags' do it 'has a link to the feature flags page' do render - expect(page.at_css('.shortcuts-deployments').parent.css('[aria-label="Feature Flags"]')).not_to be_empty - expect(rendered).to have_link('Feature Flags', href: project_feature_flags_path(project)) + expect(page.at_css('.shortcuts-deployments').parent.css('[aria-label="Feature flags"]')).not_to be_empty + expect(rendered).to have_link('Feature flags', href: project_feature_flags_path(project)) end describe 'when the user does not have access' do @@ -348,7 +348,7 @@ RSpec.describe 'layouts/nav/sidebar/_project', feature_category: :navigation do it 'does not have a link to the feature flags page' do render - expect(rendered).not_to have_link('Feature Flags') + expect(rendered).not_to have_link('Feature flags') end end end diff --git a/tooling/bin/find_changes b/tooling/bin/find_changes index 38e1f363dd9..331fae45a53 100755 --- a/tooling/bin/find_changes +++ b/tooling/bin/find_changes @@ -1,82 +1,14 @@ #!/usr/bin/env ruby # frozen_string_literal: true -require 'gitlab' +require_relative '../lib/tooling/find_changes' -class FindChanges # rubocop:disable Gitlab/NamespacedClass - def initialize(output_file:, matched_tests_file: nil, frontend_fixtures_mapping_path: nil) - @gitlab_token = ENV.fetch('PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE', '') - @gitlab_endpoint = ENV.fetch('CI_API_V4_URL') - @mr_project_path = ENV.fetch('CI_MERGE_REQUEST_PROJECT_PATH') - @mr_iid = ENV.fetch('CI_MERGE_REQUEST_IID') - @output_file = output_file - @matched_tests_file = matched_tests_file - @frontend_fixtures_mapping_path = frontend_fixtures_mapping_path - end - - def execute - add_frontend_fixture_files! - - File.write(output_file, file_changes.join(' ')) - end - - private - - def add_frontend_fixture_files? - matched_tests_file && frontend_fixtures_mapping_path - end - - def add_frontend_fixture_files! - return unless add_frontend_fixture_files? - - # If we have a `test file -> JSON frontend fixture` mapping file, we add the files JSON frontend fixtures - # files to the list of changed files so that Jest can automatically run the dependent tests thanks to --findRelatedTests - test_files.each do |test_file| - file_changes.concat(frontend_fixtures_mapping[test_file]) if frontend_fixtures_mapping.key?(test_file) - end - end - - def file_changes - @file_changes ||= - if File.exist?(output_file) - File.read(output_file).split(' ') - else - Gitlab.configure do |config| - config.endpoint = gitlab_endpoint - config.private_token = gitlab_token - end - - mr_changes.changes.flat_map do |change| - change.to_h.values_at('old_path', 'new_path') - end.uniq - end - end - - def mr_changes - @mr_changes ||= Gitlab.merge_request_changes(mr_project_path, mr_iid) - end - - def test_files - return [] if !matched_tests_file || !File.exist?(matched_tests_file) - - File.read(matched_tests_file).split(' ') - end - - def frontend_fixtures_mapping - return {} if !frontend_fixtures_mapping_path || !File.exist?(frontend_fixtures_mapping_path) - - JSON.parse(File.read(frontend_fixtures_mapping_path)) # rubocop:disable Gitlab/Json - end - - attr_reader :gitlab_token, :gitlab_endpoint, :mr_project_path, :mr_iid, :output_file, :matched_tests_file, :frontend_fixtures_mapping_path -end - -output_file = ARGV.shift -raise ArgumentError, "An path to an output file must be given as first argument of #{__FILE__}." if output_file.nil? - -matched_tests_file = ARGV.shift +output_file = ARGV.shift +matched_tests_file = ARGV.shift frontend_fixtures_mapping_path = ARGV.shift -FindChanges - .new(output_file: output_file, matched_tests_file: matched_tests_file, frontend_fixtures_mapping_path: frontend_fixtures_mapping_path) - .execute +Tooling::FindChanges + .new( + output_file: output_file, + matched_tests_file: matched_tests_file, + frontend_fixtures_mapping_path: frontend_fixtures_mapping_path).execute diff --git a/tooling/bin/find_only_js_changes b/tooling/bin/find_only_js_changes new file mode 100755 index 00000000000..67e3d3c6ff5 --- /dev/null +++ b/tooling/bin/find_only_js_changes @@ -0,0 +1,12 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require_relative '../lib/tooling/find_changes' + +if Tooling::FindChanges.new.only_js_files_changed + puts "Only JS files were changed" + exit 0 +else + puts "Changes were made to files other than JS files" + exit 1 +end diff --git a/tooling/lib/tooling/find_changes.rb b/tooling/lib/tooling/find_changes.rb new file mode 100755 index 00000000000..e151734e41c --- /dev/null +++ b/tooling/lib/tooling/find_changes.rb @@ -0,0 +1,89 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'gitlab' + +module Tooling + class FindChanges + def initialize(output_file: nil, matched_tests_file: nil, frontend_fixtures_mapping_path: nil) + @gitlab_token = ENV['PROJECT_TOKEN_FOR_CI_SCRIPTS_API_USAGE'] || '' + @gitlab_endpoint = ENV['CI_API_V4_URL'] + @mr_project_path = ENV['CI_MERGE_REQUEST_PROJECT_PATH'] + @mr_iid = ENV['CI_MERGE_REQUEST_IID'] + @output_file = output_file + @matched_tests_file = matched_tests_file + @frontend_fixtures_mapping_path = frontend_fixtures_mapping_path + end + + def execute + raise ArgumentError, "An path to an output file must be given as first argument." if output_file.nil? + + add_frontend_fixture_files! + File.write(output_file, file_changes.join(' ')) + end + + def only_js_files_changed + @output_file = nil # We ensure that we'll get the diff from the MR directly, not from a file. + + file_changes.any? && file_changes.all? { |file| file.end_with?('.js') } + end + + private + + attr_reader :gitlab_token, :gitlab_endpoint, :mr_project_path, + :mr_iid, :output_file, :matched_tests_file, :frontend_fixtures_mapping_path + + def gitlab + @gitlab ||= begin + Gitlab.configure do |config| + config.endpoint = gitlab_endpoint + config.private_token = gitlab_token + end + + Gitlab + end + end + + def add_frontend_fixture_files? + matched_tests_file && frontend_fixtures_mapping_path + end + + def add_frontend_fixture_files! + return unless add_frontend_fixture_files? + + # If we have a `test file -> JSON frontend fixture` mapping file, we add the files JSON frontend fixtures + # files to the list of changed files so that Jest can automatically run the dependent tests + # using --findRelatedTests flag. + test_files.each do |test_file| + file_changes.concat(frontend_fixtures_mapping[test_file]) if frontend_fixtures_mapping.key?(test_file) + end + end + + def file_changes + @file_changes ||= + if output_file && File.exist?(output_file) + File.read(output_file).split(' ') + else + mr_changes.changes.flat_map do |change| + change.to_h.values_at('old_path', 'new_path') + end.uniq + end + end + + def mr_changes + @mr_changes ||= gitlab.merge_request_changes(mr_project_path, mr_iid) + end + + def test_files + return [] if !matched_tests_file || !File.exist?(matched_tests_file) + + File.read(matched_tests_file).split(' ') + end + + def frontend_fixtures_mapping + return {} if !frontend_fixtures_mapping_path || !File.exist?(frontend_fixtures_mapping_path) + + JSON.parse(File.read(frontend_fixtures_mapping_path)) # rubocop:disable Gitlab/Json + end + end +end |