기능 분류

각 Sidekiq worker, Batched Background migrations, controller action, 테스트 예제 또는 API 엔드포인트는 feature_category 속성을 선언해야 합니다. 이 속성은 각각의 기능 카테고리에 매핑됩니다. 이러한 매핑은 오류 예산 메트릭, 경고 경로 설정 및 팀 소유권을 위해 수행됩니다.

기능 카테고리 디렉터리은 config/feature_categories.yml 파일에서 찾을 수 있습니다. 이 파일은 GitLab 핸드북 및 다른 GitLab 자료에서 사용되는 stages.yml 데이터 파일에서 생성됩니다.

config/feature_categories.yml 업데이트

가끔씩 새로운 기능이 GitLab stages, 그룹 및 제품 카테고리에 추가될 수 있습니다. 이럴 때 config/feature_categories.yml을 자동으로 업데이트하려면 scripts/update-feature-categories를 실행하면 됩니다. 이 스크립트는 stages.yml 파일을 가져와 파싱하고, 파일의 새 버전을 생성하여 리포지터리에 커밋되어야 합니다.

확장성 팀이 현재 feature_categories.yml 파일을 유지하고 있습니다. 파일이 오래된 경우 해당 팀에게 슬랙으로 자동으로 알림이 전송됩니다.

Gemfile

각 Ruby gem 의존성에 대해 해당 기능 카테고리를 명시해야 합니다. 이로써 소유권을 명확히하고 해당 기능을 소유하는 해당 그룹에 업그레이드를 위임할 수 있습니다.

도구 기능 카테고리

엔지니어링 프로덕션성 내부 도구에는 feature_category: :tooling을 사용합니다. 예를 들어, knapsackcrystalball은 모두 RSpec 테스트 스위트를 CI에서 실행하는 데 사용되며 어떠한 제품 그룹에도 속하지 않습니다.

공유 기능 카테고리

여러 제품 그룹 전반에서 사용되는 젬의 경우 feature_category: :shared를 사용합니다. 예를 들어 rails는 애플리케이션 전체에서 사용되며 여러 그룹과 공유됩니다.

Sidekiq worker

아래와 같이 feature_category 클래스 메서드를 사용하여 선언합니다.

class SomeScheduledTaskWorker
  include ApplicationWorker
  
  # 이 worker가 `continuous_integration` 기능 카테고리의 일부임을 선언함
  feature_category :continuous_integration
  
  # ...
end

feature_category를 사용하여 지정된 기능 카테고리는 반드시 config/feature_categories.yml에 정의되어 있어야 합니다. 그렇지 않으면 스펙이 실패합니다.

Sidekiq worker의 기능 카테고리 제외

몇 가지 모든 기능에 걸쳐 사용되는 Sidekiq worker는 단일 카테고리에 매핑할 수 없습니다. 이들은 다음과 같이 feature_category :not_owned 선언을 사용하여 선언되어야 합니다.

class SomeCrossCuttingConcernWorker
  include ApplicationWorker
  
  # 이 worker가 기능 카테고리에 매핑되지 않음을 선언함
  feature_category :not_owned # rubocop:disable Gitlab/AvoidFeatureCategoryNotOwned
  
  # ...
end

가능한 경우 “소유되지 않는”으로 표시된 워커는 메트릭 및 로그에서 호출자의 범주(작업자 또는 HTTP 엔드포인트)를 사용합니다. 예를 들어 ReactiveCachingWorker는 메트릭과 로그에서 여러 기능 카테고리를 가질 수 있습니다.

Batched background migrations

시간 제한 지침에 따른 장기 실행 마이그레이션은 배치된 백그라운드 마이그레이션으로 추출됩니다. 다음과 같이 feature_category를 정의해야 합니다.

# 파일명: lib/gitlab/background_migration/my_background_migration_job.rb

class MyBackgroundMigrationJob < BatchedMigrationJob
  feature_category :gitaly
  
  #...
end

참고: RuboCop::Cop::BackgroundMigration::FeatureCategory는 유효한 feature_category가 정의되었는지 확인합니다.

Rails 컨트롤러

컨트롤러 액션에 대한 기능 카테고리 지정은 feature_category 클래스 메서드를 사용하여 수행할 수 있습니다.

기능 카테고리는 다음을 사용하여 전체 컨트롤러에 지정할 수 있습니다.

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

이러한 형식은 혼합될 수 없습니다. 컨트롤러에 하나 이상의 카테고리가 있는 경우 모든 단일 액션이 나열되어야 합니다.

컨트롤러 액션을 기능 카테고리에서 제외

드문 경우에 액션이 특정한 기능 카테고리에 매핑되지 않을 수 있습니다. 이를 not_owned 기능 카테고리를 사용하여 수행할 수 있습니다.

class Admin::LogsController < ApplicationController
  feature_category :not_owned
end

유효한 기능 카테고리인지 확인

spec/controllers/every_controller_spec.rb는 모든 정의된 경로를 반복하여 모든 액션에 카테고리가 할당되었는지 확인합니다.

이 특수는 사용된 기능 카테고리가 알려진지 확인하고 구성에서 사용되는 동작이 여전히 경로로 존재하는지도 확인합니다.

API 엔드포인트

GraphQL API는 현재 not_owned로 분류됩니다. 추가 사양은 현재 필요하지 않습니다. 자세한 정보는 gitlab-com/gl-infra/scalability#583을 참조하세요.

Grape API 엔드포인트는 Rails 컨트롤러와 같이 feature_category 클래스 메서드를 사용할 수 있습니다.

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 컨트롤러와 마찬가지로 API 클래스는 해당 클래스 내의  액션에 대해 동일한 카테고리를 사용하는 경우를 제외하고는 모든 단일 액션에 대해 카테고리를 지정해야 합니다.

## RSpec 예제

 RSpec 예제에 대한 기능 카테고리 메타데이터를 설정해야 합니다.  정보는 플래키 테스트 문제를 식별하는  사용되어 해당 기능을 소유하는 그룹을 식별하는  사용됩니다.

`feature_category`는 [`config/feature_categories.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/feature_categories.yml)의 값이어야 합니다.

`feature_category` 메타데이터는 다음과 같이 설정할 수 있습니다:

- [최상위 `Rspec.describe` 블록](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104274/diffs#6bd01173381e873f3e1b6c55d33cdaa3d897156b_5_5)에서
- [설명하다 블록](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104274/diffs#a520db2677a30e7f1f5593584f69c49031b894b9_12_12)에서

같은 파일에 동일한 기능 카테고리가 식별되는 경우 파일을 분할하는 것을 고려하세요.

예제:

```ruby
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 규칙을 통해 위반 사항을 표시합니다.

도구 기능 범주

엔지니어링 프로덕션성 내부 도구에는 feature_category: :tooling을 사용합니다.

예를 들어, spec/tooling/danger/specs_spec.rb.

공유 기능 범주

개발자를 지원하는 기능에 대해 특정 제품 그룹과 관련이 없는 경우 feature_category: :shared를 사용합니다. 예를 들어, spec/lib/gitlab/job_waiter_spec.rb

관리자 섹션

새로운 파트를 관리자 섹션에 추가할 때 feature_category 주석을 사용하여 적절히 주석을 달아야 합니다.

역사적으로, 관리자 섹션은 코드에서 종종 not_owned로 표시되었습니다. 이제는 관리자 섹션에 새로운 추가가 올바르게 주석 처리되도록 각각을 확인해야 합니다.