github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/github/create_issue.go (about)

     1  package github
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/SAP/jenkins-library/pkg/log"
     8  	"github.com/google/go-github/v45/github"
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  // CreateIssueOptions to configure the creation
    13  type CreateIssueOptions struct {
    14  	APIURL         string        `json:"apiUrl,omitempty"`
    15  	Assignees      []string      `json:"assignees,omitempty"`
    16  	Body           []byte        `json:"body,omitempty"`
    17  	Owner          string        `json:"owner,omitempty"`
    18  	Repository     string        `json:"repository,omitempty"`
    19  	Title          string        `json:"title,omitempty"`
    20  	UpdateExisting bool          `json:"updateExisting,omitempty"`
    21  	Token          string        `json:"token,omitempty"`
    22  	TrustedCerts   []string      `json:"trustedCerts,omitempty"`
    23  	Issue          *github.Issue `json:"issue,omitempty"`
    24  }
    25  
    26  func CreateIssue(options *CreateIssueOptions) (*github.Issue, error) {
    27  	ctx, client, err := NewClientBuilder(options.Token, options.APIURL).WithTrustedCerts(options.TrustedCerts).Build()
    28  	if err != nil {
    29  		return nil, errors.Wrap(err, "failed to get GitHub client")
    30  	}
    31  	return createIssueLocal(ctx, options, client.Issues, client.Search, client.Issues)
    32  }
    33  
    34  func createIssueLocal(
    35  	ctx context.Context,
    36  	options *CreateIssueOptions,
    37  	createIssueService githubCreateIssueService,
    38  	searchIssuesService githubSearchIssuesService,
    39  	createCommentService githubCreateCommentService,
    40  ) (*github.Issue, error) {
    41  	issue := github.IssueRequest{
    42  		Title: &options.Title,
    43  	}
    44  	var bodyString string
    45  	if len(options.Body) > 0 {
    46  		bodyString = string(options.Body)
    47  	} else {
    48  		bodyString = ""
    49  	}
    50  	issue.Body = &bodyString
    51  	if len(options.Assignees) > 0 {
    52  		issue.Assignees = &options.Assignees
    53  	} else {
    54  		issue.Assignees = &[]string{}
    55  	}
    56  
    57  	var existingIssue *github.Issue = nil
    58  
    59  	if options.UpdateExisting {
    60  		existingIssue = options.Issue
    61  		if existingIssue == nil {
    62  			queryString := fmt.Sprintf("is:open is:issue repo:%v/%v in:title %v", options.Owner, options.Repository, options.Title)
    63  			searchResult, resp, err := searchIssuesService.Issues(ctx, queryString, nil)
    64  			if err != nil {
    65  				if resp != nil {
    66  					log.Entry().Errorf("GitHub search issue returned response code %v", resp.Status)
    67  				}
    68  				return nil, errors.Wrap(err, "error occurred when looking for existing issue")
    69  			} else {
    70  				for _, value := range searchResult.Issues {
    71  					if value != nil && *value.Title == options.Title {
    72  						existingIssue = value
    73  					}
    74  				}
    75  			}
    76  		}
    77  
    78  		if existingIssue != nil {
    79  			comment := &github.IssueComment{Body: issue.Body}
    80  			_, resp, err := createCommentService.CreateComment(ctx, options.Owner, options.Repository, *existingIssue.Number, comment)
    81  			if err != nil {
    82  				if resp != nil {
    83  					log.Entry().Errorf("GitHub create comment returned response code %v", resp.Status)
    84  				}
    85  				return nil, errors.Wrap(err, "error occurred when adding comment to existing issue")
    86  			}
    87  		}
    88  	}
    89  
    90  	if existingIssue == nil {
    91  		newIssue, resp, err := createIssueService.Create(ctx, options.Owner, options.Repository, &issue)
    92  		if err != nil {
    93  			if resp != nil {
    94  				log.Entry().Errorf("GitHub create issue returned response code %v", resp.Status)
    95  			}
    96  			return nil, errors.Wrap(err, "error occurred when creating issue")
    97  		}
    98  		log.Entry().Debugf("New issue created: %v", newIssue)
    99  		existingIssue = newIssue
   100  	}
   101  
   102  	return existingIssue, nil
   103  }