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

feat: [CI-11708] - Extract multiple Issues #29

Merged
merged 12 commits into from
Nov 17, 2024
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ drone-jira
NOTES*
output.json
.vscode/
.idea/
27 changes: 15 additions & 12 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 @@ -101,18 +102,20 @@ func Exec(ctx context.Context, args Args) error {
WithField("environment Type", environmentType).
WithField("environment ID", environmentID)

//check if PLUGIN_ISSUEKEYS is provided
// check if PLUGIN_ISSUEKEYS is provided
if len(args.IssueKeys) > 0 {
logger.Debugln("Provided issue keys are :", args.IssueKeys)
issues = args.IssueKeys
} else {
// fallback to extracting from commit if no issue keys are passed
var issue string = extractIssue(args)
if issue == "" {
issues = extractIssues(args)
if len(issues) == 0 {
logger.Debugln("cannot find issue number")
return errors.New("failed to extract issue number")
}
issues = []string{issue} // add the single issue here for consistency
}
logger = logger.WithField("issues", strings.Join(issues, ","))
logger.Debugln("successfully extracted all issues")

commitMessage := args.Commit.Message
if len(commitMessage) > 255 {
Expand Down Expand Up @@ -195,7 +198,7 @@ func Exec(ctx context.Context, args Args) error {
// validation of arguments
if (args.ClientID == "" && args.ClientSecret == "") && (args.ConnnectKey == "") {
logger.Debugln("client id and secret are empty. specify the client id and secret or specify connect key")
return errors.New("No client id & secret or connect token & hostname provided")
return errors.New("noClientIdAndSecretOrConnectTokenAndHostnameProvided")
Ompragash marked this conversation as resolved.
Show resolved Hide resolved
}
// create tokens and deployments
if args.ClientID != "" && args.ClientSecret != "" {
Expand Down Expand Up @@ -302,7 +305,7 @@ func getOauthToken(args Args) (string, error) {
return "", err
}
if res.StatusCode > 299 {
return "", fmt.Errorf("Error code %d", res.StatusCode)
return "", fmt.Errorf("errorCode %d", res.StatusCode)
Ompragash marked this conversation as resolved.
Show resolved Hide resolved
}
output := map[string]interface{}{}
err = json.Unmarshal(out, &output)
Expand Down Expand Up @@ -356,7 +359,7 @@ func createDeployment(payload DeploymentPayload, cloudID, debug, oauthToken stri
logrus.WithField("status", res.Status).WithField("response", outString).Info("request complete")
}
if res.StatusCode > 299 {
return fmt.Errorf("Error code %d", res.StatusCode)
return fmt.Errorf("errorCode %d", res.StatusCode)
Ompragash marked this conversation as resolved.
Show resolved Hide resolved
}
return nil
}
Expand Down Expand Up @@ -387,7 +390,7 @@ func createConnectDeployment(payload DeploymentPayload, cloudID, debug, jwtToken
logrus.WithField("status", res.Status).WithField("response", outString).Info("request complete")
}
if res.StatusCode > 299 {
return fmt.Errorf("Error code %d", res.StatusCode)
return fmt.Errorf("errorCode %d", res.StatusCode)
Ompragash marked this conversation as resolved.
Show resolved Hide resolved
}
return nil
}
Expand Down Expand Up @@ -418,7 +421,7 @@ func createConnectBuild(payload BuildPayload, cloudID, debug, jwtToken string) e
logrus.WithField("status", res.Status).WithField("response", outString).Info("request complete")
}
if res.StatusCode > 299 {
return fmt.Errorf("Error code %d", res.StatusCode)
return fmt.Errorf("errorCode %d", res.StatusCode)
Ompragash marked this conversation as resolved.
Show resolved Hide resolved
}
return nil
}
Expand All @@ -428,12 +431,12 @@ func getCloudID(instance, cloudID string) (string, error) {

tenant, err := lookupTenant(instance)
if err != nil {
return "", fmt.Errorf("Cannot get cloudid from instance, %s", err)
return "", fmt.Errorf("cannotGetCloudIdFromInstance, %s", err)
Ompragash marked this conversation as resolved.
Show resolved Hide resolved
}
return tenant.ID, nil
}
if cloudID == "" {
return "", fmt.Errorf("cloud id is empty. specify the cloud id or instance name")
return "", fmt.Errorf("cloudIdIsEmptySpecifyTheCloudIdOrInstanceName")
Ompragash marked this conversation as resolved.
Show resolved Hide resolved
}
return cloudID, nil
}
Expand All @@ -447,7 +450,7 @@ func lookupTenant(tenant string) (*Tenant, error) {
}
defer res.Body.Close()
if res.StatusCode > 299 {
return nil, fmt.Errorf("Error code %d", res.StatusCode)
return nil, fmt.Errorf("errorCode %d", res.StatusCode)
Ompragash marked this conversation as resolved.
Show resolved Hide resolved
}
out := new(Tenant)
err = json.NewDecoder(res.Body).Decode(out)
Expand Down
40 changes: 30 additions & 10 deletions plugin/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ 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.Commit.Message,
args.PullRequest.Title,
args.Commit.Source,
args.Commit.Target,
args.Commit.Branch,
), -1)

return removeDuplicates(matches)
}

// helper function determines the pipeline state.
Expand Down Expand Up @@ -153,3 +155,21 @@ func toStateEnum(s string) string {
return "unknown"
}
}

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
}
93 changes: 72 additions & 21 deletions plugin/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,94 @@ package plugin

import "testing"

func TestExtractIssue(t *testing.T) {
// compareSlices checks if s2 is a subset of s1
func compareSlices(s1, s2 []string) bool {
// Special case: if both slices are empty, they're equal
if len(s1) == 0 && len(s2) == 0 {
return true
}

// If s2 is empty but s1 isn't, or s1 is shorter than s2, they can't match
if len(s2) == 0 || len(s1) < len(s2) {
return false
}

// For each possible starting position in s1
for i := 0; i <= len(s1)-len(s2); i++ {
allMatch := true
// Try to match all elements of s2 starting at position i
for j := 0; j < len(s2); j++ {
if s1[i+j] != s2[j] {
allMatch = false
break
}
}
if allMatch {
return true
}
}
return false
}

func TestExtractIssues(t *testing.T) {
tests := []struct {
name string
text string
want string
want []string
}{
{
name: "Single issue",
text: "TEST-1 this is a test",
want: "TEST-1",
want: []string{"TEST-1"},
},
{
text: "suffix [TEST-123]",
want: "TEST-123",
name: "Two issues in brackets",
text: "suffix [TEST-123] [TEST-234]",
want: []string{"TEST-123", "TEST-234"},
},
{
text: "[TEST-123] prefix",
want: "TEST-123",
name: "Two issues, one in prefix",
text: "[TEST-123] prefix [TEST-456]",
want: []string{"TEST-123", "TEST-456"},
},
{
text: "TEST-123 prefix",
want: "TEST-123",
name: "Multiple comma-separated issues",
text: "Multiple issues: TEST-123, TEST-234, TEST-456",
want: []string{"TEST-123", "TEST-234", "TEST-456"},
},
{
text: "feature/TEST-123",
want: "TEST-123",
name: "Mixed format issues",
text: "feature/TEST-123 [TEST-456] and [TEST-789]",
want: []string{"TEST-123", "TEST-456", "TEST-789"},
},
{
name: "Space-separated issues",
text: "TEST-123 TEST-456 TEST-789",
want: []string{"TEST-123", "TEST-456", "TEST-789"},
},
{
name: "No issues",
text: "no issue",
want: "",
want: []string{},
},
}
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)
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var args Args
args.Commit.Message = tt.text
args.Project = "TEST"

got := extractIssues(args)

if !compareSlices(got, tt.want) {
t.Logf("\n Test case '%s' FAILED", tt.name)
t.Errorf("\ngot: %v\nwant: %v", got, tt.want)
} else {
t.Logf("\n Test case '%s' PASSED", tt.name)
t.Logf("\ngot: %v\nwant: %v", got, tt.want)
}
})
}
}

Expand Down Expand Up @@ -89,7 +140,7 @@ func TestToEnvironmentId(t *testing.T) {
{
name: "Empty EnvironmentId",
args: Args{EnvironmentId: ""},
expectedOutput: "production", // Updated to match the default value of "production"
expectedOutput: "production", // Updated to match the default value of "production"
},
}

Expand Down Expand Up @@ -118,7 +169,7 @@ func TestToEnvironmentType(t *testing.T) {
{
name: "Empty EnvironmentType",
args: Args{EnvironmentType: ""},
expectedOutput: "production", // Updated to match the default value of "production"
expectedOutput: "production", // Updated to match the default value of "production"
},
}

Expand Down