Skip to content

Commit 20baa1b

Browse files
authoredMar 10, 2025··
✨ Added the Issue Archiving API (#347)
Resolves #339
1 parent 476814e commit 20baa1b

File tree

6 files changed

+749
-0
lines changed

6 files changed

+749
-0
lines changed
 

‎jira/internal/issue_archive_impl.go

+200
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
// Package internal jira/internal/issue_archive_impl.go
2+
package internal
3+
4+
import (
5+
"context"
6+
"fmt"
7+
model "github.com/ctreminiom/go-atlassian/v2/pkg/infra/models"
8+
"github.com/ctreminiom/go-atlassian/v2/service"
9+
"github.com/ctreminiom/go-atlassian/v2/service/jira"
10+
"net/http"
11+
"path"
12+
)
13+
14+
// NewIssueArchivalService creates a new instance of IssueArchivalService.
15+
// It initializes an internal client with the given service connector and API version,
16+
// which will be used to perform issue archival operations.
17+
//
18+
// Parameters:
19+
// - client: The service connector used to communicate with the underlying API.
20+
// - version: The API version to be used by the archival service.
21+
//
22+
// Returns:
23+
// - A pointer to an IssueArchivalService configured with the provided client and version.
24+
//
25+
// Example usage:
26+
//
27+
// client := myConnectorInstance // your implementation of service.Connector
28+
// version := "v3"
29+
// archiveService := NewIssueArchivalService(client, version)
30+
func NewIssueArchivalService(client service.Connector, version string) *IssueArchivalService {
31+
return &IssueArchivalService{
32+
internalClient: &internalIssueArchivalImpl{c: client, version: version},
33+
}
34+
}
35+
36+
// IssueArchivalService provides methods to manage issue archival operations, including preserving, restoring, and exporting archived issues.
37+
type IssueArchivalService struct {
38+
internalClient jira.ArchiveService
39+
}
40+
41+
// Preserve archives the given issues based on their issue IDs or keys.
42+
//
43+
// Parameters:
44+
// - ctx: The context for controlling request lifecycle and deadlines.
45+
// - issueIdsOrKeys: A list of issue IDs or keys to be archived.
46+
//
47+
// Returns:
48+
// - result: A structure containing details of the archival synchronization process.
49+
// - response: The HTTP response scheme for the request.
50+
// - err: An error if the operation fails.
51+
//
52+
// https://docs.go-atlassian.io/jira-software-cloud/issues/archiving#archive-issues-by-issue-id-key
53+
func (i *IssueArchivalService) Preserve(ctx context.Context, issueIDsOrKeys []string) (*model.IssueArchivalSyncResponseScheme, *model.ResponseScheme, error) {
54+
return i.internalClient.Preserve(ctx, issueIDsOrKeys)
55+
}
56+
57+
// PreserveByJQL archives issues that match the provided JQL query.
58+
//
59+
// Parameters:
60+
// - ctx: The context for request lifecycle management.
61+
// - jql: The JQL query to select issues for archival.
62+
//
63+
// Returns:
64+
// - taskID: A unique identifier for the asynchronous archival task.
65+
// - response: The HTTP response scheme for the request.
66+
// - err: An error if the operation fails.
67+
//
68+
// https://docs.go-atlassian.io/jira-software-cloud/issues/archiving#archive-issues-by-jql
69+
func (i *IssueArchivalService) PreserveByJQL(ctx context.Context, jql string) (string, *model.ResponseScheme, error) {
70+
return i.internalClient.PreserveByJQL(ctx, jql)
71+
}
72+
73+
// Restore brings back the given archived issues using their issue IDs or keys.
74+
//
75+
// Parameters:
76+
// - ctx: The context for controlling request execution.
77+
// - issueIdsOrKeys: A list of issue IDs or keys to be restored from the archive.
78+
//
79+
// Returns:
80+
// - result: A structure containing details of the restoration process.
81+
// - response: The HTTP response scheme for the request.
82+
// - err: An error if the operation fails.
83+
//
84+
// https://docs.go-atlassian.io/jira-software-cloud/issues/archiving#restore-issues-by-issue-id-key
85+
func (i *IssueArchivalService) Restore(ctx context.Context, issueIDsOrKeys []string) (*model.IssueArchivalSyncResponseScheme, *model.ResponseScheme, error) {
86+
return i.internalClient.Restore(ctx, issueIDsOrKeys)
87+
}
88+
89+
// Export generates an export of archived issues based on the provided payload.
90+
//
91+
// Parameters:
92+
// - ctx: The context for controlling request execution.
93+
// - payload: The export configuration, including filters and format specifications.
94+
//
95+
// Returns:
96+
// - taskID: A unique identifier for the asynchronous export task.
97+
// - response: The HTTP response scheme for the request.
98+
// - err: An error if the operation fails.
99+
//
100+
// https://docs.go-atlassian.io/jira-software-cloud/issues/archiving#export-archived-issues
101+
func (i *IssueArchivalService) Export(ctx context.Context, payload *model.IssueArchivalExportPayloadScheme) (*model.IssueArchiveExportResultScheme, *model.ResponseScheme, error) {
102+
return i.internalClient.Export(ctx, payload)
103+
}
104+
105+
type internalIssueArchivalImpl struct {
106+
c service.Connector
107+
version string
108+
}
109+
110+
func (i *internalIssueArchivalImpl) Preserve(ctx context.Context, issueIDsOrKeys []string) (result *model.IssueArchivalSyncResponseScheme, response *model.ResponseScheme, err error) {
111+
112+
if len(issueIDsOrKeys) == 0 {
113+
return nil, nil, model.ErrNoIssuesSlice
114+
}
115+
116+
payload := make(map[string]interface{})
117+
payload["issueIdsOrKeys"] = issueIDsOrKeys
118+
119+
endpoint := fmt.Sprintf("rest/api/%s/issue/archive", i.version)
120+
121+
request, err := i.c.NewRequest(ctx, http.MethodPut, endpoint, "", payload)
122+
if err != nil {
123+
return nil, nil, err
124+
}
125+
126+
report := new(model.IssueArchivalSyncResponseScheme)
127+
response, err = i.c.Call(request, report)
128+
if err != nil {
129+
return nil, response, err
130+
}
131+
132+
return report, response, nil
133+
}
134+
135+
func (i *internalIssueArchivalImpl) PreserveByJQL(ctx context.Context, jql string) (taskID string, response *model.ResponseScheme, err error) {
136+
137+
if jql == "" {
138+
return "", nil, model.ErrNoJQL
139+
}
140+
141+
payload := make(map[string]interface{})
142+
payload["jql"] = jql
143+
144+
endpoint := fmt.Sprintf("rest/api/%s/issue/archive", i.version)
145+
146+
request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, "", payload)
147+
if err != nil {
148+
return "", nil, err
149+
}
150+
151+
response, err = i.c.Call(request, nil)
152+
if err != nil {
153+
return "", response, err
154+
}
155+
156+
return path.Base(response.Bytes.String()), response, nil
157+
}
158+
159+
func (i *internalIssueArchivalImpl) Restore(ctx context.Context, issueIDsOrKeys []string) (result *model.IssueArchivalSyncResponseScheme, response *model.ResponseScheme, err error) {
160+
161+
if len(issueIDsOrKeys) == 0 {
162+
return nil, nil, model.ErrNoIssuesSlice
163+
}
164+
165+
payload := make(map[string]interface{})
166+
payload["issueIdsOrKeys"] = issueIDsOrKeys
167+
168+
endpoint := fmt.Sprintf("rest/api/%s/issue/unarchive", i.version)
169+
170+
request, err := i.c.NewRequest(ctx, http.MethodPut, endpoint, "", payload)
171+
if err != nil {
172+
return nil, nil, err
173+
}
174+
175+
report := new(model.IssueArchivalSyncResponseScheme)
176+
response, err = i.c.Call(request, report)
177+
if err != nil {
178+
return nil, response, err
179+
}
180+
181+
return report, response, nil
182+
}
183+
184+
func (i *internalIssueArchivalImpl) Export(ctx context.Context, payload *model.IssueArchivalExportPayloadScheme) (task *model.IssueArchiveExportResultScheme, response *model.ResponseScheme, err error) {
185+
186+
endpoint := fmt.Sprintf("rest/api/%s/issues/archive/export", i.version)
187+
188+
request, err := i.c.NewRequest(ctx, http.MethodPut, endpoint, "", payload)
189+
if err != nil {
190+
return nil, nil, err
191+
}
192+
193+
result := new(model.IssueArchiveExportResultScheme)
194+
response, err = i.c.Call(request, result)
195+
if err != nil {
196+
return nil, response, err
197+
}
198+
199+
return result, response, nil
200+
}
+426
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,426 @@
1+
package internal
2+
3+
import (
4+
"context"
5+
"errors"
6+
model "github.com/ctreminiom/go-atlassian/v2/pkg/infra/models"
7+
"github.com/ctreminiom/go-atlassian/v2/service"
8+
"github.com/ctreminiom/go-atlassian/v2/service/mocks"
9+
"github.com/stretchr/testify/assert"
10+
"net/http"
11+
"testing"
12+
)
13+
14+
func Test_internalIssueArchivalImpl_Preserve(t *testing.T) {
15+
16+
type fields struct {
17+
c service.Connector
18+
version string
19+
}
20+
type args struct {
21+
ctx context.Context
22+
issueIdsOrKeys []string
23+
}
24+
25+
tests := []struct {
26+
name string
27+
fields fields
28+
args args
29+
on func(*fields)
30+
wantErr bool
31+
Err error
32+
}{
33+
{
34+
name: "happy path - when the issue list is archived successfully",
35+
fields: fields{version: "2"},
36+
args: args{
37+
ctx: context.Background(),
38+
issueIdsOrKeys: []string{"KP-1"},
39+
},
40+
on: func(fields *fields) {
41+
42+
client := mocks.NewConnector(t)
43+
44+
client.On("NewRequest",
45+
context.Background(),
46+
http.MethodPut,
47+
"rest/api/2/issue/archive", "", map[string]interface{}{"issueIdsOrKeys": []string{"KP-1"}}).
48+
Return(&http.Request{}, nil)
49+
50+
client.On("Call",
51+
&http.Request{},
52+
&model.IssueArchivalSyncResponseScheme{}).
53+
Return(&model.ResponseScheme{}, nil)
54+
55+
fields.c = client
56+
},
57+
},
58+
59+
{
60+
name: "fail path - when the issue list is not provided",
61+
fields: fields{version: "2"},
62+
args: args{
63+
ctx: context.Background(),
64+
issueIdsOrKeys: nil,
65+
},
66+
wantErr: true,
67+
Err: model.ErrNoIssuesSlice,
68+
},
69+
70+
{
71+
name: "fail path - when the http request cannot be created",
72+
fields: fields{version: "2"},
73+
args: args{
74+
ctx: context.Background(),
75+
issueIdsOrKeys: []string{"KP-1"},
76+
},
77+
on: func(fields *fields) {
78+
79+
client := mocks.NewConnector(t)
80+
81+
client.On("NewRequest",
82+
context.Background(),
83+
http.MethodPut,
84+
"rest/api/2/issue/archive", "", map[string]interface{}{"issueIdsOrKeys": []string{"KP-1"}}).
85+
Return(&http.Request{}, errors.New("error, unable to create the http request"))
86+
fields.c = client
87+
},
88+
wantErr: true,
89+
Err: errors.New("error, unable to create the http request"),
90+
},
91+
}
92+
for _, tt := range tests {
93+
t.Run(tt.name, func(t *testing.T) {
94+
95+
if tt.on != nil {
96+
tt.on(&tt.fields)
97+
}
98+
99+
archiveService := NewIssueArchivalService(tt.fields.c, tt.fields.version)
100+
101+
gotResult, gotResponse, err := archiveService.internalClient.Preserve(tt.args.ctx, tt.args.issueIdsOrKeys)
102+
103+
if tt.wantErr {
104+
assert.Error(t, err)
105+
assert.EqualError(t, err, tt.Err.Error())
106+
return
107+
}
108+
109+
assert.NoError(t, err)
110+
assert.NotNil(t, gotResponse)
111+
assert.NotNil(t, gotResult)
112+
})
113+
}
114+
}
115+
116+
func Test_internalIssueArchivalImpl_PreserveByJQL(t *testing.T) {
117+
type fields struct {
118+
c service.Connector
119+
version string
120+
}
121+
type args struct {
122+
ctx context.Context
123+
jql string
124+
}
125+
126+
tests := []struct {
127+
name string
128+
fields fields
129+
args args
130+
on func(*fields)
131+
wantErr bool
132+
Err error
133+
}{
134+
{
135+
name: "happy path - when the issues are archived successfully",
136+
fields: fields{version: "2"},
137+
args: args{
138+
ctx: context.Background(),
139+
jql: "project = KP",
140+
},
141+
on: func(fields *fields) {
142+
143+
client := mocks.NewConnector(t)
144+
145+
client.On("NewRequest",
146+
context.Background(),
147+
http.MethodPost,
148+
"rest/api/2/issue/archive", "", map[string]interface{}{"jql": "project = KP"}).
149+
Return(&http.Request{}, nil)
150+
151+
client.On("Call",
152+
&http.Request{},
153+
nil).
154+
Return(&model.ResponseScheme{}, nil)
155+
156+
fields.c = client
157+
},
158+
},
159+
{
160+
name: "fail path - when the jql is not provided",
161+
fields: fields{version: "2"},
162+
args: args{
163+
ctx: context.Background(),
164+
jql: "",
165+
},
166+
wantErr: true,
167+
Err: model.ErrNoJQL,
168+
},
169+
{
170+
name: "fail path - when the http request cannot be created",
171+
fields: fields{version: "2"},
172+
args: args{
173+
ctx: context.Background(),
174+
jql: "project = KP",
175+
},
176+
on: func(fields *fields) {
177+
178+
client := mocks.NewConnector(t)
179+
180+
client.On("NewRequest",
181+
context.Background(),
182+
http.MethodPost,
183+
"rest/api/2/issue/archive", "", map[string]interface{}{"jql": "project = KP"}).
184+
Return(&http.Request{}, errors.New("error, unable to create the http request"))
185+
fields.c = client
186+
},
187+
wantErr: true,
188+
Err: errors.New("error, unable to create the http request"),
189+
},
190+
}
191+
for _, tt := range tests {
192+
t.Run(tt.name, func(t *testing.T) {
193+
194+
if tt.on != nil {
195+
tt.on(&tt.fields)
196+
}
197+
198+
archiveService := NewIssueArchivalService(tt.fields.c, tt.fields.version)
199+
200+
gotResult, gotResponse, err := archiveService.internalClient.PreserveByJQL(tt.args.ctx, tt.args.jql)
201+
202+
if tt.wantErr {
203+
assert.Error(t, err)
204+
assert.EqualError(t, err, tt.Err.Error())
205+
return
206+
}
207+
208+
assert.NoError(t, err)
209+
assert.NotNil(t, gotResponse)
210+
assert.NotNil(t, gotResult)
211+
})
212+
}
213+
}
214+
215+
func Test_internalIssueArchivalImpl_Restore(t *testing.T) {
216+
type fields struct {
217+
c service.Connector
218+
version string
219+
}
220+
type args struct {
221+
ctx context.Context
222+
issueIDsOrKeys []string
223+
}
224+
tests := []struct {
225+
name string
226+
fields fields
227+
args args
228+
on func(*fields)
229+
wantErr bool
230+
Err error
231+
}{
232+
{
233+
name: "happy path - when the issues are restored successfully",
234+
fields: fields{version: "2"},
235+
args: args{
236+
ctx: context.Background(),
237+
issueIDsOrKeys: []string{"KP-1"},
238+
},
239+
on: func(fields *fields) {
240+
241+
client := mocks.NewConnector(t)
242+
243+
client.On("NewRequest",
244+
context.Background(),
245+
http.MethodPut,
246+
"rest/api/2/issue/unarchive", "", map[string]interface{}{"issueIdsOrKeys": []string{"KP-1"}}).
247+
Return(&http.Request{}, nil)
248+
249+
client.On("Call",
250+
&http.Request{},
251+
&model.IssueArchivalSyncResponseScheme{}).
252+
Return(&model.ResponseScheme{}, nil)
253+
254+
fields.c = client
255+
},
256+
},
257+
{
258+
name: "fail path - when the issue list is not provided",
259+
fields: fields{version: "2"},
260+
args: args{
261+
ctx: context.Background(),
262+
issueIDsOrKeys: nil,
263+
},
264+
wantErr: true,
265+
Err: model.ErrNoIssuesSlice,
266+
},
267+
{
268+
name: "fail path - when the http request cannot be created",
269+
fields: fields{version: "2"},
270+
args: args{
271+
ctx: context.Background(),
272+
issueIDsOrKeys: []string{"KP-1"},
273+
},
274+
on: func(fields *fields) {
275+
276+
client := mocks.NewConnector(t)
277+
278+
client.On("NewRequest",
279+
context.Background(),
280+
http.MethodPut,
281+
"rest/api/2/issue/unarchive", "", map[string]interface{}{"issueIdsOrKeys": []string{"KP-1"}}).
282+
Return(&http.Request{}, errors.New("error, unable to create the http request"))
283+
fields.c = client
284+
},
285+
wantErr: true,
286+
Err: errors.New("error, unable to create the http request"),
287+
},
288+
}
289+
for _, tt := range tests {
290+
t.Run(tt.name, func(t *testing.T) {
291+
292+
if tt.on != nil {
293+
tt.on(&tt.fields)
294+
}
295+
296+
archiveService := NewIssueArchivalService(tt.fields.c, tt.fields.version)
297+
298+
gotResult, gotResponse, err := archiveService.internalClient.Restore(tt.args.ctx, tt.args.issueIDsOrKeys)
299+
300+
if tt.wantErr {
301+
assert.Error(t, err)
302+
assert.EqualError(t, err, tt.Err.Error())
303+
return
304+
}
305+
306+
assert.NoError(t, err)
307+
assert.NotNil(t, gotResponse)
308+
assert.NotNil(t, gotResult)
309+
310+
})
311+
}
312+
}
313+
314+
func Test_internalIssueArchivalImpl_Export(t *testing.T) {
315+
type fields struct {
316+
c service.Connector
317+
version string
318+
}
319+
type args struct {
320+
ctx context.Context
321+
payload *model.IssueArchivalExportPayloadScheme
322+
}
323+
tests := []struct {
324+
name string
325+
fields fields
326+
args args
327+
on func(*fields)
328+
wantErr bool
329+
Err error
330+
}{
331+
{
332+
name: "happy path - when the issues are exported successfully",
333+
fields: fields{version: "2"},
334+
args: args{
335+
ctx: context.Background(),
336+
payload: &model.IssueArchivalExportPayloadScheme{
337+
338+
ArchivedBy: []string{
339+
"uuid-sample",
340+
"uuid-sample",
341+
},
342+
ArchivedDateRange: &model.DateRangeFilterRequestScheme{
343+
DateAfter: "2023-01-01",
344+
DateBefore: "2023-01-12",
345+
},
346+
IssueTypes: []string{"Bug", "Story"},
347+
Projects: []string{"WORK"},
348+
Reporters: []string{"uuid-sample"},
349+
},
350+
},
351+
on: func(fields *fields) {
352+
353+
client := mocks.NewConnector(t)
354+
355+
client.On("NewRequest",
356+
context.Background(),
357+
http.MethodPut,
358+
"rest/api/2/issues/archive/export", "", &model.IssueArchivalExportPayloadScheme{
359+
360+
ArchivedBy: []string{
361+
"uuid-sample",
362+
"uuid-sample",
363+
},
364+
ArchivedDateRange: &model.DateRangeFilterRequestScheme{
365+
DateAfter: "2023-01-01",
366+
DateBefore: "2023-01-12",
367+
},
368+
IssueTypes: []string{"Bug", "Story"},
369+
Projects: []string{"WORK"},
370+
Reporters: []string{"uuid-sample"},
371+
}).
372+
Return(&http.Request{}, nil)
373+
374+
client.On("Call",
375+
&http.Request{},
376+
&model.IssueArchiveExportResultScheme{}).
377+
Return(&model.ResponseScheme{}, nil)
378+
379+
fields.c = client
380+
},
381+
},
382+
{
383+
name: "fail path - when the http request cannot be created",
384+
fields: fields{version: "2"},
385+
args: args{
386+
ctx: context.Background(),
387+
payload: &model.IssueArchivalExportPayloadScheme{},
388+
},
389+
on: func(fields *fields) {
390+
391+
client := mocks.NewConnector(t)
392+
393+
client.On("NewRequest",
394+
context.Background(),
395+
http.MethodPut,
396+
"rest/api/2/issues/archive/export", "", &model.IssueArchivalExportPayloadScheme{}).
397+
Return(&http.Request{}, errors.New("error, unable to create the http request"))
398+
fields.c = client
399+
},
400+
wantErr: true,
401+
Err: errors.New("error, unable to create the http request"),
402+
},
403+
}
404+
for _, tt := range tests {
405+
t.Run(tt.name, func(t *testing.T) {
406+
407+
if tt.on != nil {
408+
tt.on(&tt.fields)
409+
}
410+
411+
archiveService := NewIssueArchivalService(tt.fields.c, tt.fields.version)
412+
413+
gotResult, gotResponse, err := archiveService.internalClient.Export(tt.args.ctx, tt.args.payload)
414+
415+
if tt.wantErr {
416+
assert.Error(t, err)
417+
assert.EqualError(t, err, tt.Err.Error())
418+
return
419+
}
420+
421+
assert.NoError(t, err)
422+
assert.NotNil(t, gotResponse)
423+
assert.NotNil(t, gotResult)
424+
})
425+
}
426+
}

‎jira/v2/api_client_impl.go

+4
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ func New(httpClient common.HTTPClient, site string) (*Client, error) {
397397
client.NotificationScheme = projectNotificationScheme
398398
client.Team = internal.NewTeamService(client)
399399

400+
client.Archive = internal.NewIssueArchivalService(client, APIVersion)
401+
400402
return client, nil
401403
}
402404

@@ -423,6 +425,8 @@ type Client struct {
423425
JQL *internal.JQLService
424426
NotificationScheme *internal.NotificationSchemeService
425427
Team *internal.TeamService
428+
429+
Archive *internal.IssueArchivalService
426430
}
427431

428432
// NewRequest creates an API request.

‎jira/v3/api_client_impl.go

+4
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ func New(httpClient common.HTTPClient, site string) (*Client, error) {
397397
client.NotificationScheme = projectNotificationScheme
398398
client.Team = internal.NewTeamService(client)
399399

400+
client.Archival = internal.NewIssueArchivalService(client, APIVersion)
401+
400402
return client, nil
401403
}
402404

@@ -423,6 +425,8 @@ type Client struct {
423425
JQL *internal.JQLService
424426
NotificationScheme *internal.NotificationSchemeService
425427
Team *internal.TeamService
428+
429+
Archival *internal.IssueArchivalService
426430
}
427431

428432
// NewRequest creates an API request.

‎pkg/infra/models/issue_archival.go

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Package models provides the models for the issue archival service.
2+
package models
3+
4+
// IssueArchivalSyncResponseScheme represents the response from the issue archival synchronization operation.
5+
type IssueArchivalSyncResponseScheme struct {
6+
Errors *IssueArchivalSyncErrorScheme `json:"errors"`
7+
NumberOfIssuesUpdated int `json:"numberOfIssuesUpdated"`
8+
}
9+
10+
// IssueArchivalSyncErrorScheme represents the error details for the issue archival synchronization operation.
11+
type IssueArchivalSyncErrorScheme struct {
12+
IssueIsSubtask *IssueArchivalErrorScheme `json:"issueIsSubtask"`
13+
IssuesInArchivedProjects *IssueArchivalErrorScheme `json:"issuesInArchivedProjects"`
14+
IssuesInUnlicensedProjects *IssueArchivalErrorScheme `json:"issuesInUnlicensedProjects"`
15+
IssuesNotFound *IssueArchivalErrorScheme `json:"issuesNotFound"`
16+
UserDoesNotHavePermission *IssueArchivalErrorScheme `json:"userDoesNotHavePermission"`
17+
}
18+
19+
// IssueArchivalErrorScheme represents the error details for the issue archival operation.
20+
type IssueArchivalErrorScheme struct {
21+
Count int `json:"count"`
22+
IssueIDsOrKeys []string `json:"issueIdsOrKeys"`
23+
Message string `json:"message"`
24+
}
25+
26+
// IssueArchivalExportPayloadScheme represents the payload for the issue archival export operation.
27+
type IssueArchivalExportPayloadScheme struct {
28+
ArchivedBy []string `json:"archivedBy"`
29+
ArchivedDateRange *DateRangeFilterRequestScheme `json:"archivedDateRange,omitempty"`
30+
IssueTypes []string `json:"issueTypes"`
31+
Projects []string `json:"projects"`
32+
Reporters []string `json:"reporters"`
33+
}
34+
35+
// DateRangeFilterRequestScheme represents the date range filter for the issue archival export operation.
36+
type DateRangeFilterRequestScheme struct {
37+
DateAfter string `json:"dateAfter,omitempty"`
38+
DateBefore string `json:"dateBefore,omitempty"`
39+
}
40+
41+
// IssueArchiveExportResultScheme represents the result of an issue archival export operation.
42+
type IssueArchiveExportResultScheme struct {
43+
TaskID string `json:"taskId,omitempty"`
44+
Payload string `json:"payload,omitempty"`
45+
Progress int `json:"progress,omitempty"`
46+
SubmittedTime int64 `json:"submittedTime,omitempty"`
47+
Status string `json:"status,omitempty"`
48+
}

‎service/jira/archive.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Package jira ...
2+
package jira
3+
4+
import (
5+
"context"
6+
"github.com/ctreminiom/go-atlassian/v2/pkg/infra/models"
7+
)
8+
9+
// ArchiveService provides methods to manage issue archival operations, including preserving, restoring, and exporting archived issues.
10+
type ArchiveService interface {
11+
12+
// Preserve archives the given issues based on their issue IDs or keys.
13+
//
14+
// Parameters:
15+
// - ctx: The context for controlling request lifecycle and deadlines.
16+
// - issueIdsOrKeys: A list of issue IDs or keys to be archived.
17+
//
18+
// Returns:
19+
// - result: A structure containing details of the archival synchronization process.
20+
// - response: The HTTP response scheme for the request.
21+
// - err: An error if the operation fails.
22+
//
23+
// https://docs.go-atlassian.io/jira-software-cloud/issues/archiving#archive-issues-by-issue-id-key
24+
Preserve(ctx context.Context, issueIDsOrKeys []string) (result *models.IssueArchivalSyncResponseScheme, response *models.ResponseScheme, err error)
25+
26+
// PreserveByJQL archives issues that match the provided JQL query.
27+
//
28+
// Parameters:
29+
// - ctx: The context for request lifecycle management.
30+
// - jql: The JQL query to select issues for archival.
31+
//
32+
// Returns:
33+
// - taskID: A unique identifier for the asynchronous archival task.
34+
// - response: The HTTP response scheme for the request.
35+
// - err: An error if the operation fails.
36+
//
37+
// https://docs.go-atlassian.io/jira-software-cloud/issues/archiving#archive-issues-by-jql
38+
PreserveByJQL(ctx context.Context, jql string) (taskID string, response *models.ResponseScheme, err error)
39+
40+
// Restore brings back the given archived issues using their issue IDs or keys.
41+
//
42+
// Parameters:
43+
// - ctx: The context for controlling request execution.
44+
// - issueIdsOrKeys: A list of issue IDs or keys to be restored from the archive.
45+
//
46+
// Returns:
47+
// - result: A structure containing details of the restoration process.
48+
// - response: The HTTP response scheme for the request.
49+
// - err: An error if the operation fails.
50+
//
51+
// https://docs.go-atlassian.io/jira-software-cloud/issues/archiving#restore-issues-by-issue-id-key
52+
Restore(ctx context.Context, issueIDsOrKeys []string) (result *models.IssueArchivalSyncResponseScheme, response *models.ResponseScheme, err error)
53+
54+
// Export generates an export of archived issues based on the provided payload.
55+
//
56+
// Parameters:
57+
// - ctx: The context for controlling request execution.
58+
// - payload: The export configuration, including filters and format specifications.
59+
//
60+
// Returns:
61+
// - taskID: A unique identifier for the asynchronous export task.
62+
// - response: The HTTP response scheme for the request.
63+
// - err: An error if the operation fails.
64+
//
65+
// https://docs.go-atlassian.io/jira-software-cloud/issues/archiving#export-archived-issues
66+
Export(ctx context.Context, payload *models.IssueArchivalExportPayloadScheme) (task *models.IssueArchiveExportResultScheme, response *models.ResponseScheme, err error)
67+
}

0 commit comments

Comments
 (0)
Please sign in to comment.