Skip to content

Added the ability to edit the estimated hours of an issue #801

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
100 changes: 60 additions & 40 deletions internal/cmd/issue/edit/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,16 @@ func edit(cmd *cobra.Command, args []string) {
}

edr := jira.EditRequest{
ParentIssueKey: parent,
Summary: params.summary,
Body: body,
Priority: params.priority,
Labels: labels,
Components: components,
FixVersions: fixVersions,
AffectsVersions: affectsVersions,
CustomFields: params.customFields,
ParentIssueKey: parent,
Summary: params.summary,
Body: body,
Priority: params.priority,
Labels: labels,
OriginalEstimate: params.originalEstimate,
Components: components,
FixVersions: fixVersions,
AffectsVersions: affectsVersions,
CustomFields: params.customFields,
}
if configuredCustomFields, err := cmdcommon.GetConfiguredCustomFields(); err == nil {
cmdcommon.ValidateCustomFields(edr.CustomFields, configuredCustomFields)
Expand Down Expand Up @@ -194,11 +195,12 @@ func getAnswers(params *editParams, issue *jira.Issue) {
if len(ans.Metadata) > 0 {
qs := getMetadataQuestions(ans.Metadata, issue)
ans := struct {
Priority string
Labels string
Components string
FixVersions string
AffectsVersions string
Priority string
Labels string
OriginalEstimate string
Components string
FixVersions string
AffectsVersions string
}{}
err := survey.Ask(qs, &ans)
cmdutil.ExitIfError(err)
Expand All @@ -209,6 +211,9 @@ func getAnswers(params *editParams, issue *jira.Issue) {
if len(ans.Labels) > 0 {
params.labels = strings.Split(ans.Labels, ",")
}
if ans.OriginalEstimate != "" {
params.originalEstimate = ans.OriginalEstimate
}
if len(ans.Components) > 0 {
params.components = strings.Split(ans.Components, ",")
}
Expand Down Expand Up @@ -300,19 +305,20 @@ func (ec *editCmd) askQuestions(issue *jira.Issue, originalBody string) error {
}

type editParams struct {
issueKey string
parentIssueKey string
summary string
body string
priority string
assignee string
labels []string
components []string
fixVersions []string
affectsVersions []string
customFields map[string]string
noInput bool
debug bool
issueKey string
parentIssueKey string
summary string
body string
priority string
assignee string
labels []string
originalEstimate string
components []string
fixVersions []string
affectsVersions []string
customFields map[string]string
noInput bool
debug bool
}

func parseArgsAndFlags(flags query.FlagParser, args []string, project string) *editParams {
Expand All @@ -334,6 +340,9 @@ func parseArgsAndFlags(flags query.FlagParser, args []string, project string) *e
labels, err := flags.GetStringArray("label")
cmdutil.ExitIfError(err)

originalEstimate, err := flags.GetString("original-estimate")
cmdutil.ExitIfError(err)

components, err := flags.GetStringArray("component")
cmdutil.ExitIfError(err)

Expand All @@ -353,19 +362,20 @@ func parseArgsAndFlags(flags query.FlagParser, args []string, project string) *e
cmdutil.ExitIfError(err)

return &editParams{
issueKey: cmdutil.GetJiraIssueKey(project, args[0]),
parentIssueKey: parentIssueKey,
summary: summary,
body: body,
priority: priority,
assignee: assignee,
labels: labels,
components: components,
fixVersions: fixVersions,
affectsVersions: affectsVersions,
customFields: custom,
noInput: noInput,
debug: debug,
issueKey: cmdutil.GetJiraIssueKey(project, args[0]),
parentIssueKey: parentIssueKey,
summary: summary,
body: body,
priority: priority,
assignee: assignee,
labels: labels,
originalEstimate: originalEstimate,
components: components,
fixVersions: fixVersions,
affectsVersions: affectsVersions,
customFields: custom,
noInput: noInput,
debug: debug,
}
}

Expand Down Expand Up @@ -406,6 +416,15 @@ func getMetadataQuestions(meta []string, issue *jira.Issue) []*survey.Question {
Default: strings.Join(issue.Fields.Labels, ","),
},
})
case "OriginalEstimate":
qs = append(qs, &survey.Question{
Name: "originalestimate",
Prompt: &survey.Input{
Message: "Estimate",
Help: "Estimate in hours",
Default: issue.Fields.OriginalEstimate,
},
})
case "FixVersions":
qs = append(qs, &survey.Question{
Name: "fixversions",
Expand Down Expand Up @@ -441,6 +460,7 @@ func setFlags(cmd *cobra.Command) {
cmd.Flags().StringP("priority", "y", "", "Edit priority")
cmd.Flags().StringP("assignee", "a", "", "Edit assignee (email or display name)")
cmd.Flags().StringArrayP("label", "l", []string{}, "Append labels")
cmd.Flags().StringP("original-estimate", "e", "", "Original Estimate in hours")
cmd.Flags().StringArrayP("component", "C", []string{}, "Replace components")
cmd.Flags().StringArray("fix-version", []string{}, "Add/Append release info (fixVersions)")
cmd.Flags().StringArray("affects-version", []string{}, "Add/Append release info (affectsVersions)")
Expand Down
6 changes: 3 additions & 3 deletions internal/cmdcommon/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func GetMetadata() []*survey.Question {
Name: "metadata",
Prompt: &survey.MultiSelect{
Message: "What would you like to add?",
Options: []string{"Priority", "Components", "Labels", "FixVersions", "AffectsVersions"},
Options: []string{"Priority", "Components", "Labels", "OriginalEstimate", "FixVersions", "AffectsVersions"},
Copy link
Owner

@ankitpokhrel ankitpokhrel Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit seem to work fine but this will add OriginalEstimate for create command as well and we don't actually seem to process that. We'd need to fix original estimate in create flow.

},
},
}
Expand Down Expand Up @@ -248,13 +248,13 @@ func ValidateCustomFields(fields map[string]string, configuredFields []jira.Issu

fieldsMap := make(map[string]string)
for _, configured := range configuredFields {
identifier := strings.ReplaceAll(strings.ToLower(strings.TrimSpace(configured.Name)), " ", "-")
identifier := strings.ToLower(strings.TrimSpace(strings.ReplaceAll(configured.Name, " ", "-")))
fieldsMap[identifier] = configured.Name
}

invalidCustomFields := make([]string, 0, len(fields))
for key := range fields {
if _, ok := fieldsMap[key]; !ok {
if _, ok := fieldsMap[strings.ToLower(strings.TrimSpace(key))]; !ok {
invalidCustomFields = append(invalidCustomFields, key)
}
}
Expand Down
31 changes: 22 additions & 9 deletions pkg/jira/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ type EditResponse struct {
// EditRequest struct holds request data for edit request.
// Setting an Assignee requires an account ID.
type EditRequest struct {
IssueType string
ParentIssueKey string
Summary string
Body string
Priority string
Labels []string
Components []string
FixVersions []string
AffectsVersions []string
IssueType string
ParentIssueKey string
Summary string
Body string
Priority string
Labels []string
OriginalEstimate string
Components []string
FixVersions []string
AffectsVersions []string
// CustomFields holds all custom fields passed
// while editing the issue.
CustomFields map[string]string
Expand Down Expand Up @@ -84,6 +85,11 @@ type editFields struct {
Add string `json:"add,omitempty"`
Remove string `json:"remove,omitempty"`
} `json:"labels,omitempty"`
Timetracking []struct {
Edit struct {
OriginalEstimate string `json:"originalEstimate,omitempty"`
} `json:"edit,omitempty"`
} `json:"timetracking,omitempty"`
Components []struct {
Add *struct {
Name string `json:"name,omitempty"`
Expand Down Expand Up @@ -181,6 +187,13 @@ func getRequestDataForEdit(req *EditRequest) *editRequest {
}{{Set: struct {
Name string `json:"name,omitempty"`
}{Name: req.Priority}}},
Timetracking: []struct {
Edit struct {
OriginalEstimate string `json:"originalEstimate,omitempty"`
} `json:"edit,omitempty"`
}{{Edit: struct {
OriginalEstimate string `json:"originalEstimate,omitempty"`
}{OriginalEstimate: req.OriginalEstimate}}},
}}

if len(req.Labels) > 0 {
Expand Down
9 changes: 5 additions & 4 deletions pkg/jira/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ type Issue struct {

// IssueFields holds issue fields.
type IssueFields struct {
Summary string `json:"summary"`
Description interface{} `json:"description"` // string in v1/v2, adf.ADF in v3
Labels []string `json:"labels"`
Resolution struct {
Summary string `json:"summary"`
Description interface{} `json:"description"` // string in v1/v2, adf.ADF in v3
Labels []string `json:"labels"`
OriginalEstimate string `json:"originalEstimate"`
Resolution struct {
Name string `json:"name"`
} `json:"resolution"`
IssueType IssueType `json:"issueType"`
Expand Down