Epic API를 Work Items로 마이그레이션
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
GitLab 17.2에서 에픽을 work item으로 도입했습니다. WorkItem GraphQL API: Epic GraphQL API는 GitLab 19.0에서 제거될 계획입니다. Work Item API는 위젯을 사용하여 건강 상태, 담당자, 계층 구조와 같은 에픽 속성을 표현합니다.
히스토리
- GitLab 17.2에서
work_item_epics라는 플래그와 함께 도입되었습니다. 기본적으로 비활성화되어 있습니다. 에픽의 새로운 모양이 활성화되어야 합니다. 베타로 도입되었습니다. - GitLab 17.4에서 GraphQL API를 사용하여 에픽 나열 기능이 도입되었습니다.
- GitLab 17.6에서 GitLab.com에 활성화되었습니다.
- GitLab 17.7에서 GitLab Self-Managed 및 GitLab Dedicated에서 기본적으로 활성화되었습니다.
- GitLab 18.1에서 일반 공급되었습니다. 기능 플래그
work_item_epics가 제거되었습니다.
GitLab 17.2에서 에픽을 work item으로 도입했습니다.
통합이 계속 작동하도록 하려면:
- Epic GraphQL API를 사용하는 경우 Epic GraphQL API가 제거되기 전에 Work Item API로 마이그레이션하세요.
- REST API를 사용하는 경우 계속 사용할 수 있지만 통합을 미래에 대비하기 위해 마이그레이션해야 합니다.
- 새 기능(담당자, 건강 상태, 다른 유형과의 연결된 항목 등)을 사용하려면
WorkItemGraphQL API를 사용해야 합니다.
API 상태#
REST API (/api/v4/)#
에픽용 REST API:
- 여전히 지원되지만 사용 중단(deprecated)되었습니다.
- 기존 엔드포인트에서 계속 작동합니다.
- 새 기능을 받지 않습니다.
- 제거 날짜가 정해져 있지 않지만 주요 릴리스에서 제거될 예정입니다.
GraphQL API#
WorkItem GraphQL API:
- 실험적(experimental)으로 표시되어 있습니다.
- 프로덕션 환경에서 사용됩니다.
- GitLab 19.0 이전에 일반 공급될 예정입니다.
- GitLab 19.0 이전에 실험적 상태를 졸업할 예정입니다.
Epic GraphQL API는 GitLab 19.0에서 제거될 계획입니다.
Work Item API로 마이그레이션#
Work Item API는 위젯을 사용하여 건강 상태, 담당자, 계층 구조와 같은 에픽 속성을 표현합니다.
GraphiQL 탐색기 설정#
다음 예시를 실행하려면 GraphiQL(기존 쿼리를 탐색할 수 있는 대화형 GraphQL API 탐색기)을 사용할 수 있습니다:
- GraphiQL 탐색기 도구를 열고:
- GitLab.com의 경우 https://gitlab.com/-/graphql-explorer로 이동합니다.
- GitLab Self-Managed의 경우
https://gitlab.example.com/-/graphql-explorer로 이동합니다.gitlab.example.com을 인스턴스 URL로 변경합니다.
- 예시에 나열된 쿼리를 GraphiQL 탐색기 도구의 왼쪽 창에 붙여넣습니다.
- Play를 선택합니다.
에픽 쿼리#
에픽 ID는 work item ID와 다르지만 IID(각 그룹에 대해 증가하는 ID)는 동일합니다.
예를 들어 /gitlab-org/-/epics/123의 에픽은 work item과 동일한 IID 123을 가집니다.
이전 (Epic API):
query Epics {
group(fullPath: "gitlab-org") {
epics {
nodes {
id
iid
title
}
}
}
}
응답 예시:
{
"data": {
"group": {
"epics": {
"nodes": [
{
"id": "gid://gitlab/Epic/2335843",
"iid": "15596",
"title": "First epic"
},
{
"id": "gid://gitlab/Epic/2335762",
"iid": "15595",
"title": "Second epic"
}
]
}
}
}
}
이후 (Work Item API):
query EpicsAsWorkItem {
group(fullPath: "gitlab-org") {
workItems(types: [EPIC]) {
nodes {
id
iid
title
}
}
}
}
응답 예시:
{
"data": {
"group": {
"workItems": {
"nodes": [
{
"id": "gid://gitlab/WorkItem/154888575",
"iid": "15596",
"title": "First epic"
},
{
"id": "gid://gitlab/WorkItem/154877868",
"iid": "15595",
"title": "Second epic"
}
]
}
}
}
}
에픽 생성#
이전 (Epic API):
mutation CreateEpic {
createEpic(input: { title: "New epic", groupPath: "gitlab-org" }) {
epic {
id
title
}
}
}
응답 예시:
{
"data": {
"createEpic": {
"epic": {
"id": "gid://gitlab/Epic/806",
"title": "New epic"
}
}
}
}
이후 (Work Item API):
에픽을 생성하려면:
-
네임스페이스의 에픽에 대한 work item 유형 ID(
workItemTypeId)를 가져옵니다.에픽의
workItemTypeId는 GitLab 인스턴스 또는 네임스페이스 간에 동일하다고 보장되지 않습니다. 기본 work item 유형에 동일한 ID를 보장하기 위한 작업은 epic 15272에서 추적됩니다.query WorkItemTypes { namespace(fullPath: "gitlab-org") { workItemTypes(name: EPIC) { nodes { id name } } } }응답 예시:
{ "data": { "namespace": { "workItemTypes": { "nodes": [ { // 는 네임스페이스 및 인스턴스에 따라 다릅니다 "id": "gid://gitlab/WorkItems::Type/", "name": "Epic" } ] } } } } -
해당 ID를 사용하여 에픽(유형
epic의 work item)을 생성합니다:mutation CreateWorkItemEpic { workItemCreate( input: { title: "New work item epic" namespacePath: "gitlab-org" workItemTypeId: "gid://gitlab/WorkItems::Type/" } ) { workItem { id title } } }응답 예시:
{ "data": { "workItemCreate": { "workItem": { "id": "gid://gitlab/WorkItem/2243", "title": "New work item epic" } } } }
위젯#
Work Item API는 위젯 개념을 도입합니다. 위젯은 work item 유형의 특정 기능이나 속성을 나타냅니다. 건강 상태나 담당자와 같은 속성에서 날짜나 계층 구조까지 다양합니다. 각 work item 유형에는 고유한 사용 가능한 위젯 집합이 있습니다.
위젯으로 에픽 쿼리#
에픽에 대한 상세 정보를 검색하려면 GraphQL 쿼리에서 다양한 위젯을 사용할 수 있습니다. 다음 예시는 에픽의 다음 항목을 쿼리하는 방법을 보여줍니다:
- 계층 구조(상위/하위 관계)
- 담당자
- 이모지 반응
- 색상
- 건강 상태
- 시작 및 마감 날짜
사용 가능한 모든 위젯은 Work Item 위젯 참조를 참조하세요.
위젯으로 에픽을 쿼리하려면:
이전 (Epic API):
query DetailedEpicQuery {
group(fullPath: "gitlab-org") {
epic(iid: 1000) {
id
iid
title
confidential
author {
id
name
}
state
color
parent {
id
title
}
startDate
dueDate
ancestors {
nodes {
id
title
}
}
children {
nodes {
id
title
}
}
notes {
nodes {
body
createdAt
author {
name
}
}
}
}
}
}
응답 예시:
{
"data": {
"group": {
"epic": {
"id": "gid://gitlab/Epic/5579",
"iid": "1000",
"title": "Pajamas component: Pagination - Style",
"confidential": false,
"author": {
"id": "gid://gitlab/User/3079878",
"name": "Sidney Jones"
},
"state": "opened",
"color": "#1068bf",
"parent": {
"id": "gid://gitlab/Epic/5576",
"title": "Pajamas component: Pagination"
},
"startDate": null,
"dueDate": null,
"ancestors": {
"nodes": [
{
"id": "gid://gitlab/Epic/5523",
"title": "Components of Pajamas Design System"
},
{
"id": "gid://gitlab/Epic/5576",
"title": "Pajamas component: Pagination"
}
]
},
"children": {
"nodes": []
},
"notes": {
"nodes": [
{
"body": "changed the description",
"createdAt": "2019-04-02T17:03:05Z",
"author": {
"name": "Sidney Jones"
}
},
{
"body": "mentioned in epic &997",
"createdAt": "2019-04-26T15:45:49Z",
"author": {
"name": "Zhang Wei"
}
},
{
"body": "added issue gitlab-ui#302",
"createdAt": "2019-06-27T09:20:43Z",
"author": {
"name": "Alex Garcia"
}
},
{
"body": "added issue gitlab-ui#304",
"createdAt": "2019-06-27T09:20:43Z",
"author": {
"name": "Alex Garcia"
}
},
{
"body": "added issue gitlab-ui#316",
"createdAt": "2019-07-11T08:26:25Z",
"author": {
"name": "Alex Garcia"
}
},
{
"body": "mentioned in issue gitlab-design#528",
"createdAt": "2019-08-05T14:12:51Z",
"author": {
"name": "Jan Kowalski"
}
}
]
}
}
}
}
}
이후 (Work Item API):
query DetailedEpicWorkItem {
namespace(fullPath: "gitlab-org") {
workItem(iid: "10") {
id
title
confidential
author {
id
name
}
state
widgets {
... on WorkItemWidgetColor {
color
textColor
__typename
}
... on WorkItemWidgetHierarchy {
children {
nodes {
id
title
}
}
parent {
title
}
__typename
}
... on WorkItemWidgetHealthStatus {
type
healthStatus
}
... on WorkItemWidgetAssignees {
assignees {
nodes {
name
}
}
__typename
}
... on WorkItemWidgetAwardEmoji {
downvotes
upvotes
awardEmoji {
nodes {
unicode
}
}
__typename
}
... on WorkItemWidgetStartAndDueDate {
dueDate
isFixed
startDate
__typename
}
... on WorkItemWidgetNotes {
discussions {
nodes {
notes {
edges {
node {
body
id
author {
name
}
}
}
}
}
}
}
__typename
}
}
}
}
응답 예시:
{
"data": {
"namespace": {
"workItem": {
"id": "gid://gitlab/WorkItem/146171815",
"title": "Pajamas component: Pagination - Style",
"confidential": false,
"author": {
"id": "gid://gitlab/User/3079878",
"name": "Sidney Jones"
},
"state": "OPEN",
"widgets": [
{
"assignees": {
"nodes": []
},
"__typename": "WorkItemWidgetAssignees"
},
{
"__typename": "WorkItemWidgetDescription"
},
{
"children": {
"nodes": [
{
"id": "gid://gitlab/WorkItem/24697619",
"title": "Pagination does not conform with button styling and interaction styling"
},
{
"id": "gid://gitlab/WorkItem/22693964",
"title": "Remove next and previous labels on mobile and smaller viewports for pagination component"
},
{
"id": "gid://gitlab/WorkItem/22308883",
"title": "Update pagination border and background colors according to the specs"
},
{
"id": "gid://gitlab/WorkItem/22294339",
"title": "Pagination \"active\" page contains gray border on right side"
}
]
},
"parent": {
"title": "Pajamas component: Pagination"
},
"__typename": "WorkItemWidgetHierarchy"
},
{
"__typename": "WorkItemWidgetLabels"
},
{
"discussions": {
"nodes": [
{
"notes": {
"edges": [
{
"node": {
"body": "changed the description",
"id": "gid://gitlab/Note/156548315",
"author": {
"name": "Sidney Jones"
}
}
}
]
}
},
{
"notes": {
"edges": [
{
"node": {
"body": "added ~10161862 label",
"id": "gid://gitlab/LabelNote/853dc8176d8eff789269d69c31c019ecd9918996",
"author": {
"name": "Jan Kowalski"
}
}
}
]
}
},
{
"notes": {
"edges": [
{
"node": {
"body": "mentioned in epic &997",
"id": "gid://gitlab/Note/164703873",
"author": {
"name": "Zhang Wei"
}
}
}
]
}
},
{
"notes": {
"edges": [
{
"node": {
"body": "added issue gitlab-ui#302",
"id": "gid://gitlab/Note/185977331",
"author": {
"name": "Alex Garcia"
}
}
}
]
}
},
{
"notes": {
"edges": [
{
"node": {
"body": "added issue gitlab-ui#304",
"id": "gid://gitlab/Note/185977335",
"author": {
"name": "Alex Garcia"
}
}
}
]
}
},
{
"notes": {
"edges": [
{
"node": {
"body": "added issue gitlab-ui#316",
"id": "gid://gitlab/Note/190661279",
"author": {
"name": "Alex Garcia"
}
}
}
]
}
},
{
"notes": {
"edges": [
{
"node": {
"body": "mentioned in issue gitlab-design#528",
"id": "gid://gitlab/Note/200228415",
"author": {
"name": "Jan Kowalski"
}
}
}
]
}
},
{
"notes": {
"edges": [
{
"node": {
"body": "added ~8547186 ~10161725 labels and removed ~10161862 label",
"id": "gid://gitlab/LabelNote/dfa79f5c4e6650850cc9e767f0dc0d3896bfd0f9",
"author": {
"name": "Sidney Jones"
}
}
}
]
}
}
]
},
"__typename": "WorkItemWidgetNotes"
},
{
"dueDate": null,
"isFixed": false,
"startDate": null,
"__typename": "WorkItemWidgetStartAndDueDate"
},
{
"type": "HEALTH_STATUS",
"healthStatus": null,
"__typename": "WorkItemWidgetHealthStatus"
},
{
"__typename": "WorkItemWidgetVerificationStatus"
},
{
"__typename": "WorkItemWidgetNotifications"
},
{
"downvotes": 0,
"upvotes": 0,
"awardEmoji": {
"nodes": []
},
"__typename": "WorkItemWidgetAwardEmoji"
},
{
"__typename": "WorkItemWidgetLinkedItems"
},
{
"__typename": "WorkItemWidgetCurrentUserTodos"
},
{
"__typename": "WorkItemWidgetRolledupDates"
},
{
"__typename": "WorkItemWidgetParticipants"
},
{
"__typename": "WorkItemWidgetWeight"
},
{
"__typename": "WorkItemWidgetTimeTracking"
},
{
"color": "#1068bf",
"textColor": "#FFFFFF",
"__typename": "WorkItemWidgetColor"
}
]
}
}
}
}
위젯으로 work item 에픽 생성#
input 파라미터의 일부로 위젯을 사용하여 work item을 생성하거나 업데이트합니다.
예를 들어 다음 항목이 포함된 에픽을 생성하려면 아래 쿼리를 실행합니다:
- 제목
- 설명
- 색상
- 건강 상태
- 시작 날짜
- 마감 날짜
- 담당자
mutation createEpicWithWidgets {
workItemCreate(
input: {
title: "New work item epic"
namespacePath: "gitlab-org"
workItemTypeId: "gid://gitlab/WorkItems::Type/"
colorWidget: { color: "#e24329" }
descriptionWidget: { description: "My new plans ..." }
healthStatusWidget: { healthStatus: onTrack }
startAndDueDateWidget: { startDate: "2024-10-12", dueDate: "2024-12-12", isFixed: true }
assigneesWidget: { assigneeIds: "gid://gitlab/User/" }
}
) {
workItem {
id
title
description
widgets {
... on WorkItemWidgetColor {
color
textColor
__typename
}
... on WorkItemWidgetAssignees {
assignees {
nodes {
id
name
}
}
__typename
}
... on WorkItemWidgetHealthStatus {
healthStatus
__typename
}
... on WorkItemWidgetStartAndDueDate {
startDate
dueDate
isFixed
__typename
}
}
}
}
}
응답 예시:
{
"data": {
"workItemCreate": {
"workItem": {
"id": "gid://gitlab/WorkItem/2252",
"title": "New epic",
"description": "My new plans ...",
"widgets": [
{
"assignees": {
"nodes": [
{
"id": "gid://gitlab/User/46",
"name": "Jane Smith"
}
]
},
"__typename": "WorkItemWidgetAssignees"
},
{
"color": "#e24329",
"textColor": "#FFFFFF",
"__typename": "WorkItemWidgetColor"
},
{
"healthStatus": "onTrack",
"__typename": "WorkItemWidgetHealthStatus"
},
{
"startDate": "2024-10-12",
"dueDate": "2024-12-12",
"isFixed": true,
"__typename": "WorkItemWidgetStartAndDueDate"
}
]
}
}
}
}
위젯을 사용하여 work item 에픽 업데이트#
work item을 편집하려면 위젯으로 work item 에픽 생성의 위젯 입력을 재사용하되 workItemUpdate mutation을 대신 사용합니다.
work item의 전역 ID(형식 gid://gitlab/WorkItem/)를 가져와 input의 id로 사용합니다:
mutation updateEpicWorkItemWithWidgets {
workItemUpdate(
input: {
id: "gid://gitlab/WorkItem/"
title: "Updated work item epic title"
colorWidget: { color: "#fc6d26" }
descriptionWidget: { description: "My other new plans ..." }
healthStatusWidget: { healthStatus: onTrack }
startAndDueDateWidget: { startDate: "2025-10-12", dueDate: "2025-12-12", isFixed: true }
assigneesWidget: { assigneeIds: "gid://gitlab/User/45" }
}
) {
workItem {
id
title
description
widgets {
... on WorkItemWidgetColor {
color
textColor
__typename
}
... on WorkItemWidgetAssignees {
assignees {
nodes {
id
name
}
}
__typename
}
... on WorkItemWidgetHealthStatus {
healthStatus
__typename
}
... on WorkItemWidgetStartAndDueDate {
startDate
dueDate
isFixed
__typename
}
}
}
}
}
응답 예시:
{
"data": {
"workItemUpdate": {
"workItem": {
"id": "gid://gitlab/WorkItem/2252",
"title": "Updated work item epic title",
"description": "My other new plans ...",
"widgets": [
{
"assignees": {
"nodes": [
{
"id": "gid://gitlab/User/45",
"name": "Ardella Williamson"
}
]
},
"__typename": "WorkItemWidgetAssignees"
},
{
"color": "#fc6d26",
"textColor": "#FFFFFF",
"__typename": "WorkItemWidgetColor"
},
{
"healthStatus": "onTrack",
"__typename": "WorkItemWidgetHealthStatus"
},
{
"startDate": "2025-10-12",
"dueDate": "2025-12-12",
"isFixed": true,
"__typename": "WorkItemWidgetStartAndDueDate"
}
]
}
}
}
}
에픽 work item 삭제#
에픽 work item을 삭제하려면 workItemDelete mutation을 사용합니다:
mutation deleteEpicWorkItem {
workItemDelete(input: { id: "gid://gitlab/WorkItem/" }) {
clientMutationId
errors
namespace {
id
}
}
}
응답 예시:
{
"data": {
"workItemDelete": {
"clientMutationId": null,
"errors": [],
"namespace": {
"id": "gid://gitlab/Group/24"
}
}
}
}
