Work items 및 Work Item 유형

과제

이슈는 협업을 위한 중앙집중식 허브가 될 수 있는 잠재력을 갖고 있습니다. 다양한 이슈 유형이 다른 필드와 다른 컨텍스트를 필요로 하는 것을 받아들여야 합니다. 이 작업에 따라 달라집니다. 예를 들면:

  • 버그는 재현 단계를 나열해야 합니다.
  • 사건은 스택 추적 및 해당 사건에만 관련되는 컨텍스트 정보를 필요로 합니다.

각 객체 유형이 별도의 모델로 이탈하는 대신, 함께 사용할 수 있는 공통 모델을 표준화할 수 있으며 해당 모델에는 포함할 위젯(하나 이상의 속성)을 사용자 정의할 수 있습니다.

현재 이슈 사용의 몇 가지 문제점 및 Work Item을 고려하는 이유는 다음과 같습니다.

  • 이슈 유형을 표시하기 위해 레이블을 사용하는 것은 번거롭고 보고서 보기를 복잡하게 만듭니다.
  • 이슈 유형은 레이블의 주요 두 가지 사용 사례 중 하나이기 때문에 이에 대한 일류 지원을 제공하는 것이 합리적입니다.
  • 이슈에 계속해서 더 많은 기능을 추가함에 따라 이슈가 지저분해 지고 완벽하지 않습니다.
  • 다른 객체와의 관계를 표출하는 일관된 패턴이 없습니다.
  • 다른 종류의 이슈 간 일관된 상호 작용 모델이 없습니다.
  • 이슈 유형의 다양한 구현은 유연성과 확장성이 부족합니다.
  • 이펙트, 이슈, 요구 사항 등은 모두 공통 상호 작용에 대해 유사하지만 약간의 차이가 있어 사용자는 각각의 동작 방식에 대한 복잡한 mental 모델을 가져야 합니다.
  • 이슈는 지원해야 할 새로운 작업의 모든 개발을 처리하기 위해 충분히 확장할 수 없습니다.
  • 이슈 유형을 이슈 추적의 핵심 역할을 넘어서 워크 아이템 유형 지원 및 로직 및 구조적 차이를 처리하는 것이 더 큰 도전이 됩니다.
  • 새로운 기능은 일반적으로 이슈에서 행동을 가져오는 일류 객체로 구현됩니다. 이로 인해 중복된 작업 및 궁극적으로 일반적 상호 작용 사이에 작은 차이가 발생합니다. 이는 일관성 없는 UX로 이어집니다.

Work Item 용어

혼란을 방지하고 효율적인 의사 소통을 보장하기 위해 Work Item에 대한 논의 시에는 오로지 다음 용어를 사용할 것입니다. 이 디렉터리은 Work Item 용어의 단일 진리의 원천(SSoT)입니다.

용어 설명 잘못된 사용 예 되어야 하는 것
work item type Work Item의 클래스; 예: 이슈, 요구 사항, 테스트 케이스, 사건 또는 작업 에픽은 최종적으로 이슈로 발전할 것입니다 에픽은 최종적으로 Work Item 유형으로 발전할 것입니다
work item Work Item 유형의 인스턴스    
work item view 모든 유형의 Work Item을 렌더링하는 새로운 프론트엔드 뷰 이것은 새로운 뷰에서 렌더링되어야 합니다 이것은 Work Item 뷰에 렌더링되어야 합니다
legacy object Work Item 유형으로 변환된 또는 변환될 객체 에픽은 별개의/이전/기존 객체에서 Work Item 유형으로 이전될 것입니다 에픽은 기존 객체에서 Work Item 유형으로 변환될 것입니다
legacy issue view 이슈 및 사건을 렌더링하는 기존 뷰 이슈는 여전히 이전 뷰에서 렌더링됩니다 이슈는 여전히 기존 이슈 뷰에서 렌더링됩니다
issue 현존하는 이슈 모델    
issuable issuable 모듈을 현재 사용 중인 모든 모델(이슈, 에픽 및 MRs) 사건은 issuable입니다 사건은 Work Item 유형입니다
widget 특정 Work Item 데이터를 표시하거나 상호 작용할 수 있도록 하는 UI 요소    

과거에는 일부 용어가 혼란스러워졌으며 현재 권장되지 않습니다.

용어 설명 잘못된 사용 예 되어야 하는 것
issue type Work Item 클래스를 지칭하기 위한 이전 방식 작업은 이슈 유형입니다 작업은 Work Item 유형입니다

이주 전략

WI 모델은 기존 이슈 모델을 기반으로 구축될 것이며, 이슈 모델 코드를 WI 모델로 점진적으로 이주할 것입니다.

이를 처리하는 한 가지 방법은:

class WorkItems::WorkItem < ApplicationRecord
  self.table_name = 'issues'
  
  # ...모든 현재 issue.rb 코드
end

class Issue < WorkItems::WorkItem
  # 이 클래스에 코드를 추가하지 마십시오. WorkItems:WorkItem에 추가하십시오
end

우리는 이미 이슈 테이블 내 issue_type 열을 통해 WITs 개념을 사용하고 있습니다. 이슈, 사건, 테스트 케이스 이슈 유형이 있습니다. 미래에 사용자가 사용자 정의 WITs를 정의할 수 있도록하기 위해 이것을 확장할 것입니다. 따라서 issue_type를 별도의 work_item_types 테이블로 이동할 것입니다. issue_typework_item_types로의 이주 과정은 이 에픽에서 설명된 모든 루트 레벨 그룹을 위한 WITs 집합을 생성하는 것을 포함할 것입니다.

note
먼저, WIT를 루트 레벨 그룹에서만 정의할 수 있을 것이며, 그 다음에는 하위 그룹에서 상속될 것입니다. 나중에 하위 그룹에서 새로운 WIT를 정의하는 가능성을 조사할 것입니다.

work_item_types 테이블 소개

예를 들어 ID가 11, 1213인 세 개의 루트 레벨 그룹이 있다고 가정해 보겠습니다. 또한 다음 기본 유형이 있다면: 이슈: 0, 사건: 1, 테스트 케이스: 2.

해당 work_item_types 레코드:

namespace_id base_type title
11 0 이슈
11 1 사건
11 2 테스트 케이스
12 0 이슈
12 1 사건
12 2 테스트 케이스
13 0 이슈
13 1 사건
13 2 테스트 케이스

이를 달성하기 위해 우리가 할 작업:

  1. 이슈 테이블에 work_item_type_id 열을 추가합니다.
  2. 새로운 또는 업데이트된 이슈에 대해 issue_typework_item_type_id 열 모두에 작성되도록 합니다.
  3. work_item_type_id 열을 뒷받침하여 이슈의 프로젝트 루트 그룹에 대응하는 work_item_types#id를 가리킬 수 있도록 합니다. 예를 들면: ruby issue.project.root_group.work_item_types.where(base_type: issue.issue_type).first.id.

  4. issues#work_item_type_id가 채워지면, 쿼리를 issue_type 대신 work_item_type_id를 사용하는 방향으로 전환할 수 있습니다.

새로운 WIT를 도입하는 데에는 두 가지 옵션이 있습니다:

  • 위 프로세스의 첫 번째 단계를 따릅니다. 사용자의 선택에 따라 새로운 WIT를 루트 레벨 그룹의 모든 사용자에게 사용 가능하게 하는 과정을 실행해야 할 것입니다. 긴 실행 중인 마이그레이션 외에도 work_item_types에 수백만 레코드를 삽입해야 할 수 있습니다. 이것은 추가적인 WIT를 사용하고 싶지 않거나 필요하지 않은 사용자에게 불필요할 수 있습니다.
  • 사용자가 선택한 경우 work_item_types의 특정 루트 레벨 그룹에 대한 레코드는 사용자가 선택했을 때에만 생성되도록 만들 수 있습니다. 그러나 이것은 새롭게 도입된 Work Item 유형의 낮은 발견 가능성을 의미합니다.

작업 항목 유형 위젯

위젯은 작업 항목에 존재할 수 있는 단일 컴포넌트입니다. 이 컴포넌트는 하나 이상의 작업 항목 유형에서 사용될 수 있으며 구현 단계에서 가볍게 사용자 정의될 수 있습니다.

위젯에는 프론트엔드 UI(있는 경우)와 위젯이 사용하는 데이터를 표시하고 관리하는 관련 로직이 모두 포함되어 있습니다. 데이터 모델과 위젯 간에 일대다 연결이 있을 수 있습니다. 즉, 동일한 데이터를 사용하거나 관리하는 여러 위젯이 존재할 수 있으며 동시에 표시될 수 있습니다(예: 읽기 전용 요약 위젯 및 편집 가능한 상세 위젯 또는 동일한 모델의 두 가지 다른 필터링된 보기를 보여주는 두 위젯).

위젯은 목적에 따라 구분되어야 합니다. 가능한 경우, 이 목적은 최대한 높은 수준으로 추상화되어 재사용성을 극대화해야 합니다. 예를 들어 “작업”을 관리하는 위젯은 “하위 항목”으로 구축되었습니다. 하위 항목의 유형을 관리하는 대신, 이를 하위 항목을 관리하는 모든 항목으로 추상화하여 구축했습니다.

모든 WIT(Work Item Types)은 미리 정의된 위젯 풀을 공유하고 특정 WIT에서 활성화된 위젯에 따라 사용자 정의될 것입니다. 모든 속성(열 또는 연결)은 속한 WIT에 관계없이 자체 캡슐화된 기능을 갖는 위젯이 될 것입니다. 어떤 WIT이든 어떤 위젯이든 사용할 수 있기 때문에 특정 WIT에 대해 어떤 위젯이 활성화되어 있는지 정의만 하면 됩니다. 따라서 특정 작업 항목 유형을 전환한 후에는 다른 집합의 위젯이 표시됩니다.

위젯 메타데이터

각 WIT에 해당하는 활성 위젯으로 WIT를 사용자 정의하기 위해 데이터 구조를 사용하여 각 WIT를 매핑해야 합니다.

의도는 GitLab이 다양한 작업 항목 계획을 구현하기 위해 작업 항목 유형을 고도로 구성 가능하게 하고(의견 있는 GitLab 워크플로우 또는 SAFe 5 등), 최종적으로는 고객이 자체 워크플로를 사용자 정의할 수 있도록 하는 것입니다.

이 경우, 작업 항목 계획은 특정 특성(특정 위젯이 활성화되었는지 여부와 같은)을 가진 유형 집합으로 정의될 것입니다. 예를 들어, Epic, Story, Bug 및 Task와 같은 것들.

새로운 작업 항목 구조를 구축할 때, 우리는 매우 유연한 방식으로 이러한 여러 유형을 정의할 수 있도록 하고자 합니다. 고객 사용자 정의를 도입하기 전에 GitLab이 이 시스템을 먼저 사용하도록(고객 사용자 정의를 도입하기 전)하면 초기 시스템을 더 잘 구축할 수 있습니다.

작업 항목의 base_type은 각 유형에 대한 활성 위젯을 정의하는 데 사용됩니다(현재 상태). 이 정의는 데이터베이스 테이블에 저장되어야 합니다. WIT 위젯 메타데이터의 구체적인 구조는 아직 정의되지 않았습니다. base_type은 다른 유형의 리소스(요구 사항 및 사건)를 작업 항목으로 변환하는 데 도움을 주도록 추가되었습니다. 결국(이러한 리소스가 정규 작업 항목이 되는 경우), base_type은 제거될 것입니다.

WIT 위젯의 아키텍처가 확정되기 전에는 새로운 작업 항목 유형을 만드는 것을 보류하고 있습니다. 새로운 작업 항목 유형이 반드시 필요한 경우 프로젝트 관리 엔지니어 팀원에 연락하십시오.

데이터베이스에 새로운 작업 항목 유형 생성

이슈 테이블에서 issue_type 열을 제거하여 새로운 work_item_types 테이블을 사용하도록 변경한 것은 이 에픽)에서 설명한 대로 완료되었습니다.

work_item_types 테이블을 도입한 후, 우리는 더 많은 work_item_types을 추가하고 다른 팀이 쉽게 추가할 수 있도록 하고자 합니다. 새로운 work_item_type을 도입하려면 다음을 수행해야 합니다:

  1. work_item_types 테이블에 새 레코드를 생성하는 데이터베이스 마이그레이션 작성.
  2. Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter를 업데이트합니다.

다음 MR(합병 요청)은 어떻게 새로운 work_item_types를 도입하는지 보여줍니다:

데이터베이스 마이그레이션 작성

먼저, work_item_types 테이블에 새 레코드를 생성하는 데이터베이스 마이그레이션을 작성합니다.

마이그레이션을 작성할 때 다음 사항을 염두에 두십시오:

  • 중요: 기존 API에서 새로운 유형을 제외합니다.
    • 아마도 기존 기능(이슈 디렉터리과 같은)에 새롭게 생성된 작업 항목 유형이 완전히 배포될 때까지 이 유형의 새 작업 항목이 나타나지 않도록 하려고 할 것입니다. 이 경우 이 제외 디렉터리에 새 유형을 추가해야 합니다. 이 마이그레이션이 실행되는 즉시 사용자가 새로운 이슈 및 작업 항목을 생성할 수 있다고 예상하지 않는 한입니다.
  • 특별한 마이그레이션을 사용하지 마십시오.
    • 새로운 작업 항목 유형을 추가하는 데 포스트 배포 마이그레이션 대신 일반적인 마이그레이션을 사용하는 것이 유익하다고 생각합니다. 이렇게 함으로써 이 유형이 즉시 존재한다고 가정할 수 있도록 마이그레이션 의존 MR들이 다음 릴리스를 기다리지 않아도 되도록 하겠습니다.

      중요: 일반 마이그레이션을 사용하는 경우, 두 가지를 반드시 확인해야 합니다: 1. 일반 마이그레이션에 대한 시간 지침을 초과하지 않습니다. 1. 마이그레이션이 역호환성을 유지하도록 합니다. 이것은 이 마이그레이션을 도입한 MR이 롤백되어 마이그레이션이 되돌아가고 마이그레이션이 되어 있지 않더라도 배포된 코드가 계속 작동해야 한다는 것을 의미합니다.

  • 마이그레이션은 실패하지 않아야 합니다.
    • 새 유형을 생성하는 마이그레이션을 실행할 때 work_item_types에 관련된 데이터가 특정 상태에 있는 것으로 예상합니다. 현재, 데이터가 무결하지 않은 상태로 발견되어도 마이그레이션을 실패시키지 않도록 마이그레이션을 작성합니다. 시드(seed)와 마이그레이션을 기반으로 데이터 상태에 얼마나 의존할 수 있는지에 대한 논의가 있습니다. 이를 통해 데이터가 일관되지 않은 상태에 있을 때 마이그레이션이 실패하지 않도록 마이그레이션을 작성할 수 있습니다. 아마도 우리는 이것을 변경하기 위해 몇 가지 데이터베이스 작업을 업데이트해야 할 것입니다.
  • 새 유형에 대한 위젯 정의 추가
    • 마이그레이션은 새 작업 항목 유형과 해당 작업 항목에 필요한 위젯 정의를 추가합니다. 선택하는 위젯은 새로운 작업 항목이 지원하는 기능에 따라 다르지만 Description과 같이 모든 새로운 작업 항목이 필요한 위젯도 있을 것입니다.
  • 선택 사항: 계층 제한 생성
    • 올바른 작업 항목 유형이 Hierarchy 위젯을 사용할 수 있는 경우에만 이 유형을 위한 레코드를 work_item_hierarchy_restrictions 테이블에 삽입합니다. 이 테이블에서는 어떤 작업 항목 유형이 하위 항목이 될 수 있고 무슨 유형의 하위 항목인지를 추가해야 합니다. 또한, 동일한 유형의 작업 항목에 대한 계층 깊이를 지정해야 합니다. 새로운 제한을 생성할 때 기본적으로 계층 간(그룹이나 프로젝트 간) 관계는 비활성화되지만 cross_hierarchy_enabled를 지정하여 활성화할 수 있습니다. 작업 항목 유형에 대해 제한이 캐시되기 때문에, 관련된 작업 항목 유형에 대해 clear_reactive_cache!를 호출해야 합니다.
  • 선택 사항: 연결된 항목 제한 생성
    • Linked items 위젯과 마찬가지로 Linked items 위젯도 연결된 항목 유형을 정의하는 규칙을 지원합니다. 제한은 소스 유형이 다른 유형에 연결되거나 차단할 수 있는지를 지정할 수 있습니다. 현재 제한 사항은 다음과 같습니다:

      유형 연결 가능한 유형 차단할 수 있는 유형 차단 가능한 유형
      Epic Epic, issue, task, objective, key result Epic, issue, task, objective, key result Epic, issue, task
      Issue Epic, issue, task, objective, key result Epic, issue, task, objective, key result Epic, issue, task
      Task Epic, issue, task, objective, key result Epic, issue, task, objective, key result Epic, issue, task
      Objective Epic, issue, task, objective, key result Objective, key result Epic, issue, task, objective, key result
      Key result Epic, issue, task, objective, key result Objective, key result Epic, issue, task, objective, key result
  • 마이그레이션 스펙에 대해 공유된 예시 사용
    • 다른 마이그레이션 유형(새 작업 항목 유형, 새 위젯 정의 등)에 대해 다양한 공유된 예시를 사용해야 합니다. add_work_item_widget_shared_examples.rb에서 각 마이그레이션 유형에 대해 사용해야 하는 공유 예시가 다릅니다.
티켓 작업 항목 추가 예시

데이터베이스에 Ticket 작업 항목 유형이 이미 존재하지만, 마이그레이션 예시로 사용할 것입니다. 새 유형의 경우 새 이름과 ENUM 값을 사용해야 함에 유의하십시오.

class AddTicketWorkItemType < Gitlab::Database::Migration[2.1]
  disable_ddl_transaction!
  restrict_gitlab_migration gitlab_schema: :gitlab_main
  
  ISSUE_ENUM_VALUE = 0
  # Enum 값은 모델에서 정의된 열거형이 있는 곳에서 가져옵니다.
  # https://gitlab.com/gitlab-org/gitlab/-/blob/1253f12abddb69cd1418c9e13e289d828b489f36/app/models/work_items/type.rb#L30.
  # 새 작업 항목 유형은 단순히 다음 정수 값을 선택해야 합니다.
  TICKET_ENUM_VALUE = 8
  TICKET_NAME = 'Ticket'
  # 위젯 정의에는 열거형이 정의되어 있습니다.
  # https://gitlab.com/gitlab-org/gitlab/-/blob/1253f12abddb69cd1418c9e13e289d828b489f36/app/models/work_items/widget_definition.rb#L17.
  # 향후 사용자 정의 위젯 이름을 지원할 예정이므로 열거형과 이름 둘 다 제공해야 합니다.
  TICKET_WIDGETS = {
    'Assignees' => 0,
    'Description' => 1,
    'Hierarchy' => 2,
    'Labels' => 3,
    'Milestone' => 4,
    'Notes' => 5,
    'Start and due date' => 6,
    'Health status' => 7,
    'Weight' => 8,
    'Iteration' => 9,
    'Notifications' => 14,
    'Current user todos' => 15,
    'Award emoji' => 16
  }.freeze
  
  # 중략
end

Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter 업데이트

BaseTypeImporter는 우리가 가진 유형의 구조와 각각에 연관된 위젯을 명확하게 시각화할 수 있는 곳입니다. BaseTypeImporter는 새로 설치된 GitLab 및 테스트 스위트의 단일 근원지입니다. 마이그레이션으로 변경된 사항은 항상 여기에 반영되어야 합니다.

사용자 정의 작업 항목 유형

WIT 위젯 메타데이터와 WIT를 특정 위젯에 매핑하는 워크플로우를 사용하여 사용자 정의 WIT(Work Item Type)을 사용자에게 노출시킬 수 있을 것입니다. 사용자는 자체 WIT을 만들고 미리 정의된 풀에서 위젯을 사용자화할 수 있을 것입니다.

사용자 정의 위젯

최종 목표는 사용자가 사용자 정의 위젯을 정의하고 이러한 사용자 정의 위젯을 모든 WIT에서 사용할 수 있도록 하는 것입니다. 그러나 이것은 더 많은 반복을 필요로하며 데이터 및 응용 프로그램 아키텍처를 결정하기 위해 추가 조사가 필요합니다.

요구 사항과 에픽을 작업 항목 유형으로 마이그레이션

요구 사항과 에픽을 고유한 위젯을 사용하여 작업 항목 유형으로 마이그레이션할 것입니다. 이를 위해 issues 테이블로 데이터를 마이그레이션하고 현재 requirementsepics 테이블을 유지하여 기존 참조와의 역호환성을 보장할 것입니다.

요구 사항을 작업 항목 유형으로 마이그레이션

현재 Requirement 속성은 Issue 속성의 하위 집합이므로 마이그레이션은 주로 다음과 같습니다.

  • 데이터 마이그레이션.
  • API 수준에서의 역호환성 유지.
  • 기존 참조가 계속 작동하도록 보장.

다른 기반 데이터 구조로의 마이그레이션은 최종 사용자에게 무리가 가지 않아야 합니다.

에픽을 작업 항목 유형으로 마이그레이션

에픽은 현재 Issue WIT에는 없는 몇 가지 추가 기능이 있습니다. 따라서, 에픽을 작업 항목 유형으로 마이그레이션하려면 현재 에픽 객체와 WIT 간의 기능 동등성을 제공해야 합니다.

주요 누락된 기능은 다음과 같습니다:

  • 그룹 수준의 작업 항목 가져오기. 이는 그룹 및 프로젝트 통합에 따라 달립니다.
  • 계층 위젯: 작업 항목을 계층 구조로 구조화하는 능력.
  • 상속된 날짜 위젯.

이미 에픽을 사용하고 있는 사용자의 업무 절차를 방해하지 않기 위해 프로젝트 수준에서 에픽과 유사한 기능을 제공하는 ‘Feature’라는 새로운 WIT를 소개할 것입니다. 그룹 및 프로젝트 통합에 대한 진행과 함께 이렇게 함으로써 최소한의 사용자 업무 절차 방해로 에픽을 WIT로의 원활한 마이그레이션 경로를 제공할 수 있을 것입니다.

작업 항목, 작업 항목 유형 및 위젯 로드맵

우리는 작업 항목, 작업 항목 유형 및 사용자 정의 위젯(CW)으로 전환할 것입니다. 진행할 작업의 대략적인 개요는 epic 6033를 참조하십시오.

Redis HLL 카운터 스키마

우리는 현재의 Redis 슬롯 스키마로는 그룹 내 또는 단계 수준에서 기능별로 이벤트를 집계 및 중복 제거할 수 없는 Plan xMAU, Project Management xMAU, Certify xMAU 및 Product Planning xMAU를 보다 확장 가능한 Redis 카운터 스키마가 필요합니다.

세 가지 Plan 제품 그룹은 모두 동일한 기본 객체(work item)를 사용할 것입니다. 각 제품 그룹은 여전히 MAU를 추적해야 합니다.

제안된 집계 카운터 스키마

graph TD Event[특정 상호 작용 카운터] --> AC[집계 카운터] AC --> Plan[Plan xMAU] AC --> PM[프로젝트 관리 xMAU] AC --> PP[제품 기획 xMAU] AC --> Cer[인증 xMAU] AC --> WI[작업 항목 사용자]

구현

새로운 집계 스키마는 이미 구현되었으며 이미 GitLab.com에서 작업 항목의 고유한 작업을 추적하고 있습니다.

구현 세부 정보에 대해서는 MR를 참조할 수 있습니다. 이 MR은 새로운 고유한 작업의 정의, 코드에서의 이벤트 추적 및 필요한 집계 카운터에 새로운 고유한 작업 추가를 다룹니다.