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

Extract multiple Jira issue keys #19

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

A plugin to attach build and deployment details to a Jira issue. For information on how to use the plugin with drone there is a video [here](https://youtu.be/YIKbLeY1-gI)

This plugin was modified to extract multiple issues by changing the extractIssues function and slight changes to the file plugin.go, also was added a new argument AdditionalMessage to serve as an input variable. The AdditionalMessage variable has the purpose to contain information of other issues.

The util_test.go file was changed to suit the modifications.

## Building

Build the plugin binary:
Expand Down Expand Up @@ -37,6 +41,7 @@ docker run --rm \
-e PLUGIN_PIPELINE=drone \
-e PLUGIN_ENVIRONMENT=production \
-e PLUGIN_STATE=successful \
-e PLUGIN_ADDITIONAL_MESSAGE="DRONE-43 updated the plugin" \
-w /drone/src \
-v $(pwd):/drone/src \
plugins/jira
Expand All @@ -53,4 +58,4 @@ docker run --rm \
- `ENVIRONMENT_NAME` Deployment environment (optional)
- `LINK` Link to deployment (optional)
- `STATE` State of the deployment (optional)
- `ADDITIONAL_MESSAGE` Additional message containing information about other issues (optional)
40 changes: 31 additions & 9 deletions plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"net/http"
"net/http/httputil"
"strconv"
"strings"
"time"

"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -67,13 +68,15 @@ type Args struct {

// connect hostname (required)
ConnectHostname string `envconfig:"PLUGIN_CONNECT_HOSTNAME"`

AdditionalMessage string `envconfig:"PLUGIN_ADDITIONAL_MESSAGE"`
}

// Exec executes the plugin.
func Exec(ctx context.Context, args Args) error {
var (
environ = toEnvironment(args)
issue = extractIssue(args)
issues = extractIssues(args)
state = toState(args)
version = toVersion(args)
deeplink = toLink(args)
Expand All @@ -89,13 +92,14 @@ func Exec(ctx context.Context, args Args) error {
WithField("state", state).
WithField("version", version)

if issue == "" {
logger.Debugln("cannot find issue number")
return errors.New("failed to extract issue number")
if len(issues) == 0 {
logger.Debugln("cannot find issues")
return errors.New("failed to extract issues")
}

logger = logger.WithField("issue", issue)
logger.Debugln("successfully extraced issue number")
issues = removeDuplicates(issues)
logger = logger.WithField("issues", strings.Join(issues, ","))
logger.Debugln("successfully extracted all issues")

deploymentPayload := DeploymentPayload{
Deployments: []*Deployment{
Expand All @@ -105,7 +109,7 @@ func Exec(ctx context.Context, args Args) error {
Associations: []Association{
{
Associationtype: "issueIdOrKeys",
Values: []string{issue},
Values: issues,
},
},
Displayname: strconv.Itoa(args.Build.Number),
Expand Down Expand Up @@ -135,7 +139,7 @@ func Exec(ctx context.Context, args Args) error {
URL: deeplink,
LastUpdated: time.Now(),
PipelineID: args.Name,
IssueKeys: []string{issue},
IssueKeys: issues,
State: state,
UpdateSequenceNumber: args.Build.Number,
},
Expand Down Expand Up @@ -198,7 +202,7 @@ func Exec(ctx context.Context, args Args) error {
}
}
// only create card if the state is successful
ticketLink := fmt.Sprintf("https://%s.atlassian.net/browse/%s", args.Instance, issue)
ticketLink := fmt.Sprintf("https://%s.atlassian.net/browse/%s", args.Instance, issues)
cardData := Card{
Pipeline: args.Name,
Instance: args.Instance,
Expand Down Expand Up @@ -394,3 +398,21 @@ func lookupTenant(tenant string) (*Tenant, error) {
err = json.NewDecoder(res.Body).Decode(out)
return out, err
}

func removeDuplicates(list []string) []string {
// Create an empty map to store seen elements
seen := make(map[string]bool)

// Initialize a new list to store unique elements
uniqueList := []string{}

for _, element := range list {
// Check if the element is already seen
if !seen[element] {
seen[element] = true
uniqueList = append(uniqueList, element)
}
}

return uniqueList
}
23 changes: 13 additions & 10 deletions plugin/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@ import (
// helper function to extract the issue number from
// the commit details, including the commit message,
// branch and pull request title.
func extractIssue(args Args) string {
return regexp.MustCompile(args.Project + "\\-\\d+").FindString(
fmt.Sprintln(
args.Commit.Message,
args.PullRequest.Title,
args.Commit.Source,
args.Commit.Target,
args.Commit.Branch,
),
)
func extractIssues(args Args) []string {

regex := regexp.MustCompile(args.Project+"-\\d+")
matches := regex.FindAllString(fmt.Sprintln(
args.AdditionalMessage,
args.Commit.Message,
args.PullRequest.Title,
args.Commit.Source,
args.Commit.Target,
args.Commit.Branch,
), -1)

return matches
}

// helper function determines the pipeline state.
Expand Down
107 changes: 69 additions & 38 deletions plugin/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,73 @@ package plugin

import "testing"

func TestExtractIssue(t *testing.T) {
tests := []struct {
text string
want string
}{
{
text: "TEST-1 this is a test",
want: "TEST-1",
},
{
text: "suffix [TEST-123]",
want: "TEST-123",
},
{
text: "[TEST-123] prefix",
want: "TEST-123",
},
{
text: "TEST-123 prefix",
want: "TEST-123",
},
{
text: "feature/TEST-123",
want: "TEST-123",
},
{
text: "no issue",
want: "",
},
}
for _, test := range tests {
var args Args
args.Commit.Message = test.text
args.Project = "TEST"
if got, want := extractIssue(args), test.want; got != want {
t.Errorf("Got issue number %v, want %v", got, want)
}
}
func compareSlices(s1, s2 []string) bool {
if len(s2) < 1 || len(s1) < len(s2){
return false
}

for i := 0; i < len(s1); i++ {
found := true
for j := 0; j < len(s2); j++ {
if s1[i+j] != s2[j] {
found = false
break
}
}
if found {
return true
}
}
return false
}

func TestExtractIssues(t *testing.T) {
tests := []struct {
text string
want []string
}{
{
text: "TEST-1 this is a test",
want: []string{"TEST-1"},
},
{
text: "suffix [TEST-123] [TEST-234]",
want: []string{"TEST-123", "TEST-234"},
},
{
text: "[TEST-123] prefix [TEST-456]",
want: []string{"TEST-123"},
},
{
text: "Multiple issues: TEST-123, TEST-234, TEST-456",
want: []string{"TEST-123", "TEST-234", "TEST-456"},
},
{
text: "feature/TEST-123 [TEST-456] and [TEST-789]",
want: []string{"TEST-123", "TEST-456", "TEST-789"},
},
{
text: "TEST-123 TEST-456 TEST-789",
want: []string{"TEST-123", "TEST-789"},
},
{
text: "no issue",
want: []string{},
},
}

t.Errorf("TESTING")

for _, test := range tests {
var args Args
args.Commit.Message = test.text
args.Project = "TEST"
got := extractIssues(args)
t.Errorf("TEXT:%v || WANT: %s", got, test.want)
t.Errorf(" %v", compareSlices(got, test.want))
if !compareSlices(got, test.want) {
t.Errorf("Got issues %v, want %v", got, test.want)
}
}

}