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:
parent
9b6a8cb3b6
commit
2b11c09a8c
@ -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)
|
||||
|
||||
|
@ -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{},
|
||||
},
|
||||
{
|
||||
|
@ -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'")
|
||||
})
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user