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

githubCreateIssue_fix #4151

Merged
merged 20 commits into from
Dec 15, 2022
Merged
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
3 changes: 2 additions & 1 deletion cmd/checkmarxExecuteScan.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ func (c *checkmarxExecuteScanUtilsBundle) Open(name string) (*os.File, error) {
}

func (c *checkmarxExecuteScanUtilsBundle) CreateIssue(ghCreateIssueOptions *piperGithub.CreateIssueOptions) error {
return piperGithub.CreateIssue(ghCreateIssueOptions)
_, err := piperGithub.CreateIssue(ghCreateIssueOptions)
return err
}

func (c *checkmarxExecuteScanUtilsBundle) GetIssueService() *github.IssuesService {
Expand Down
3 changes: 2 additions & 1 deletion cmd/fortifyExecuteScan.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ func (f *fortifyUtilsBundle) GetArtifact(buildTool, buildDescriptorFile string,
}

func (f *fortifyUtilsBundle) CreateIssue(ghCreateIssueOptions *piperGithub.CreateIssueOptions) error {
return piperGithub.CreateIssue(ghCreateIssueOptions)
_, err := piperGithub.CreateIssue(ghCreateIssueOptions)
return err
}

func (f *fortifyUtilsBundle) GetIssueService() *github.IssuesService {
Expand Down
74 changes: 58 additions & 16 deletions cmd/githubCreateIssue.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,71 @@ package cmd

import (
"fmt"
"io/ioutil"

"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/pkg/errors"

piperGithub "github.com/SAP/jenkins-library/pkg/github"
github "github.com/google/go-github/v45/github"
)

type githubCreateIssueUtils interface {
FileRead(string) ([]byte, error)
}

func githubCreateIssue(config githubCreateIssueOptions, telemetryData *telemetry.CustomData) {
err := runGithubCreateIssue(&config, telemetryData)
fileUtils := &piperutils.Files{}
options := piperGithub.CreateIssueOptions{}
err := runGithubCreateIssue(&config, telemetryData, &options, fileUtils, piperGithub.CreateIssue)
if err != nil {
log.Entry().WithError(err).Fatal("Failed to comment on issue")
}
}

func runGithubCreateIssue(config *githubCreateIssueOptions, _ *telemetry.CustomData) error {

options := piperGithub.CreateIssueOptions{}
err := transformConfig(config, &options, ioutil.ReadFile)
func runGithubCreateIssue(config *githubCreateIssueOptions, _ *telemetry.CustomData, options *piperGithub.CreateIssueOptions, utils githubCreateIssueUtils, createIssue func(*piperGithub.CreateIssueOptions) (*github.Issue, error)) error {
chunks, err := getBody(config, utils.FileRead)
if err != nil {
return err
}
transformConfig(config, options, chunks[0])
issue, err := createIssue(options)
if err != nil {
return err
}
if len(chunks) > 1 {
for _, v := range chunks[1:] {
options.Body = []byte(v)
options.Issue = issue
options.UpdateExisting = true
_, err = createIssue(options)
if err != nil {
return err
}
}
}
return nil
}

return piperGithub.CreateIssue(&options)
func getBody(config *githubCreateIssueOptions, readFile func(string) ([]byte, error)) ([]string, error) {
var bodyString []rune
if len(config.Body)+len(config.BodyFilePath) == 0 {
return nil, fmt.Errorf("either parameter `body` or parameter `bodyFilePath` is required")
}
if len(config.Body) == 0 {
issueContent, err := readFile(config.BodyFilePath)
if err != nil {
return nil, errors.Wrapf(err, "failed to read file '%v'", config.BodyFilePath)
}
bodyString = []rune(string(issueContent))
} else {
bodyString = []rune(config.Body)
}
return getChunks(bodyString, config.ChunkSize), nil
}

func transformConfig(config *githubCreateIssueOptions, options *piperGithub.CreateIssueOptions, readFile func(string) ([]byte, error)) error {
func transformConfig(config *githubCreateIssueOptions, options *piperGithub.CreateIssueOptions, body string) {
options.Token = config.Token
options.APIURL = config.APIURL
options.Owner = config.Owner
Expand All @@ -38,16 +75,21 @@ func transformConfig(config *githubCreateIssueOptions, options *piperGithub.Crea
options.Body = []byte(config.Body)
options.Assignees = config.Assignees
options.UpdateExisting = config.UpdateExisting
options.Body = []byte(body)
}

if len(config.Body)+len(config.BodyFilePath) == 0 {
return fmt.Errorf("either parameter `body` or parameter `bodyFilePath` is required")
func getChunks(value []rune, chunkSize int) []string {
chunks := []string{}
length := len(value)
if length == 0 {
return []string{""}
}
if len(config.Body) == 0 {
issueContent, err := readFile(config.BodyFilePath)
if err != nil {
return errors.Wrapf(err, "failed to read file '%v'", config.BodyFilePath)
for i := 0; i < length; i += chunkSize {
to := length
if to > i+chunkSize {
to = i + chunkSize
}
options.Body = issueContent
chunks = append(chunks, string(value[i:to]))
}
return nil
return chunks
}
11 changes: 11 additions & 0 deletions cmd/githubCreateIssue_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 70 additions & 11 deletions cmd/githubCreateIssue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,57 @@ package cmd
import (
"testing"

piperGithub "github.com/SAP/jenkins-library/pkg/github"
"github.com/SAP/jenkins-library/pkg/mock"

github "github.com/google/go-github/v45/github"
"github.com/stretchr/testify/assert"

piperGithub "github.com/SAP/jenkins-library/pkg/github"
)

func TestGetChunk(t *testing.T) {
tests := []struct {
name string
chunkSize int
largeString string
expectedChunks []string
}{
{
name: "large string",
largeString: `The quick
brown fox jumps
over
the lazy dog
`,
chunkSize: 12,
expectedChunks: []string{"The quick\nbr", "own fox jump", "s\nover\nthe l", "azy dog\n"},
},
{
name: "small string",
largeString: `small`,
chunkSize: 12,
expectedChunks: []string{"small"},
},
{
name: "exact size",
largeString: `exact size12`,
chunkSize: 12,
expectedChunks: []string{"exact size12"},
},
{
name: "empty string",
largeString: ``,
chunkSize: 12,
expectedChunks: []string{""},
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
chunks := getChunks([]rune(test.largeString), test.chunkSize)
assert.ElementsMatch(t, test.expectedChunks, chunks)
})
}
}

func TestTransformConfig(t *testing.T) {
t.Parallel()

Expand All @@ -22,22 +66,28 @@ func TestTransformConfig(t *testing.T) {
Body: "This is my test body",
Title: "This is my title",
Assignees: []string{"userIdOne", "userIdTwo"},
ChunkSize: 100,
}
options := piperGithub.CreateIssueOptions{}
resultChunks := []string{}
createIssue := func(options *piperGithub.CreateIssueOptions) (*github.Issue, error) {
resultChunks = append(resultChunks, string(options.Body))
return nil, nil
}

// test
err := transformConfig(&config, &options, filesMock.FileRead)
err := runGithubCreateIssue(&config, nil, &options, &filesMock, createIssue)

// assert
assert.NoError(t, err)
assert.Equal(t, config.Token, options.Token)
assert.Equal(t, config.APIURL, options.APIURL)
assert.Equal(t, config.Owner, options.Owner)
assert.Equal(t, config.Repository, options.Repository)
assert.Equal(t, []byte(config.Body), options.Body)
assert.Equal(t, config.Title, options.Title)
assert.Equal(t, config.Assignees, options.Assignees)
assert.Equal(t, config.UpdateExisting, options.UpdateExisting)
assert.ElementsMatch(t, resultChunks, []string{string(config.Body)})
})

t.Run("Success bodyFilePath", func(t *testing.T) {
Expand All @@ -50,32 +100,41 @@ func TestTransformConfig(t *testing.T) {
BodyFilePath: "test.md",
Title: "This is my title",
Assignees: []string{"userIdOne", "userIdTwo"},
ChunkSize: 100,
}
options := piperGithub.CreateIssueOptions{}

resultChunks := []string{}
createIssue := func(options *piperGithub.CreateIssueOptions) (*github.Issue, error) {
resultChunks = append(resultChunks, string(options.Body))
return nil, nil
}
// test
err := transformConfig(&config, &options, filesMock.FileRead)
err := runGithubCreateIssue(&config, nil, &options, &filesMock, createIssue)

// assert
assert.NoError(t, err)
assert.Equal(t, config.Token, options.Token)
assert.Equal(t, config.APIURL, options.APIURL)
assert.Equal(t, config.Owner, options.Owner)
assert.Equal(t, config.Repository, options.Repository)
assert.Equal(t, []byte("Test markdown"), options.Body)
assert.Equal(t, config.Title, options.Title)
assert.Equal(t, config.Assignees, options.Assignees)
assert.Equal(t, config.UpdateExisting, options.UpdateExisting)
assert.ElementsMatch(t, resultChunks, []string{"Test markdown"})
})

t.Run("Error - missing issue body", func(t *testing.T) {
// init
filesMock := mock.FilesMock{}
config := githubCreateIssueOptions{}
config := githubCreateIssueOptions{ChunkSize: 100}
options := piperGithub.CreateIssueOptions{}

resultChunks := []string{}
createIssue := func(options *piperGithub.CreateIssueOptions) (*github.Issue, error) {
resultChunks = append(resultChunks, string(options.Body))
return nil, nil
}
// test
err := transformConfig(&config, &options, filesMock.FileRead)
err := runGithubCreateIssue(&config, nil, &options, &filesMock, createIssue)

// assert
assert.EqualError(t, err, "either parameter `body` or parameter `bodyFilePath` is required")
Expand Down
Loading