1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

feat(githubCreateIssue): allow content via file (#2557)

This commit is contained in:
Oliver Nocon 2021-03-19 13:04:30 +01:00 committed by GitHub
parent 9b6a8cb3b6
commit 2b11c09a8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 107 additions and 16 deletions

View File

@ -2,6 +2,8 @@ package cmd
import (
"context"
"fmt"
"io/ioutil"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/telemetry"
@ -20,22 +22,37 @@ func githubCreateIssue(config githubCreateIssueOptions, telemetryData *telemetry
if err != nil {
log.Entry().WithError(err).Fatal("Failed to get GitHub client")
}
err = runGithubCreateIssue(ctx, &config, telemetryData, client.Issues)
err = runGithubCreateIssue(ctx, &config, telemetryData, client.Issues, ioutil.ReadFile)
if err != nil {
log.Entry().WithError(err).Fatal("Failed to comment on issue")
}
}
func runGithubCreateIssue(ctx context.Context, config *githubCreateIssueOptions, _ *telemetry.CustomData, ghCreateIssueService githubCreateIssueService) error {
func runGithubCreateIssue(ctx context.Context, config *githubCreateIssueOptions, _ *telemetry.CustomData, ghCreateIssueService githubCreateIssueService, readFile func(string) ([]byte, error)) error {
if len(config.Body)+len(config.BodyFilePath) == 0 {
return fmt.Errorf("either parameter `body` or parameter `bodyFilePath` is required")
}
issue := github.IssueRequest{
Body: &config.Body,
Title: &config.Title,
}
if len(config.Body) > 0 {
issue.Body = &config.Body
} else {
issueContent, err := readFile(config.BodyFilePath)
if err != nil {
return errors.Wrapf(err, "failed to read file '%v'", config.BodyFilePath)
}
body := string(issueContent)
issue.Body = &body
}
newIssue, resp, err := ghCreateIssueService.Create(ctx, config.Owner, config.Repository, &issue)
if err != nil {
log.Entry().Errorf("GitHub response code %v", resp.Status)
return errors.Wrap(err, "Error occurred when creating issue")
return errors.Wrap(err, "error occurred when creating issue")
}
log.Entry().Debugf("New issue created: %v", newIssue)

View File

@ -14,12 +14,13 @@ import (
)
type githubCreateIssueOptions struct {
APIURL string `json:"apiUrl,omitempty"`
Body string `json:"body,omitempty"`
Owner string `json:"owner,omitempty"`
Repository string `json:"repository,omitempty"`
Title string `json:"title,omitempty"`
Token string `json:"token,omitempty"`
APIURL string `json:"apiUrl,omitempty"`
Body string `json:"body,omitempty"`
BodyFilePath string `json:"bodyFilePath,omitempty"`
Owner string `json:"owner,omitempty"`
Repository string `json:"repository,omitempty"`
Title string `json:"title,omitempty"`
Token string `json:"token,omitempty"`
}
// GithubCreateIssueCommand Create a new GitHub issue.
@ -84,13 +85,13 @@ You will be able to use this step for example for regular jobs to report into yo
func addGithubCreateIssueFlags(cmd *cobra.Command, stepConfig *githubCreateIssueOptions) {
cmd.Flags().StringVar(&stepConfig.APIURL, "apiUrl", `https://api.github.com`, "Set the GitHub API url.")
cmd.Flags().StringVar(&stepConfig.Body, "body", os.Getenv("PIPER_body"), "Defines the content of the issue, e.g. using markdown syntax.")
cmd.Flags().StringVar(&stepConfig.BodyFilePath, "bodyFilePath", os.Getenv("PIPER_bodyFilePath"), "Defines the path to a file containing the markdown content for the issue. This can be used instead of [`body`](#body)")
cmd.Flags().StringVar(&stepConfig.Owner, "owner", os.Getenv("PIPER_owner"), "Name of the GitHub organization.")
cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Name of the GitHub repository.")
cmd.Flags().StringVar(&stepConfig.Title, "title", os.Getenv("PIPER_title"), "Defines the title for the Issue.")
cmd.Flags().StringVar(&stepConfig.Token, "token", os.Getenv("PIPER_token"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line.")
cmd.MarkFlagRequired("apiUrl")
cmd.MarkFlagRequired("body")
cmd.MarkFlagRequired("owner")
cmd.MarkFlagRequired("repository")
cmd.MarkFlagRequired("title")
@ -121,7 +122,15 @@ func githubCreateIssueMetadata() config.StepData {
ResourceRef: []config.ResourceReference{},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "string",
Mandatory: true,
Mandatory: false,
Aliases: []config.Alias{},
},
{
Name: "bodyFilePath",
ResourceRef: []config.ResourceReference{},
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
Type: "string",
Mandatory: false,
Aliases: []config.Alias{},
},
{

View File

@ -6,6 +6,8 @@ import (
"net/http"
"testing"
"github.com/SAP/jenkins-library/pkg/mock"
"github.com/google/go-github/v32/github"
"github.com/stretchr/testify/assert"
)
@ -40,6 +42,7 @@ func TestRunGithubCreateIssue(t *testing.T) {
t.Run("Success", func(t *testing.T) {
// init
filesMock := mock.FilesMock{}
ghCreateIssueService := ghCreateIssueMock{
issueID: 1,
}
@ -51,7 +54,7 @@ func TestRunGithubCreateIssue(t *testing.T) {
}
// test
err := runGithubCreateIssue(ctx, &config, nil, &ghCreateIssueService)
err := runGithubCreateIssue(ctx, &config, nil, &ghCreateIssueService, filesMock.FileRead)
// assert
assert.NoError(t, err)
@ -61,17 +64,73 @@ func TestRunGithubCreateIssue(t *testing.T) {
assert.Equal(t, config.Title, ghCreateIssueService.issue.GetTitle())
})
t.Run("Success - body from file", func(t *testing.T) {
// init
filesMock := mock.FilesMock{}
filesMock.AddFile("test.md", []byte("Test markdown"))
ghCreateIssueService := ghCreateIssueMock{
issueID: 1,
}
config := githubCreateIssueOptions{
Owner: "TEST",
Repository: "test",
BodyFilePath: "test.md",
Title: "This is my title",
}
// test
err := runGithubCreateIssue(ctx, &config, nil, &ghCreateIssueService, filesMock.FileRead)
// assert
assert.NoError(t, err)
assert.Equal(t, config.Owner, ghCreateIssueService.owner)
assert.Equal(t, config.Repository, ghCreateIssueService.repo)
assert.Equal(t, "Test markdown", ghCreateIssueService.issue.GetBody())
assert.Equal(t, config.Title, ghCreateIssueService.issue.GetTitle())
})
t.Run("Error", func(t *testing.T) {
// init
filesMock := mock.FilesMock{}
ghCreateIssueService := ghCreateIssueMock{
issueError: fmt.Errorf("error creating issue"),
}
config := githubCreateIssueOptions{
Body: "test content",
}
// test
err := runGithubCreateIssue(ctx, &config, nil, &ghCreateIssueService, filesMock.FileRead)
// assert
assert.EqualError(t, err, "error occurred when creating issue: error creating issue")
})
t.Run("Error - missing issue body", func(t *testing.T) {
// init
filesMock := mock.FilesMock{}
ghCreateIssueService := ghCreateIssueMock{}
config := githubCreateIssueOptions{}
// test
err := runGithubCreateIssue(ctx, &config, nil, &ghCreateIssueService)
err := runGithubCreateIssue(ctx, &config, nil, &ghCreateIssueService, filesMock.FileRead)
// assert
assert.EqualError(t, err, "Error occurred when creating issue: error creating issue")
assert.EqualError(t, err, "either parameter `body` or parameter `bodyFilePath` is required")
})
t.Run("Error - missing body file", func(t *testing.T) {
// init
filesMock := mock.FilesMock{}
ghCreateIssueService := ghCreateIssueMock{}
config := githubCreateIssueOptions{
BodyFilePath: "test.md",
}
// test
err := runGithubCreateIssue(ctx, &config, nil, &ghCreateIssueService, filesMock.FileRead)
// assert
assert.Contains(t, fmt.Sprint(err), "failed to read file 'test.md'")
})
}

View File

@ -31,7 +31,13 @@ spec:
- STAGES
- STEPS
type: string
mandatory: true
- name: bodyFilePath
description: Defines the path to a file containing the markdown content for the issue. This can be used instead of [`body`](#body)
scope:
- PARAMETERS
- STAGES
- STEPS
type: string
- name: owner
aliases:
- name: githubOrg