Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Added the Issue Archiving API #347

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
133 changes: 133 additions & 0 deletions jira/internal/issue_archive_impl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package internal

Check warning

Code scanning / Revive (reported by Codacy)

should have a package comment Warning

should have a package comment

import (
"context"
"fmt"
model "github.com/ctreminiom/go-atlassian/v2/pkg/infra/models"
"github.com/ctreminiom/go-atlassian/v2/service"
"github.com/ctreminiom/go-atlassian/v2/service/jira"
"net/http"
"path"
)

func NewIssueArchivalService(client service.Connector, version string) *IssueArchivalService {

Check warning

Code scanning / Revive (reported by Codacy)

exported function NewIssueArchivalService should have comment or be unexported Warning

exported function NewIssueArchivalService should have comment or be unexported
return &IssueArchivalService{
internalClient: &internalIssueArchivalImpl{c: client, version: version},
}
}

type IssueArchivalService struct {

Check warning

Code scanning / Revive (reported by Codacy)

exported type IssueArchivalService should have comment or be unexported Warning

exported type IssueArchivalService should have comment or be unexported
internalClient jira.ArchiveService
}

func (i *IssueArchivalService) Preserve(ctx context.Context, issueIdsOrKeys []string) (*model.IssueArchivalSyncResponseScheme, *model.ResponseScheme, error) {

Check warning

Code scanning / Revive (reported by Codacy)

exported method IssueArchivalService.Preserve should have comment or be unexported Warning

exported method IssueArchivalService.Preserve should have comment or be unexported

Check warning

Code scanning / Revive (reported by Codacy)

method parameter issueIdsOrKeys should be issueIDsOrKeys Warning

method parameter issueIdsOrKeys should be issueIDsOrKeys
return i.internalClient.Preserve(ctx, issueIdsOrKeys)
}

func (i *IssueArchivalService) PreserveByJQL(ctx context.Context, jql string) (string, *model.ResponseScheme, error) {

Check warning

Code scanning / Revive (reported by Codacy)

exported method IssueArchivalService.PreserveByJQL should have comment or be unexported Warning

exported method IssueArchivalService.PreserveByJQL should have comment or be unexported
return i.internalClient.PreserveByJQL(ctx, jql)
}

func (i *IssueArchivalService) Restore(ctx context.Context, issueIdsOrKeys []string) (*model.IssueArchivalSyncResponseScheme, *model.ResponseScheme, error) {

Check warning

Code scanning / Revive (reported by Codacy)

method parameter issueIdsOrKeys should be issueIDsOrKeys Warning

method parameter issueIdsOrKeys should be issueIDsOrKeys

Check warning

Code scanning / Revive (reported by Codacy)

exported method IssueArchivalService.Restore should have comment or be unexported Warning

exported method IssueArchivalService.Restore should have comment or be unexported
return i.internalClient.Restore(ctx, issueIdsOrKeys)
}

func (i *IssueArchivalService) Export(ctx context.Context, payload *model.IssueArchivalExportPayloadScheme) (string, *model.ResponseScheme, error) {

Check warning

Code scanning / Revive (reported by Codacy)

exported method IssueArchivalService.Export should have comment or be unexported Warning

exported method IssueArchivalService.Export should have comment or be unexported
return i.internalClient.Export(ctx, payload)
}

type internalIssueArchivalImpl struct {
c service.Connector
version string
}

func (i *internalIssueArchivalImpl) Preserve(ctx context.Context, issueIdsOrKeys []string) (result *model.IssueArchivalSyncResponseScheme, response *model.ResponseScheme, err error) {

Check warning

Code scanning / Revive (reported by Codacy)

method parameter issueIdsOrKeys should be issueIDsOrKeys Warning

method parameter issueIdsOrKeys should be issueIDsOrKeys

if len(issueIdsOrKeys) == 0 {
return nil, nil, model.ErrNoIssuesSlice
}

payload := make(map[string]interface{})
payload["issueIdsOrKeys"] = issueIdsOrKeys

endpoint := fmt.Sprintf("rest/api/%s/issue/archive", i.version)

request, err := i.c.NewRequest(ctx, http.MethodPut, endpoint, "", payload)
if err != nil {
return nil, nil, err
}

report := new(model.IssueArchivalSyncResponseScheme)
response, err = i.c.Call(request, report)
if err != nil {
return nil, response, err
}

return report, response, nil
}

func (i *internalIssueArchivalImpl) PreserveByJQL(ctx context.Context, jql string) (taskID string, response *model.ResponseScheme, err error) {

if jql == "" {
return "", nil, model.ErrNoJQL
}

payload := make(map[string]interface{})
payload["jql"] = jql

endpoint := fmt.Sprintf("rest/api/%s/issue/archive", i.version)

request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, "", payload)
if err != nil {
return "", nil, err
}

response, err = i.c.Call(request, nil)
if err != nil {
return "", response, err
}

return path.Base(response.Bytes.String()), response, nil
}

func (i *internalIssueArchivalImpl) Restore(ctx context.Context, issueIdsOrKeys []string) (result *model.IssueArchivalSyncResponseScheme, response *model.ResponseScheme, err error) {

Check warning

Code scanning / Revive (reported by Codacy)

method parameter issueIdsOrKeys should be issueIDsOrKeys Warning

method parameter issueIdsOrKeys should be issueIDsOrKeys

if len(issueIdsOrKeys) == 0 {
return nil, nil, model.ErrNoIssuesSlice
}

payload := make(map[string]interface{})
payload["issueIdsOrKeys"] = issueIdsOrKeys

endpoint := fmt.Sprintf("rest/api/%s/issue/unarchive", i.version)

request, err := i.c.NewRequest(ctx, http.MethodPut, endpoint, "", payload)
if err != nil {
return nil, nil, err
}

report := new(model.IssueArchivalSyncResponseScheme)
response, err = i.c.Call(request, report)
if err != nil {
return nil, response, err
}

return report, response, nil
}

func (i *internalIssueArchivalImpl) Export(ctx context.Context, payload *model.IssueArchivalExportPayloadScheme) (taskID string, response *model.ResponseScheme, err error) {

endpoint := fmt.Sprintf("rest/api/%s/issues/archive/export", i.version)

request, err := i.c.NewRequest(ctx, http.MethodPut, endpoint, "", payload)
if err != nil {
return "", nil, err
}

response, err = i.c.Call(request, nil)
if err != nil {
return "", response, err
}

return "", response, nil
}
4 changes: 4 additions & 0 deletions jira/v2/api_client_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ func New(httpClient common.HTTPClient, site string) (*Client, error) {
client.NotificationScheme = projectNotificationScheme
client.Team = internal.NewTeamService(client)

client.Archive = internal.NewIssueArchivalService(client, APIVersion)

return client, nil
}

Expand All @@ -423,6 +425,8 @@ type Client struct {
JQL *internal.JQLService
NotificationScheme *internal.NotificationSchemeService
Team *internal.TeamService

Archive *internal.IssueArchivalService
}

// NewRequest creates an API request.
Expand Down
4 changes: 4 additions & 0 deletions jira/v3/api_client_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@ func New(httpClient common.HTTPClient, site string) (*Client, error) {
client.NotificationScheme = projectNotificationScheme
client.Team = internal.NewTeamService(client)

client.Archival = internal.NewIssueArchivalService(client, APIVersion)

return client, nil
}

Expand All @@ -423,6 +425,8 @@ type Client struct {
JQL *internal.JQLService
NotificationScheme *internal.NotificationSchemeService
Team *internal.TeamService

Archival *internal.IssueArchivalService
}

// NewRequest creates an API request.
Expand Down
33 changes: 33 additions & 0 deletions pkg/infra/models/issue_archival.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package models

Check warning

Code scanning / Revive (reported by Codacy)

should have a package comment Warning

should have a package comment

type IssueArchivalSyncResponseScheme struct {

Check warning

Code scanning / Revive (reported by Codacy)

exported type IssueArchivalSyncResponseScheme should have comment or be unexported Warning

exported type IssueArchivalSyncResponseScheme should have comment or be unexported
Errors *IssueArchivalSyncErrorScheme `json:"errors"`
NumberOfIssuesUpdated int `json:"numberOfIssuesUpdated"`
}

type IssueArchivalSyncErrorScheme struct {

Check warning

Code scanning / Revive (reported by Codacy)

exported type IssueArchivalSyncErrorScheme should have comment or be unexported Warning

exported type IssueArchivalSyncErrorScheme should have comment or be unexported
IssueIsSubtask *IssueArchivalErrorScheme `json:"issueIsSubtask"`
IssuesInArchivedProjects *IssueArchivalErrorScheme `json:"issuesInArchivedProjects"`
IssuesInUnlicensedProjects *IssueArchivalErrorScheme `json:"issuesInUnlicensedProjects"`
IssuesNotFound *IssueArchivalErrorScheme `json:"issuesNotFound"`
UserDoesNotHavePermission *IssueArchivalErrorScheme `json:"userDoesNotHavePermission"`
}

type IssueArchivalErrorScheme struct {

Check warning

Code scanning / Revive (reported by Codacy)

exported type IssueArchivalErrorScheme should have comment or be unexported Warning

exported type IssueArchivalErrorScheme should have comment or be unexported
Count int `json:"count"`
IssueIdsOrKeys []string `json:"issueIdsOrKeys"`

Check warning

Code scanning / Revive (reported by Codacy)

struct field IssueIdsOrKeys should be IssueIDsOrKeys Warning

struct field IssueIdsOrKeys should be IssueIDsOrKeys
Message string `json:"message"`
}

type IssueArchivalExportPayloadScheme struct {

Check warning

Code scanning / Revive (reported by Codacy)

exported type IssueArchivalExportPayloadScheme should have comment or be unexported Warning

exported type IssueArchivalExportPayloadScheme should have comment or be unexported
ArchivedBy []string `json:"archivedBy"`
ArchivedDateRange *DateRangeFilterRequestScheme `json:"archivedDateRange,omitempty"`
IssueTypes []string `json:"issueTypes"`
Projects []string `json:"projects"`
Reporters []string `json:"reporters"`
}

type DateRangeFilterRequestScheme struct {

Check warning

Code scanning / Revive (reported by Codacy)

exported type DateRangeFilterRequestScheme should have comment or be unexported Warning

exported type DateRangeFilterRequestScheme should have comment or be unexported
DateAfter string `json:"dateAfter,omitempty"`
DateBefore string `json:"dateBefore,omitempty"`
}
79 changes: 79 additions & 0 deletions service/jira/archive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package jira

Check warning

Code scanning / Revive (reported by Codacy)

should have a package comment Warning

should have a package comment

import (
"context"
"github.com/ctreminiom/go-atlassian/v2/pkg/infra/models"
)

// ArchiveService provides methods to manage issue archival operations, including preserving, restoring, and exporting archived issues.
type ArchiveService interface {

// Preserve archives the given issues based on their issue IDs or keys.
//
// Parameters:
// - ctx: The context for controlling request lifecycle and deadlines.
// - issueIdsOrKeys: A list of issue IDs or keys to be archived.
//
// Returns:
// - result: A structure containing details of the archival synchronization process.
// - response: The HTTP response scheme for the request.
// - err: An error if the operation fails.
//
// Example Usage:
// result, response, err := issue.archive.Preserve(ctx, []string{"ISSUE-123", "ISSUE-456"})
//
// https://docs.go-atlassian.io/jira-software-cloud/application-roles#get-application-role
Preserve(ctx context.Context, issueIdsOrKeys []string) (result *models.IssueArchivalSyncResponseScheme, response *models.ResponseScheme, err error)

Check warning

Code scanning / Revive (reported by Codacy)

interface method parameter issueIdsOrKeys should be issueIDsOrKeys Warning

interface method parameter issueIdsOrKeys should be issueIDsOrKeys

// PreserveByJQL archives issues that match the provided JQL query.
//
// Parameters:
// - ctx: The context for request lifecycle management.
// - jql: The JQL query to select issues for archival.
//
// Returns:
// - taskID: A unique identifier for the asynchronous archival task.
// - response: The HTTP response scheme for the request.
// - err: An error if the operation fails.
//
// Example Usage:
// taskID, response, err := issue.Archive.PreserveByJQL(ctx, "project = ABC AND status = 'Resolved'")
//
// https://docs.go-atlassian.io/jira-software-cloud/application-roles#get-application-role
PreserveByJQL(ctx context.Context, jql string) (taskID string, response *models.ResponseScheme, err error)

// Restore brings back the given archived issues using their issue IDs or keys.
//
// Parameters:
// - ctx: The context for controlling request execution.
// - issueIdsOrKeys: A list of issue IDs or keys to be restored from the archive.
//
// Returns:
// - result: A structure containing details of the restoration process.
// - response: The HTTP response scheme for the request.
// - err: An error if the operation fails.
//
// Example Usage:
// result, response, err := issue.Archive.Restore(ctx, []string{"ISSUE-789"})
//
// https://docs.go-atlassian.io/jira-software-cloud/application-roles#get-application-role
Restore(ctx context.Context, issueIdsOrKeys []string) (result *models.IssueArchivalSyncResponseScheme, response *models.ResponseScheme, err error)

Check warning

Code scanning / Revive (reported by Codacy)

interface method parameter issueIdsOrKeys should be issueIDsOrKeys Warning

interface method parameter issueIdsOrKeys should be issueIDsOrKeys

// Export generates an export of archived issues based on the provided payload.
//
// Parameters:
// - ctx: The context for controlling request execution.
// - payload: The export configuration, including filters and format specifications.
//
// Returns:
// - taskID: A unique identifier for the asynchronous export task.
// - response: The HTTP response scheme for the request.
// - err: An error if the operation fails.
//
// Example Usage:
// exportPayload := &models.IssueArchivalExportPayloadScheme{Format: "CSV", Fields: []string{"summary", "status"}}
// taskID, response, err := issue.Archive.Export(ctx, exportPayload)
//
// https://docs.go-atlassian.io/jira-software-cloud/application-roles#get-application-role
Export(ctx context.Context, payload *models.IssueArchivalExportPayloadScheme) (taskID string, response *models.ResponseScheme, err error)
}
Loading