Skip to content

Commit 92636f4

Browse files
authored
Added support for jira issue fields (#402)
* Added jira-issue-fields to attest jira command * Removed comment about Creator * Added test of jira fields
1 parent 0bf92fb commit 92636f4

File tree

5 files changed

+58
-13
lines changed

5 files changed

+58
-13
lines changed

cmd/kosli/attestJira.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ type JiraAttestationPayload struct {
2020

2121
type attestJiraOptions struct {
2222
*CommonAttestationOptions
23-
baseURL string
24-
username string
25-
apiToken string
26-
pat string
27-
assert bool
28-
payload JiraAttestationPayload
23+
baseURL string
24+
username string
25+
apiToken string
26+
pat string
27+
issueFields string
28+
assert bool
29+
payload JiraAttestationPayload
2930
}
3031

3132
const attestJiraShortDesc = `Report a jira attestation to an artifact or a trail in a Kosli flow. `
@@ -41,6 +42,11 @@ The attestation is reported in all cases, and its compliance status depends on r
4142
existing Jira issues.
4243
If you have wrong Jira credentials or wrong Jira-base-url it will be reported as non existing Jira issue.
4344
This is because Jira returns same 404 error code in all cases.
45+
46+
The ^--jira-issue-fields^ can be used to include fields from the jira issue. By default no fields
47+
are included. ^*all^ will give all fields. Using ^--jira-issue-fields "*all" --dry-run^ will give you
48+
the complete list so you can select the once you need. The issue fields uses the jira API that is documented here:
49+
https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-issueidorkey-get-request
4450
` + attestationBindingDesc + `
4551
4652
` + commitDescription
@@ -81,6 +87,18 @@ kosli attest jira \
8187
--api-token yourAPIToken \
8288
--org yourOrgName
8389
90+
# report a jira attestation about a trail and include jira issue summary, description and creator:
91+
kosli attest jira \
92+
--name yourAttestationName \
93+
--flow yourFlowName \
94+
--trail yourTrailName \
95+
--jira-base-url https://kosli.atlassian.net \
96+
--jira-username user@domain.com \
97+
--jira-api-token yourJiraAPIToken \
98+
--jira-issue-fields "summary,description,creator"
99+
--api-token yourAPIToken \
100+
--org yourOrgName
101+
84102
# report a jira attestation about an artifact which has not been reported yet in a trail:
85103
kosli attest jira \
86104
--name yourTemplateArtifactName.yourAttestationName \
@@ -184,6 +202,7 @@ func newAttestJiraCmd(out io.Writer) *cobra.Command {
184202
cmd.Flags().StringVar(&o.username, "jira-username", "", jiraUsernameFlag)
185203
cmd.Flags().StringVar(&o.apiToken, "jira-api-token", "", jiraAPITokenFlag)
186204
cmd.Flags().StringVar(&o.pat, "jira-pat", "", jiraPATFlag)
205+
cmd.Flags().StringVar(&o.issueFields, "jira-issue-fields", "", jiraIssueFieldFlag)
187206
cmd.Flags().BoolVar(&o.assert, "assert", false, attestationAssertFlag)
188207

189208
err := RequireFlags(cmd, []string{"flow", "trail", "name", "commit", "jira-base-url"})
@@ -226,7 +245,7 @@ func (o *attestJiraOptions) run(args []string) error {
226245
issueLog := ""
227246
issueFoundCount := 0
228247
for _, issueID := range issueIDs {
229-
result, err := jc.GetJiraIssueInfo(issueID)
248+
result, err := jc.GetJiraIssueInfo(issueID, o.issueFields)
230249
if err != nil {
231250
return err
232251
}

cmd/kosli/attestJira_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ func (suite *AttestJiraCommandTestSuite) TestAttestJiraCmd() {
161161
commitMessage: "EX-1 test commit",
162162
},
163163
},
164+
{
165+
name: "can attest jira against a trail with summary and description from jira issue fields",
166+
cmd: fmt.Sprintf(`attest jira --name bar
167+
--jira-base-url https://kosli-test.atlassian.net --jira-username tore@kosli.com
168+
--jira-issue-fields "summary,description"
169+
--repo-root %s %s`, suite.tmpDir, suite.defaultKosliArguments),
170+
golden: "jira attestation 'bar' is reported to trail: test-123\n",
171+
additionalConfig: jiraTestsAdditionalConfig{
172+
commitMessage: "EX-1 test commit",
173+
},
174+
},
164175
{
165176
name: "can attest jira against a trail when name is not found in the trail template",
166177
cmd: fmt.Sprintf(`attest jira --name additional

cmd/kosli/reportEvidenceCommitJira.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func (o *reportEvidenceCommitJiraOptions) run(args []string) error {
185185
issueLog := ""
186186
issueFoundCount := 0
187187
for _, issueID := range issueIDs {
188-
result, err := jc.GetJiraIssueInfo(issueID)
188+
result, err := jc.GetJiraIssueInfo(issueID, "")
189189
if err != nil {
190190
return err
191191
}

cmd/kosli/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ The ^.kosli_ignore^ will be treated as part of the artifact like any other file,
114114
jiraUsernameFlag = "Jira username (for Jira Cloud)"
115115
jiraAPITokenFlag = "Jira API token (for Jira Cloud)"
116116
jiraPATFlag = "Jira personal access token (for self-hosted Jira)"
117+
jiraIssueFieldFlag = "[optional] The comma separated list of fields to include from the Jira issue. Default no fields are included. '*all' will give all fields."
117118
envDescriptionFlag = "[optional] The environment description."
118119
flowDescriptionFlag = "[optional] The Kosli flow description."
119120
trailDescriptionFlag = "[optional] The Kosli trail description."

internal/jira/jira.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ type JiraConfig struct {
1515
}
1616

1717
type JiraIssueInfo struct {
18-
IssueID string `json:"issue_id"`
19-
IssueURL string `json:"issue_url"`
20-
IssueExists bool `json:"issue_exists"`
18+
IssueID string `json:"issue_id"`
19+
IssueURL string `json:"issue_url"`
20+
IssueExists bool `json:"issue_exists"`
21+
IssueFields *jira.IssueFields `json:"issue_fields,omitempty"`
2122
}
2223

2324
// NewJiraConfig returns a new JiraConfig
@@ -61,7 +62,7 @@ func (jc *JiraConfig) NewJiraClient() (*jira.Client, error) {
6162

6263
// GetJiraIssueInfo retrieve Jira issue information
6364
// if issue is not found, we still return a JiraIssueInfo object with IssueExists set to false
64-
func (jc *JiraConfig) GetJiraIssueInfo(issueID string) (*JiraIssueInfo, error) {
65+
func (jc *JiraConfig) GetJiraIssueInfo(issueID string, issueFields string) (*JiraIssueInfo, error) {
6566
result := &JiraIssueInfo{
6667
IssueID: issueID,
6768
IssueExists: false,
@@ -72,13 +73,26 @@ func (jc *JiraConfig) GetJiraIssueInfo(issueID string) (*JiraIssueInfo, error) {
7273
if err != nil {
7374
return result, err
7475
}
75-
issue, response, err := jiraClient.Issue.Get(issueID, nil)
76+
77+
// API will return all fields if the Fields is empty so we default to a non-existing field.
78+
// The user can use '*all' if they want all
79+
if issueFields == "" {
80+
issueFields = "non-existing-key-in-jira-fields"
81+
}
82+
queryOptions := jira.GetQueryOptions{
83+
Fields: issueFields,
84+
}
85+
86+
issue, response, err := jiraClient.Issue.Get(issueID, &queryOptions)
7687
if err != nil && response.StatusCode != http.StatusNotFound {
7788
return result, err
7889
}
7990

8091
if issue != nil {
8192
result.IssueExists = true
93+
if issue.Fields != nil {
94+
result.IssueFields = issue.Fields
95+
}
8296
}
8397
return result, nil
8498
}

0 commit comments

Comments
 (0)