Help us learn about your current experience with the documentation. Take the survey.

功能分类

每个 Sidekiq worker、批量后台迁移(Batched Background migrations)、controller action、测试示例 或 API 端点都必须声明一个 feature_category 属性。这个属性将每个元素映射到一个 功能类别。这样做的目的是为了错误预算(error budgeting)、告警路由(alert routing)和团队归属(team attribution)。

功能类别列表可以在 config/feature_categories.yml 文件中找到。该文件是根据 GitLab Handbook 和其他 GitLab 资源中使用的 stages.yml 数据文件生成的。

更新 config/feature_categories.yml

偶尔会有新功能添加到 GitLab 的阶段(stages)、组(groups)和产品类别中。当这种情况发生时,你可以通过运行 scripts/update-feature-categories 来自动更新 config/feature_categories.yml。这个脚本会获取并解析 stages.yml 文件,并生成一个新版本的文件,需要将其提交到仓库中。

可扩展性团队 目前维护着 feature_categories.yml 文件。当文件过时时,他们会在 Slack 上收到自动通知。

Gemfile

对于每个 Ruby gem 依赖,我们应该指定哪个功能类别需要这个依赖。这应该明确所有权,我们可以将升级委托给拥有该功能的相关组。

工具功能类别

对于开发者体验(Developer Experience)内部工具,我们使用 feature_category: :tooling。例如,knapsackgitlab-crystalball 都用于在 CI 中运行 RSpec 测试套件,它们不属于任何产品组。

测试平台功能类别

对于主要由 测试平台子部门 维护的 gem,我们使用 feature_category: :test_platform。例如,capybaraGemfileqa/Gemfile 中都有定义,用于运行涉及 UI 的测试。它们不属于特定的产品组。

共享功能类别

对于在不同产品组之间使用的 gem,我们使用 feature_category: :shared。例如,rails 在整个应用程序中使用,并与多个组共享。

Sidekiq workers

声明使用 feature_category 类方法,如下所示。

class SomeScheduledTaskWorker
  include ApplicationWorker

  # 声明这个 worker 属于
  # `continuous_integration` 功能类别
  feature_category :continuous_integration

  # ...
end

使用 feature_category 指定的功能类别应该在 config/feature_categories.yml 中定义。如果没有定义,测试将会失败。

将 Sidekiq workers 排除在功能分类之外

一些用于所有功能的 Sidekiq workers 无法映射到单个类别。这些应该使用 feature_category :not_owned 声明来声明,如下所示:

class SomeCrossCuttingConcernWorker
  include ApplicationWorker

  # 声明这个 worker 不映射到任何功能类别
  feature_category :not_owned # rubocop:disable Gitlab/AvoidFeatureCategoryNotOwned

  # ...
end

在可能的情况下,标记为 “not owned” 的 workers 在指标和日志中使用其调用者的类别(worker 或 HTTP 端点)。例如,ReactiveCachingWorker 在指标和日志中可以有多个功能类别。

批量后台迁移

长时间运行的迁移(根据 时间限制指南)被提取为 批量后台迁移。它们应该定义一个 feature_category,如下所示:

# 文件名: lib/gitlab/background_migration/my_background_migration_job.rb

class MyBackgroundMigrationJob < BatchedMigrationJob
  feature_category :gitaly

  #...
end

RuboCop::Cop::BackgroundMigration::FeatureCategory cop 确保定义了有效的 feature_category

Rails controllers

可以使用 feature_category 类方法为 controller actions 指定功能类别。

可以在整个 controller 上指定功能类别,使用:

class Boards::ListsController < ApplicationController
  feature_category :kanban_boards
end

可以使用第二个参数将功能类别限制为动作列表:

class DashboardController < ApplicationController
  feature_category :team_planning, [:issues, :issues_calendar]
  feature_category :code_review_workflow, [:merge_requests]
end

这些形式不能混合使用:如果一个 controller 有多个类别,每个动作都必须列出。

将 controller actions 排除在功能分类之外

在极少数情况下,如果一个动作无法与功能类别关联,可以使用 not_owned 功能类别来完成。

class Admin::LogsController < ApplicationController
  feature_category :not_owned
end

确保功能类别有效

spec/controllers/every_controller_spec.rb 会遍历所有已定义的路由,并检查 controller 是否为所有动作分配了类别。

该测试还会验证使用的功能类别是否已知,以及配置中使用的动作是否仍然作为路由存在。

API endpoints

GraphQL API 目前被归类为 not_owned。目前不需要额外的规范。更多信息,请参见 gitlab-com/gl-infra/scalability#583

Grape API 端点可以使用 feature_category 类方法,就像 Rails controllers 一样:

module API
  class Issues < ::API::Base
    feature_category :team_planning
  end
end

第二个参数可用于为特定路由指定功能类别:

module API
  class Users < ::API::Base
    feature_category :user_profile, ['/users/:id/custom_attributes', '/users/:id/custom_attributes/:key']
  end
end

或者可以在动作本身中指定功能类别:

module API
  class Users < ::API::Base
    get ':id', feature_category: :user_profile do
    end
  end
end

与 Rails controllers 一样,API 类必须为每个动作指定类别,除非该类中的每个动作都使用相同的类别。

RSpec Examples

你必须为每个 RSpec 示例设置功能类别元数据。此信息用于识别拥有该功能的组,以解决不稳定测试问题。

feature_category 应该是 config/feature_categories.yml 中的一个值。

feature_category 元数据可以设置:

如果在同一文件中识别出多个功能类别,考虑拆分该文件。

示例:

RSpec.describe Admin::Geo::SettingsController, :geo, feature_category: :geo_replication do

对于没有设置 feature_category 的示例,在本地环境中运行时会添加警告。

要禁用警告,在运行 RSpec 测试时使用 RSPEC_WARN_MISSING_FEATURE_CATEGORY=false

RSPEC_WARN_MISSING_FEATURE_CATEGORY=false bin/rspec spec/<test_file>

此外,我们通过 RSpec/FeatureCategory RuboCop 规则标记违规行为。

工具功能类别

对于工程生产力(Engineering Productivity)内部工具,我们使用 feature_category: :tooling

例如在 spec/tooling/danger/specs_spec.rb 中。

共享功能类别

对于支持开发者且不特定于产品组的功能,我们使用 feature_category: :shared。例如 spec/lib/gitlab/job_waiter_spec.rb

Admin 部分

在添加 Admin 部分的新内容时,添加功能类别同样重要。历史上,Admin 部分在代码中通常被标记为 not_owned。现在,你必须确保 Admin 部分的每个新内容都使用 feature_category 标记法正确标注。