작업 항목 및 작업 항목 유형
GitLab v19.1작업 항목(Work Items)은 GitLab의 이슈 추적 기능을 표준화하고 확장하는 유연한 모델을 도입합니다. 이슈는 협업을 위한 중앙 허브가 될 가능성이 있습니다. 버그에는 재현 단계를 나열해야 합니다. 인시던트에는 스택 트레이스 참조와 해당 인시던트에만 관련된 기타 맥락 정보가 필요합니다.
작업 항목(Work Items)은 GitLab의 이슈 추적 기능을 표준화하고 확장하는 유연한 모델을 도입합니다. 작업 항목을 사용하면 다양한 위젯으로 커스터마이즈할 수 있는 다양한 유형을 정의하여 버그, 인시던트, 테스트 케이스 또는 기타 작업 단위를 추적하는 등 특정 요구사항을 충족할 수 있습니다. 이 아키텍처 문서는 작업 항목 및 작업 항목 유형에 대한 개발 세부 사항과 구현 전략을 다룹니다. 앞으로 진행해야 할 작업의 대략적인 개요는 에픽 6033을 참조하세요.
과제#
이슈는 협업을 위한 중앙 허브가 될 가능성이 있습니다. 각기 다른 이슈 유형은 어떤 작업을 수행하는 데 사용되는지에 따라 서로 다른 필드와 맥락이 필요하다는 사실을 받아들여야 합니다. 예를 들어:
-
버그에는 재현 단계를 나열해야 합니다.
-
인시던트에는 스택 트레이스 참조와 해당 인시던트에만 관련된 기타 맥락 정보가 필요합니다.
각 객체 유형이 별도의 모델로 분기되는 대신, 포함하는 위젯(하나 이상의 속성)으로 커스터마이즈할 수 있는 공통 기반 모델을 표준화할 수 있습니다.
현재 이슈 사용의 문제점과 작업 항목을 검토하는 이유는 다음과 같습니다:
라벨을 사용하여 이슈 유형을 표시하는 것은 번거롭고 보고 뷰를 더 복잡하게 만듭니다.
이슈 유형은 라벨의 상위 두 가지 사용 사례 중 하나이므로, 이를 위한 일급 지원을 제공하는 것이 합리적입니다.
더 많은 기능을 추가함에 따라 이슈가 혼잡해지기 시작했으며, 완벽하지 않습니다:
다른 객체와의 관계를 표시하는 방법에 일관된 패턴이 없습니다.
-
라벨을 사용하기 때문에 서로 다른 이슈 유형 간에 일관된 인터랙션 모델이 없습니다.
-
이슈 유형의 다양한 구현은 유연성과 확장성이 부족합니다.
에픽, 이슈, 요구사항 등은 공통 인터랙션에서 유사하지만 미묘한 차이가 있어 사용자가 각각의 동작 방식에 대한 복잡한 정신 모델을 유지해야 합니다.
이슈는 지원해야 할 새로운 작업들을 충분히 수용할 만큼 확장 가능하지 않습니다.
Issue 유형을 이슈 추적의 핵심 역할을 넘어 다양한 작업 항목 유형을 지원하고 로직 및 구조 차이를 처리하는 방향으로 확장함에 따라 코드베이스 유지 관리 및 기능 개발이 더 큰 과제가 됩니다.
새로운 기능은 일반적으로 공유 관심사를 통해 이슈의 동작을 가져오는 일급 객체로 구현됩니다. 이는 중복된 노력으로 이어지고, 궁극적으로 공통 인터랙션 간에 작은 차이를 유발합니다. 이는 일관성 없는 UX로 이어집니다.
작업 항목 용어#
혼란을 방지하고 효율적인 커뮤니케이션을 보장하기 위해, 작업 항목에 대해 논의할 때 다음 용어만 사용합니다. 이 목록은 작업 항목 용어의 단일 진실 공급원(Single Source Of Truth, SSOT)입니다.
| 용어 | 설명 | 잘못된 사용 예 | 올바른 표현 |
|---|---|---|---|
| work item type | 작업 항목의 클래스; 예: 이슈, 요구사항, 테스트 케이스, 인시던트, 태스크 | 에픽은 결국 이슈가 될 것이다 | 에픽은 결국 work item type이 될 것이다 |
| work item | work item type의 인스턴스 | ||
| work item view | 모든 유형의 작업 항목을 렌더링하는 새로운 프론트엔드 뷰 | 이것은 새 뷰에서 렌더링되어야 한다 | 이것은 work item view에서 렌더링되어야 한다 |
| legacy object | 작업 항목 유형으로 전환되었거나 전환될 객체 | 에픽은 독립/구형/이전 객체에서 work item type으로 마이그레이션될 것이다 | 에픽은 legacy object에서 work item type으로 전환될 것이다 |
| legacy issue view | 이슈와 인시던트를 렌더링하는 데 사용되는 기존 뷰 | 이슈는 계속 구 뷰에서 렌더링된다 | 이슈는 계속 legacy issue view에서 렌더링된다 |
| issue | 기존 이슈 모델 | ||
| issuable | 현재 issuable 모듈을 사용하는 모든 모델 (이슈, 에픽, MR) | 인시던트는 issuable이다 | 인시던트는 work item type이다 |
| widget | 특정 작업 항목 데이터를 표시하거나 상호작용을 허용하는 UI 요소 |
일부 용어는 과거에 사용되었지만 이후 혼란을 야기하여 현재는 사용을 권장하지 않습니다.
| 용어 | 설명 | 잘못된 사용 예 | 올바른 표현 |
|---|---|---|---|
| issue type | 작업 항목 클래스를 지칭하던 이전 방식 | 태스크는 issue type이다 | 태스크는 work item type이다 |
마이그레이션 전략#
WI 모델은 기존 Issue 모델 위에 구축되며, Issue 모델 코드를 WI 모델로 점진적으로 마이그레이션할 것입니다.
접근 방법 중 하나는 다음과 같습니다:
class WorkItems::WorkItem < ApplicationRecord
self.table_name = 'issues'
# ... all the current issue.rb code
end
class Issue < WorkItems::WorkItem
# Do not add code to this class add to WorkItems:WorkItem
end
issues 테이블 내에서 issue_type 칼럼을 통해 이미 WIT 개념을 사용하고 있습니다.
issue, incident, test_case 이슈 유형이 있습니다. 향후 사용자가 커스텀 WIT를 정의할 수 있도록
확장하기 위해, issue_type을 별도의 테이블인 work_item_types로 이동할 것입니다.
issue_type을 work_item_types로 마이그레이션하는 과정은 이 에픽에
설명된 대로 모든 루트 수준 그룹에 대한 WIT 세트 생성을 포함합니다.
처음에는 WIT 정의가 루트 수준 그룹에서만 가능하며, 이후 하위 그룹에 상속됩니다. 향후 반복에서 하위 그룹 수준에서 새 WIT를 정의하는 가능성을 조사할 것입니다.
작업 항목 유형 아키텍처#
GitLab은 시스템 정의 유형과 커스텀 작업 항목 유형을 모두 지원하는 유연한 유형 시스템을 사용합니다. 이 아키텍처는 교차 셀 데이터베이스 쿼리 없이 효율적인 유형 조회를 가능하게 하는 Cells 이니셔티브의 요구사항을 충족하도록 설계되었습니다. 아키텍처 배경은 구성 가능한 작업 항목 유형 설계 문서를 참조하세요.
시스템 정의 유형#
시스템 정의 유형은 GitLab에 내장된 사전 정의된 작업 항목 유형입니다. 이 유형들은 코드에서 Ruby 모듈로 정의되어 시작 시 메모리에 로드됩니다.
사용 가능한 유형:
| 유형 | ID | 기본 유형 | 가용성 | 비고 |
|---|---|---|---|---|
| Issue | 1 | issue | CE + EE | |
| Incident | 2 | incident | CE + EE | 전체 WIT로 전환 중 |
| Test Case | 3 | test_case | EE only | 전체 WIT로 전환 중 |
| Requirement | 4 | requirement | EE only | 전체 WIT로 전환 중 |
| Task | 5 | task | CE + EE | |
| Objective | 6 | objective | EE only | 제거 예정 |
| Key Result | 7 | key_result | EE only | 제거 예정 |
| Epic | 8 | epic | EE only | |
| Ticket | 9 | ticket | CE + EE |
구현 세부 사항:
-
모델:
WorkItems::TypesFramework::SystemDefined::Type -
위치:
app/models/work_items/types_framework/system_defined/ -
각 유형은
definitions/디렉터리에 정의 모듈이 있습니다 (예:definitions/issue.rb) -
데이터베이스 쿼리 없이 ActiveRecord 유사 API를 제공하기 위해
ActiveRecord::FixedItemsModel을 사용합니다
유형 정의 예시:
module WorkItems::TypesFramework::SystemDefined::Definitions::Issue
def self.configuration
{ id: 1, name: 'Issue', base_type: 'issue', icon_name: 'work-item-issue' }
end
def self.widgets
%w[assignees description labels milestone notes ...]
end
def self.supports_move_action?
true
end
end
커스텀 작업 항목 유형#
커스텀 유형을 통해 조직과 네임스페이스는 자신의 워크플로에 맞게 작업 항목 유형을 만들 수 있습니다. 이 기능은 FY27 Q1에 제공될 예정입니다.
커스텀 유형은 두 가지 방법으로 생성할 수 있습니다:
-
완전히 새로운 커스텀 유형 - 시스템 정의 유형처럼 동작하지만 고유한 개념을 나타내는 완전히 새로운 유형을 만듭니다 (예: "Pizza"). 이 유형은 기본적으로 Issue처럼 동작하지만 고유한 정체성을 가집니다.
-
전환된 유형 - 기존 시스템 정의 유형을 전환하여 커스텀 유형을 만듭니다. 커스텀 유형은 원래 시스템 정의 유형을 참조하며 다른 속성(이름, 아이콘, 보관 상태)만 저장합니다. 다른 모든 동작과 위젯은 참조된 시스템 정의 유형에서 상속됩니다.
구현 세부 사항:
-
모델:
WorkItems::TypesFramework::Custom::Type -
테이블:
work_item_custom_types -
범위:
Self-Managed: 조직 수준 (장기 타깃 범위)
-
SaaS (GitLab.com): 루트 그룹 수준 (조직 수준 기능이 사용 가능할 때까지의 임시 솔루션)
-
한도: 부모 범위당,
WorkItems::TypesFramework::Custom::Type::MAX_TYPE_PER_PARENT에 저장됨
GitLab.com에서는 현재 모든 루트 그룹이 동일한 조직에 속하기 때문에 커스텀 유형이 루트 그룹으로 범위가 지정됩니다. SaaS에서 조직 수준 기능이 완전히 사용 가능하게 되면, Self-Managed와 일치하도록 커스텀 유형이 조직 범위로 이동됩니다.
전환된 유형:
시스템 정의 유형을 전환할 때, 커스텀 유형은 원본을 참조하고 특정 커스터마이즈를 허용하면서 동작을 상속합니다.
커스터마이즈 가능한 속성:
-
name- 커스텀 표시 이름 (최대 48자) -
icon_name- 커스텀 아이콘 선택 -
archived- 보관 상태
상속되는 속성:
-
위젯 구성 (향후: 유형별 커스터마이즈 가능)
-
기본 유형 동작
-
계층 제한
예시:
조직이 시스템 정의 "Issue" 유형을 전환하여 커스텀 "Bug" 유형을 만드는 경우:
-
모든 Issue 위젯과 동작을 상속합니다
-
이름을 "Bug"로 재정의합니다
-
선택적으로 다른 아이콘을 사용합니다
-
converted_from_system_defined_type_identifier칼럼을 통해 Issue 유형을 참조합니다
Provider 인터페이스#
WorkItems::TypesFramework::Provider 클래스는 작업 항목 유형에 접근하기 위한 단일 진입점입니다.
모든 코드는 유형 클래스에 직접 접근하는 대신 Provider를 사용해야 합니다.
네임스페이스 컨텍스트:
Provider에 네임스페이스를 전달하는 것은 사용 가능한 유형을 결정하기 때문에 매우 중요합니다:
-
네임스페이스 없음: 시스템 정의 유형만 반환 (9개의 전역 유형)
-
네임스페이스 있음: 시스템 정의 유형과 다음에 대해 정의된 커스텀 유형(전환된 유형 또는 완전히 새로운 유형) 모두 반환:
Self-Managed: 네임스페이스의 조직
- SaaS (GitLab.com): 네임스페이스를 포함하는 루트 그룹
Provider는 단일 요청 내에서 빠른 조회를 위해 요청 저장소에 유형을 캐시하여, 커스텀 유형에 대한 반복적인 쿼리를 방지합니다.
사용법:
# Initialize with namespace context
provider = WorkItems::TypesFramework::Provider.new(namespace)
# Fetch types
provider.all # All available types
provider.filtered_types # Types available to namespace
provider.find_by_base_type(:issue) # Find by base type
provider.find_by_id(1) # Find by ID
provider.default_issue_type # Get default issue type
관련 파일:
-
Provider:
types_framework/provider.rb -
커스텀 유형:
types_framework/custom/type.rb
이전 맥락#
GitLab 18.1 이전에는 작업 항목 유형이 work_item_types 데이터베이스 테이블에 저장되었습니다.
이 방식은 Cells 이니셔티브를 지원하기 위해
현재의 시스템 정의 유형 아키텍처로 대체되었습니다.
작업 항목 유형 위젯#
위젯은 작업 항목에 존재할 수 있는 단일 컴포넌트입니다. 이 컴포넌트는 하나 또는 여러 작업 항목 유형에서 사용될 수 있으며 구현 지점에서 가볍게 커스터마이즈할 수 있습니다.
위젯에는 프론트엔드 UI(있는 경우)와 위젯이 사용하는 데이터를 표시하고 관리하기 위한 관련 로직이 모두 포함됩니다. 데이터 모델과 위젯 사이에는 일대다 연결이 있을 수 있습니다. 즉, 동일한 데이터를 사용하거나 관리하는 여러 위젯이 있을 수 있으며, 동시에 존재할 수 있습니다 (예: 읽기 전용 요약 위젯과 편집 가능한 세부 정보 위젯, 또는 동일한 모델의 두 가지 다른 필터링된 뷰를 보여주는 두 개의 위젯).
위젯은 목적에 따라 차별화되어야 합니다. 가능한 경우, 이 목적은 재사용성을 극대화하기 위해 가장 합리적인 수준으로 추상화되어야 합니다. 예를 들어, "태스크"를 관리하기 위한 위젯은 "하위 항목"으로 구축되었습니다. 하나의 유형의 자식을 관리하는 대신, 모든 자식을 관리하도록 추상화되었습니다.
모든 WIT는 사전 정의된 위젯의 동일한 풀을 공유하며, 특정 WIT에서 어떤 위젯이 활성화되어 있는지에 따라 커스터마이즈됩니다. 모든 속성(칼럼 또는 연관)은 속한 WIT에 관계없이 자체 캡슐화된 기능을 갖는 위젯이 됩니다. 어떤 WIT든 어떤 위젯이든 가질 수 있기 때문에, 특정 WIT에 대해 어떤 위젯이 활성화되어 있는지만 정의하면 됩니다. 따라서 특정 작업 항목의 유형을 전환한 후 다른 위젯 세트가 표시됩니다.
작업 항목 위젯과 새 위젯을 만드는 방법에 대해 더 자세히 읽어보세요.
위젯 메타데이터#
각 WIT를 해당 활성 위젯으로 커스터마이즈하기 위해 각 WIT를 특정 위젯에 매핑하는 데이터 구조가 필요합니다.
작업 항목 유형이 고도로 구성 가능하도록 하는 것이 의도입니다. GitLab이 고객을 위한 다양한 작업 항목 스키마 (의견이 반영된 GitLab 워크플로, SAFe 5 등)를 구현하기 위해서도, 그리고 궁극적으로 고객이 자신의 워크플로를 커스터마이즈할 수 있도록 하기 위해서도 마찬가지입니다.
이 경우, 작업 항목 스키마는 에픽, 스토리, 버그, 태스크 등 특정 특성(일부 위젯은 활성화, 다른 위젯은 비활성화)을 가진 유형 세트로 정의됩니다.
새로운 작업 항목 아키텍처를 구축하면서, 이러한 다양한 유형을 매우 유연한 방식으로 정의하는 기능을 구축하고자 합니다. GitLab이 이 시스템을 먼저 사용(고객 커스터마이즈를 도입하지 않고)함으로써 초기 시스템을 더 잘 구축할 수 있습니다.
base_type 속성은 작업 항목의 기본 유형 분류(이슈, 에픽, 태스크 등)를 식별합니다.
이 속성은 기본 위젯 구성과 동작을 결정합니다.
커스텀 작업 항목 유형은 시스템 정의 유형의 base_type에 위임하여 위젯 구성과 동작을 상속합니다.
향후 반복에서는 커스텀 유형에 대한 커스텀 위젯 선택을 지원할 예정입니다.
시스템 정의 작업 항목 유형 추가#
GitLab에 새로운 시스템 정의 작업 항목 유형을 추가하려면:
유형 구성, 위젯, 동작을 정의하는 정의 모듈을 생성합니다. (app/models/work_items/types_framework/system_defined/definitions/ 내)
애플리케이션 시작 시 로드되도록 WorkItems::TypesFramework::SystemDefined::Type에 정의를 포함합니다.
가시성 상수에 추가 - UI 및 API에서 유형이 표시되는 위치를 제어하는 프론트엔드 및 백엔드 상수에 기본 유형을 추가합니다.
구체적인 구현 세부 사항은 Slack의 #g_project-management에서 Plan Project Management 팀에 문의하세요.
다음 예시 MR들은 레거시 데이터베이스 기반 접근 방식을 사용하며 현재 구현을 반영하지 않을 수 있습니다. 시스템 정의 유형 추가에 대한 최신 지침은 Slack의 #g_project-management에서 Plan Project Management 팀에 문의하세요.
이전 참조 MR:
유형 관계 정의#
유형 관계 정의(예: 어떤 유형이 자식을 가질 수 있는지, 어떤 유형이 다른 유형과 연결될 수 있는지)는 유형 모듈 자체에 정의됩니다. 모든 구성은 한 곳에 있고 코드로 정의됩니다.
새 시스템 정의 유형을 만들 때 다음 정의를 유형 모듈에 포함하세요:
-
위젯 구성 - 이 유형에 사용 가능한 위젯.
-
계층 제한 - 이 유형의 부모 또는 자식이 될 수 있는 유형 및 최대 중첩 깊이.
-
연결 항목 제한 - 이 유형이 관련되거나 차단될 수 있는 유형.
현재 관계 규칙은 app/models/work_items/types_framework/system_defined/definitions/의 개별 유형 정의 모듈을 참조하세요.
커스텀 위젯#
최종 목표는 사용자가 커스텀 위젯을 정의하고 이 커스텀 위젯을 어떤 WIT에서든 사용할 수 있도록 하는 것입니다. 하지만 이는 훨씬 이후의 반복이며 사용할 데이터 및 애플리케이션 아키텍처를 결정하기 위한 추가 조사가 필요합니다.
요구사항 및 에픽을 작업 항목 유형으로 마이그레이션#
요구사항과 에픽을 자체 위젯 세트와 함께 작업 항목 유형으로 마이그레이션할 것입니다.
이를 위해 데이터를 issues 테이블로 마이그레이션하고, 이미 존재하는 참조와의 하위 호환성을 보장하기 위해
현재 requirements 및 epics 테이블을 이전 참조에 대한 프록시로 유지합니다.
요구사항을 작업 항목 유형으로 마이그레이션#
현재 Requirement 속성은 Issue 속성의 하위 집합이므로 마이그레이션은 주로 다음으로 구성됩니다:
-
데이터 마이그레이션.
-
API 수준에서 하위 호환성 유지.
-
기존 참조가 계속 작동하도록 보장.
다른 기반 데이터 구조로의 마이그레이션은 최종 사용자에게 투명하게 이루어져야 합니다.
에픽을 작업 항목 유형으로 마이그레이션#
Epic에는 Issue WIT가 현재 가지고 있지 않은 일부 추가 기능이 있습니다.
따라서 에픽을 작업 항목 유형으로 마이그레이션하려면 현재 Epic 객체와 WIT 간의 기능 동등성을 제공해야 합니다.
주요 누락 기능은 다음과 같습니다:
-
작업 항목을 그룹 수준으로 가져오기. 이는 그룹 및 프로젝트 통합 이니셔티브에 의존합니다.
-
계층 위젯: 작업 항목을 계층 구조로 구성하는 기능.
-
상속된 날짜 위젯.
이미 에픽을 사용하고 있는 사용자의 워크플로를 방해하지 않기 위해, 프로젝트 수준에서 에픽과 기능 동등성을
제공하는 Feature라는 새 WIT를 도입할 것입니다.
이를 그룹 및 프로젝트 통합 진행과 결합하면
사용자 워크플로를 최소한으로 방해하면서 에픽을 WIT로 원활하게 마이그레이션하는 경로를 제공하는 데 도움이 됩니다.
작업 항목 계측#
작업 항목 인터랙션은 GitLab 내부 이벤트 시스템을 사용하여 추적되며, 분석을 위해 Snowplow로 전달됩니다. 중앙화된 계측 아키텍처는 모든 작업 항목 유형과 인터랙션에 걸쳐 일관된 추적을 제공합니다.
아키텍처 개요#
계측 시스템은 세 가지 주요 컴포넌트로 구성됩니다:
graph LR accTitle: Work Items Instrumentation accDescr: Visualization of the flow between work item services and instrumentation. subgraph Services US[UpdateService] CS[CreateService] Other[Other Services] end
subgraph Instrumentation
TS[TrackingService]
EM[EventMappings]
EA[EventActions]
end
US -->|old_associations| TS
CS -->|explicit event| TS
Other -->|explicit event| TS
TS --> EM
EM --> EA
TS -->|track_internal_event| IE[Internal Events]
| 컴포넌트 | 목적 |
|---|---|
| EventActions | 모든 추적 가능한 이벤트 상수 정의 (예: work_item_create, work_item_title_update) |
| TrackingService | 추적을 위한 통합 진입점; 명시적 이벤트를 수신하거나 변경 사항에서 이벤트를 파생 |
| EventMappings | 속성 및 연관 변경에서 이벤트로의 선언적 매핑 |
이벤트 속성#
모든 작업 항목 이벤트에는 세분화를 위한 표준화된 속성이 포함됩니다:
| 속성 | 설명 |
|---|---|
| user | 작업을 수행하는 사용자 |
| namespace | 작업 항목을 포함하는 네임스페이스 |
| project | 작업 항목을 포함하는 프로젝트 (해당되는 경우) |
| label | 작업 항목 유형 이름 (예: Issue, Epic, Task) |
| property | 네임스페이스에서 사용자의 권한 |
통합 패턴#
명시적 이벤트 추적#
생성, 삭제, 복제와 같은 개별 작업의 경우 이벤트를 직접 전달합니다:
Gitlab::WorkItems::Instrumentation::TrackingService.new(
work_item: work_item,
current_user: current_user,
event: Gitlab::WorkItems::Instrumentation::EventActions::CREATE
).execute
파생 이벤트 추적#
여러 필드가 변경될 수 있는 업데이트의 경우, 이전 상태를 전달하고
EventMappings가 어떤 이벤트를 발생시킬지 결정하도록 합니다:
# In associations_before_update, capture state before changes
def associations_before_update(work_item)
super.merge(
confidential: work_item.confidential,
# ... other associations
)
end
# In after_update, track with old_associations
Gitlab::WorkItems::Instrumentation::TrackingService.new(
work_item: work_item,
current_user: current_user,
old_associations: old_associations
).execute
현재 이벤트#
추적 가능한 작업 항목 이벤트의 전체 목록은
EventActions를 참조하세요.
새 이벤트 추가#
새 작업 항목 이벤트를 추가하려면:
내부 이벤트 CLI를 사용하여 이벤트 및 메트릭을 정의합니다. 필요한 YAML 정의를 생성하려면 빠른 시작 가이드를 따르세요.
lib/gitlab/work_items/instrumentation/event_actions.rb에 이벤트 상수를 추가합니다:
NEW_ACTION = 'work_item_new_action'
ALL_EVENTS = [
# ... existing events
NEW_ACTION
].freeze
(업데이트에서 파생된 이벤트만 해당) lib/gitlab/work_items/instrumentation/event_mappings.rb에 매핑을 추가합니다:
속성 변경의 경우:
ATTRIBUTE_MAPPINGS = [
# ... existing mappings
{ event: EventActions::NEW_ACTION, key: 'attribute_name' }
].freeze
커스텀 비교 로직을 사용하는 연관 변경의 경우:
ASSOCIATION_MAPPINGS = [
# ... existing mappings
{
event: EventActions::NEW_ACTION,
key: :association_name,
compare: ->(old, new) { old != new }
}
].freeze
관련 서비스 클래스에서 추적 서비스를 호출합니다.
공유 예시를 사용하여 스펙을 추가합니다:
it_behaves_like 'tracks work item event', :work_item, :user, 'work_item_new_action'
YAML 정의가 준비된 후 새 이벤트 계측을 추가하는 최소 예시는 변경된 파일 5개와 +28줄만으로 두 가지 이벤트를 추가하는 MR !215447을 참조하세요.
관련 파일#
-
이벤트 상수:
event_actions.rb -
추적 서비스:
tracking_service.rb -
이벤트 매핑:
event_mappings.rb