Feature Categorization

Introduced in GitLab 13.2.

Each Sidekiq worker, controller action, or (eventually) API endpoint must declare a feature_category attribute. This attribute maps each of these to a feature category. This is done for error budgeting, alert routing, and team attribution.

The list of feature categories can be found in the file config/feature_categories.yml. This file is generated from the stages.yml data file used in the GitLab Handbook and other GitLab resources.

Updating config/feature_categories.yml

Occasionally new features will be added to GitLab stages, groups, and product categories. When this occurs, you can automatically update config/feature_categories.yml by running scripts/update-feature-categories. This script will fetch and parse stages.yml and generate a new version of the file, which needs to be committed to the repository.

The Scalabilitity team currently maintains the stages.yml file. They will automatically be notified on Slack when the file becomes outdated.

Sidekiq workers

The declaration uses the feature_category class method, as shown below.

class SomeScheduledTaskWorker
  include ApplicationWorker

  # Declares that this worker is part of the
  # `continuous_integration` feature category
  feature_category :continuous_integration

  # ...
end

The feature categories specified using feature_category should be defined in config/feature_categories.yml. If not, the specs will fail.

Excluding Sidekiq workers from feature categorization

A few Sidekiq workers, that are used across all features, cannot be mapped to a single category. These should be declared as such using the feature_category_not_owned! declaration, as shown below:

class SomeCrossCuttingConcernWorker
  include ApplicationWorker

  # Declares that this worker does not map to a feature category
  feature_category_not_owned!

  # ...
end

Rails controllers

Specifying feature categories on controller actions can be done using the feature_category class method.

A feature category can be specified on an entire controller using:

class Projects::MergeRequestsController < ApplicationController
  feature_category :source_code_management
end

The feature category can be limited to a list of actions using the only argument, actions can be excluded using the except argument.

class Projects::MergeRequestsController < ApplicationController
  feature_category :code_testing, only: [:metrics_reports]
  feature_category :source_code_management, except: [:test_reports, :coverage_reports]
end

except and only arguments can not be combined.

When specifying except all other actions will get the specified category assigned.

The assignment can also be scoped using if and unless procs:

class Projects::MergeRequestsController < ApplicationController
  feature_category :source_code_management,
                   unless: -> (action) { action.include?("reports") }
                   if: -> (action) { action.include?("widget") }
end

In this case, both procs need to be satisfied for the action to get the category assigned.

Excluding controller actions from feature categorization

In the rare case an action cannot be tied to a feature category this can be done using the not_owned feature category.

class Admin::LogsController < ApplicationController
  feature_category :not_owned
end

Ensuring feature categories are valid

The spec/controllers/every_controller_spec.rb will iterate over all defined routes, and check the controller to see if a category is assigned to all actions.

The spec also validates if the used feature categories are known. And if the actions used in only and except configuration still exist as routes.