Skip to content
This repository has been archived by the owner on Oct 29, 2024. It is now read-only.

feat: add Jira component #205

Merged
merged 29 commits into from
Jul 28, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
435e1b2
feat: add Jira component
YCK1130 Jul 8, 2024
a739ba5
feat: add list boards
YCK1130 Jul 9, 2024
3705e93
feat: add get issue and debug logger
YCK1130 Jul 9, 2024
b9fb7ea
fix: fix error check
YCK1130 Jul 9, 2024
eb2414f
feat: add get sprint
YCK1130 Jul 11, 2024
e713a77
fix: fix list boards bug
YCK1130 Jul 12, 2024
9c4f135
feat: add list issue task
YCK1130 Jul 12, 2024
d16dcbb
fix: fix advance search bug
YCK1130 Jul 15, 2024
8bb0730
fix: fix typo
YCK1130 Jul 15, 2024
56d4b3d
feat: add list board test
YCK1130 Jul 16, 2024
de03559
feat: add test for get issue and sprint
YCK1130 Jul 17, 2024
b49b636
feat: add test for list issue
YCK1130 Jul 17, 2024
61a3364
feat: add more test cases
YCK1130 Jul 17, 2024
5640d45
chore: silence the debug logger
YCK1130 Jul 17, 2024
43ed498
chore: fix typo and gen docs
YCK1130 Jul 17, 2024
945e48b
chore: fix typo
YCK1130 Jul 17, 2024
c2a3254
chore: remove irrelavent params
YCK1130 Jul 17, 2024
6eafef5
chore: format code
YCK1130 Jul 17, 2024
19b2efe
chore: update icon
YCK1130 Jul 17, 2024
e0ccbef
feat: add list standard issues
YCK1130 Jul 22, 2024
1d30636
feat: add list sprint
YCK1130 Jul 22, 2024
d19e2a9
feat: reoder list issue, add jql
YCK1130 Jul 22, 2024
c6bb84a
fix: testing problem
YCK1130 Jul 22, 2024
416bac4
chore: update readme
YCK1130 Jul 22, 2024
eed8d7e
chore: silence logger
YCK1130 Jul 22, 2024
2817bb1
chore: change params name for better clarity
YCK1130 Jul 23, 2024
bbcdf02
chore: improve list issue UX
YCK1130 Jul 24, 2024
31c22d1
fix: change link format
YCK1130 Jul 25, 2024
49638eb
Merge branch 'main' into YCK1130/jira-component
donch1989 Jul 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 186 additions & 0 deletions application/jira/v0/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
---
title: "Jira"
lang: "en-US"
draft: false
description: "Learn about how to set up a VDP Jira component https://github.com/instill-ai/instill-core"
---

The Jira component is an application component that allows users to do anything available on Jira.
It can carry out the following tasks:

- [List Boards](#list-boards)
- [List Issues](#list-issues)
- [List Sprints](#list-sprints)
- [Get Issue](#get-issue)
- [Get Sprint](#get-sprint)



## Release Stage

`Alpha`



## Configuration

The component configuration is defined and maintained [here](https://github.com/instill-ai/component/blob/main/application/jira/v0/config/definition.json).




## Setup


| Field | Field ID | Type | Note |
| :--- | :--- | :--- | :--- |
| Token (required) | `token` | string | Fill in your Jira API token. You can generate one from your Jira account "settings > security > API tokens". |
| Base URL (required) | `base-url` | string | Fill in your Jira base URL. For example, if your Jira URL is https://mycompany.atlassian.net, then your base URL is https://mycompany.atlassian.net. |
| Email (required) | `email` | string | Fill in your Jira email address. |




## Supported Tasks

### List Boards

List all boards in Jira


| Input | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| Task ID (required) | `task` | string | `TASK_LIST_BOARDS` |
| Project Key or ID | `project-key-or-id` | string | This filters results to boards that are relevant to a project. Relevance meaning that the JQL filter defined in board contains a reference to a project. |
| Board Type | `board-type` | string | The type of board, can be: scrum, kanban, simple. Default is simple |
| Name | `name` | string | Name filters results to boards that match or partially match the specified name. Default is empty |
| Start At | `start-at` | integer | The starting index of the returned boards. Base index: 0. Default is 0 |
| Max Results | `max-results` | integer | The maximum number of boards to return. Default is 50 |



| Output | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| Boards (optional) | `boards` | array[object] | A array of boards in Jira |
| Start At | `start-at` | integer | The starting index of the returned boards. Base index: 0 |
| Max Results | `max-results` | integer | The maximum number of boards |
| Total | `total` | integer | The total number of boards |
| Is Last | `is-last` | boolean | Whether the last board is reached |






### List Issues

List issues in Jira


| Input | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| Task ID (required) | `task` | string | `TASK_LIST_ISSUES` |
| Board ID (required) | `board-id` | integer | The ID of the board |
| Range | `range` | object | Choose the range of issues to return. Default is `all` |
| Start At | `start-at` | integer | The starting index of the returned boards. Base index: 0. Default is 0 |
| Max Results | `max-results` | integer | The maximum number of boards to return. Default is 50 |



| Output | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| Issues (optional) | `issues` | array[object] | A array of issues in Jira |
| Start At | `start-at` | integer | The starting index of the returned boards. Base index: 0 |
| Max Results | `max-results` | integer | The maximum number of boards |
| Total | `total` | integer | The total number of boards |






### List Sprints

List sprints in Jira


| Input | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| Task ID (required) | `task` | string | `TASK_LIST_SPRINTS` |
| Board ID (required) | `board-id` | integer | The ID of the board |
| Start At | `start-at` | integer | The starting index of the returned boards. Base index: 0. Default is 0 |
| Max Results | `max-results` | integer | The maximum number of boards to return. Default is 50 |



| Output | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| Sprints (optional) | `sprints` | array[object] | A array of sprints in Jira |
| Start At | `start-at` | integer | The starting index of the returned boards. Base index: 0 |
| Max Results | `max-results` | integer | The maximum number of boards |
| Total | `total` | integer | The total number of boards |






### Get Issue

Get an issue in Jira


| Input | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| Task ID (required) | `task` | string | `TASK_GET_ISSUE` |
| Issue ID or Key (required) | `issue-id-or-key` | string | The ID or key of the issue |
| Update History | `update-history` | boolean | Whether the project in which the issue is created is added to the user's Recently viewed project list, as shown under Projects in Jira. |



| Output | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| ID | `id` | string | The ID of the issue |
| Key | `key` | string | The key of the issue |
| Self | `self` | string | The URL of the issue |
| Fields | `fields` | object | The fields of the issue. All navigable and Agile fields are returned |
| Issue Type (optional) | `issue-type` | string | The type of the issue, can be: `Task`, `Epic` |
| Summary (optional) | `summary` | string | The summary of the issue |
| Description (optional) | `description` | string | The description of the issue |
| Status (optional) | `status` | string | The status of the issue, can be: `To Do`, `In Progress`, `Done` |






### Get Sprint

Get a sprint in Jira


| Input | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| Task ID (required) | `task` | string | `TASK_GET_SPRINT` |
| Sprint ID (required) | `sprint-id` | integer | The ID of the sprint. The sprint will only be returned if you can view the board that the sprint was created on, or view at least one of the issues in the sprint. |



| Output | ID | Type | Description |
| :--- | :--- | :--- | :--- |
| ID (optional) | `id` | integer | The ID of the sprint |
| Self (optional) | `self` | string | The URL of the sprint |
| State (optional) | `state` | string | The state of the sprint, can be: `active`, `closed`, `future` |
| Name (optional) | `name` | string | The name of the sprint |
| Start Date (optional) | `start-date` | string | The start date of the sprint. In the RFC3339 format, e.g. 2018-03-05T00:00:00Z |
| End Date (optional) | `end-date` | string | The end date of the sprint. In the RFC3339 format, e.g. 2018-03-05T00:00:00Z |
| Complete Date (optional) | `complete-date` | string | The complete date of the sprint. In the RFC3339 format, e.g. 2018-03-05T00:00:00Z |
| Origin Board ID (optional) | `origin-board-id` | integer | The ID of the origin board |
| Goal (optional) | `goal` | string | The Goal of the sprint |







15 changes: 15 additions & 0 deletions application/jira/v0/assets/jira.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
109 changes: 109 additions & 0 deletions application/jira/v0/boards.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package jira

import (
"context"
_ "embed"
"fmt"

"github.com/instill-ai/component/base"
"github.com/instill-ai/x/errmsg"
"google.golang.org/protobuf/types/known/structpb"
)

type Board struct {
ID int `json:"id"`
Name string `json:"name"`
Self string `json:"self"`
BoardType string `json:"type"`
}

type ListBoardsInput struct {
ProjectKeyOrID string `json:"project-key-or-id,omitempty" api:"projectKeyOrId"`
BoardType string `json:"board-type,omitempty" api:"type"`
Name string `json:"name,omitempty" api:"name"`
StartAt int `json:"start-at,omitempty" api:"startAt"`
MaxResults int `json:"max-results,omitempty" api:"maxResults"`
}
type ListBoardsResp struct {
Values []Board `json:"values"`
StartAt int `json:"startAt"`
MaxResults int `json:"maxResults"`
Total int `json:"total"`
IsLast bool `json:"isLast"`
}

type ListBoardsOutput struct {
Boards []Board `json:"boards"`
StartAt int `json:"start-at"`
MaxResults int `json:"max-results"`
Total int `json:"total"`
IsLast bool `json:"is-last"`
}

func (jiraClient *Client) listBoardsTask(ctx context.Context, props *structpb.Struct) (*structpb.Struct, error) {
var opt ListBoardsInput
if err := base.ConvertFromStructpb(props, &opt); err != nil {
return nil, err
}

boards, err := jiraClient.listBoards(ctx, &opt)
if err != nil {
return nil, err
}
var output ListBoardsOutput
output.Boards = append(output.Boards, boards.Values...)
if output.Boards == nil {
output.Boards = []Board{}
}
output.StartAt = boards.StartAt
output.MaxResults = boards.MaxResults
output.IsLast = boards.IsLast
output.Total = boards.Total
return base.ConvertToStructpb(output)
}

func (jiraClient *Client) listBoards(_ context.Context, opt *ListBoardsInput) (*ListBoardsResp, error) {
apiEndpoint := "rest/agile/1.0/board"

req := jiraClient.Client.R().SetResult(&ListBoardsResp{})
err := addQueryOptions(req, *opt)
if err != nil {
return nil, err
}
resp, err := req.Get(apiEndpoint)

if err != nil {
return nil, err
}
boards := resp.Result().(*ListBoardsResp)
return boards, err
}

type GetBoardResp struct {
Location struct {
DisplayName string `json:"displayName"`
Name string `json:"name"`
ProjectKey string `json:"projectKey"`
ProjectID int `json:"projectId"`
ProjectName string `json:"projectName"`
ProjectTypeKey string `json:"projectTypeKey"`
UserAccountID string `json:"userAccountId"`
UserID string `json:"userId"`
} `json:"location"`
Board
}

func (jiraClient *Client) getBoard(_ context.Context, boardID int) (*GetBoardResp, error) {
apiEndpoint := fmt.Sprintf("rest/agile/1.0/board/%v", boardID)

req := jiraClient.Client.R().SetResult(&GetBoardResp{})
resp, err := req.Get(apiEndpoint)
if err != nil {
return nil, fmt.Errorf(
err.Error(), errmsg.Message(err),
)
}
result := resp.Result().(*GetBoardResp)

return result, err
}
Loading
Loading