Skip to content
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
9 changes: 9 additions & 0 deletions acceptance/acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ func TestIssues(t *testing.T) {
testscript.Run(t, testScriptParamsFor(tsEnv, "issue"))
}

func TestIssues2_0(t *testing.T) {
var tsEnv testScriptEnv
if err := tsEnv.fromEnv(); err != nil {
t.Fatal(err)
}

testscript.Run(t, testScriptParamsFor(tsEnv, "issues-2.0"))
}

func TestLabels(t *testing.T) {
var tsEnv testScriptEnv
if err := tsEnv.fromEnv(); err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private

# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING

# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING

cd $SCRIPT_NAME-$RANDOM_STRING

# Create an issue with --type
exec gh issue create --title 'with type' --body '' --type 'Bug'
stdout2env ISSUE_URL

# Confirm the type stuck
exec gh issue view $ISSUE_URL --json issueType --jq .issueType.name
stdout '^Bug$'

# Clear the type with --remove-type
exec gh issue edit $ISSUE_URL --remove-type
exec gh issue view $ISSUE_URL --json issueType --jq '.issueType // "null"'
stdout '^null$'

# Set the type back with --type
exec gh issue edit $ISSUE_URL --type 'Bug'
exec gh issue view $ISSUE_URL --json issueType --jq .issueType.name
stdout '^Bug$'
32 changes: 32 additions & 0 deletions acceptance/testdata/issues-2.0/issue-create-and-edit-parent.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private

# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING

# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING

cd $SCRIPT_NAME-$RANDOM_STRING

# Create the parent issue
exec gh issue create --title 'parent' --body ''
stdout2env PARENT_URL

# Create a child via --parent on create
exec gh issue create --title 'child via create' --body '' --parent $PARENT_URL
stdout2env CHILD_URL

# Confirm parent is set
exec gh issue view $CHILD_URL --json parent --jq .parent.url
stdout $PARENT_URL

# Clear the parent with --remove-parent
exec gh issue edit $CHILD_URL --remove-parent
exec gh issue view $CHILD_URL --json parent --jq '.parent // "null"'
stdout '^null$'

# Set the parent back with --parent on edit
exec gh issue edit $CHILD_URL --parent $PARENT_URL
exec gh issue view $CHILD_URL --json parent --jq .parent.url
stdout $PARENT_URL
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private

# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING

# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING

cd $SCRIPT_NAME-$RANDOM_STRING

# Create the two helper issues that the main issue will block / be blocked by
exec gh issue create --title 'blocker' --body ''
stdout2env BLOCKER_URL

exec gh issue create --title 'blocked' --body ''
stdout2env BLOCKED_URL

# Create the main issue with both relationships set on create
exec gh issue create --title 'main' --body '' --blocked-by $BLOCKER_URL --blocking $BLOCKED_URL
stdout2env MAIN_URL

# Confirm both relationships landed
exec gh issue view $MAIN_URL --json blockedBy --jq '.blockedBy.nodes[].url'
stdout $BLOCKER_URL

exec gh issue view $MAIN_URL --json blocking --jq '.blocking.nodes[].url'
stdout $BLOCKED_URL

# Add a second blocker / blocked via edit
exec gh issue create --title 'blocker 2' --body ''
stdout2env BLOCKER_2_URL

exec gh issue create --title 'blocked 2' --body ''
stdout2env BLOCKED_2_URL

exec gh issue edit $MAIN_URL --add-blocked-by $BLOCKER_2_URL --add-blocking $BLOCKED_2_URL

exec gh issue view $MAIN_URL --json blockedBy --jq '.blockedBy.totalCount'
stdout '^2$'

exec gh issue view $MAIN_URL --json blocking --jq '.blocking.totalCount'
stdout '^2$'

# Remove the original blocker / blocked
exec gh issue edit $MAIN_URL --remove-blocked-by $BLOCKER_URL --remove-blocking $BLOCKED_URL

exec gh issue view $MAIN_URL --json blockedBy --jq '.blockedBy.nodes[].title'
stdout '^blocker 2$'
! stdout '^blocker$'

exec gh issue view $MAIN_URL --json blocking --jq '.blocking.nodes[].title'
stdout '^blocked 2$'
! stdout '^blocked$'
35 changes: 35 additions & 0 deletions acceptance/testdata/issues-2.0/issue-edit-sub-issues.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private

# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING

# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING

cd $SCRIPT_NAME-$RANDOM_STRING

# Create three issues: parent A, parent B, candidate C
exec gh issue create --title 'parent A' --body ''
stdout2env PARENT_A_URL

exec gh issue create --title 'parent B' --body ''
stdout2env PARENT_B_URL

exec gh issue create --title 'candidate C' --body ''
stdout2env CANDIDATE_URL

# Add C as a sub-issue of A
exec gh issue edit $PARENT_A_URL --add-sub-issue $CANDIDATE_URL
exec gh issue view $CANDIDATE_URL --json parent --jq .parent.url
stdout $PARENT_A_URL

# Adding C as a sub-issue of B silently overwrites the existing parent
exec gh issue edit $PARENT_B_URL --add-sub-issue $CANDIDATE_URL
exec gh issue view $CANDIDATE_URL --json parent --jq .parent.url
stdout $PARENT_B_URL

# Removing the sub-issue from B drops the parent
exec gh issue edit $PARENT_B_URL --remove-sub-issue $CANDIDATE_URL
exec gh issue view $CANDIDATE_URL --json parent --jq '.parent // "null"'
stdout '^null$'
21 changes: 21 additions & 0 deletions acceptance/testdata/issues-2.0/issue-list-filter-by-type.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private

# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING

# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING

cd $SCRIPT_NAME-$RANDOM_STRING

# Create one Bug-typed issue and one untyped issue
exec gh issue create --title 'typed-bug' --body '' --type 'Bug'
exec gh issue create --title 'untyped' --body ''

sleep 3

# Filtering by type returns only the typed issue
exec gh issue list --type 'Bug'
stdout 'typed-bug'
! stdout 'untyped'
39 changes: 39 additions & 0 deletions acceptance/testdata/issues-2.0/issue-view-issues-2.0-fields.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Create a repository with a file so it has a default branch
exec gh repo create $ORG/$SCRIPT_NAME-$RANDOM_STRING --add-readme --private

# Defer repo cleanup
defer gh repo delete --yes $ORG/$SCRIPT_NAME-$RANDOM_STRING

# Clone the repo
exec gh repo clone $ORG/$SCRIPT_NAME-$RANDOM_STRING

cd $SCRIPT_NAME-$RANDOM_STRING

# Create a parent, a sub-issue, a blocker, and a blocked target
exec gh issue create --title 'parent' --body ''
stdout2env PARENT_URL

exec gh issue create --title 'sub' --body ''
stdout2env SUB_URL

exec gh issue create --title 'blocker' --body ''
stdout2env BLOCKER_URL

exec gh issue create --title 'blocked' --body ''
stdout2env BLOCKED_URL

# Create the main issue wired up to all four
exec gh issue create --title 'main' --body '' --type 'Bug' --parent $PARENT_URL --blocked-by $BLOCKER_URL --blocking $BLOCKED_URL
stdout2env MAIN_URL

# Attach the sub-issue
exec gh issue edit $MAIN_URL --add-sub-issue $SUB_URL

# Non-tty view should include all the new Issues 2.0 fields
exec gh issue view $MAIN_URL
stdout '^issue-type:\tBug$'
stdout '^parent:\t.+/.+#[0-9]+$'
stdout '^sub-issues:\t.+/.+#[0-9]+$'
stdout '^sub-issues-completed:\t0/1$'
stdout '^blocked-by:\t.+/.+#[0-9]+$'
stdout '^blocking:\t.+/.+#[0-9]+$'
65 changes: 65 additions & 0 deletions api/export_pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,71 @@ func (issue *Issue) ExportData(fields []string) map[string]interface{} {
})
}
data[f] = items
case "issueType":
data[f] = issue.IssueType
case "parent":
if issue.Parent != nil {
data[f] = map[string]interface{}{
"id": issue.Parent.ID,
"number": issue.Parent.Number,
"title": issue.Parent.Title,
"url": issue.Parent.URL,
"state": issue.Parent.State,
}
} else {
data[f] = nil
}
case "subIssues":
items := make([]map[string]interface{}, 0, len(issue.SubIssues.Nodes))
for _, n := range issue.SubIssues.Nodes {
items = append(items, map[string]interface{}{
"id": n.ID,
"number": n.Number,
"title": n.Title,
"url": n.URL,
"state": n.State,
})
}
data[f] = map[string]interface{}{
"nodes": items,
"totalCount": issue.SubIssues.TotalCount,
}
case "subIssuesSummary":
data[f] = map[string]interface{}{
"total": issue.SubIssuesSummary.Total,
"completed": issue.SubIssuesSummary.Completed,
"percentCompleted": issue.SubIssuesSummary.PercentCompleted,
}
case "blockedBy":
items := make([]map[string]interface{}, 0, len(issue.BlockedBy.Nodes))
for _, n := range issue.BlockedBy.Nodes {
items = append(items, map[string]interface{}{
"id": n.ID,
"number": n.Number,
"title": n.Title,
"url": n.URL,
"state": n.State,
})
}
data[f] = map[string]interface{}{
"nodes": items,
"totalCount": issue.BlockedBy.TotalCount,
}
case "blocking":
items := make([]map[string]interface{}, 0, len(issue.Blocking.Nodes))
for _, n := range issue.Blocking.Nodes {
items = append(items, map[string]interface{}{
"id": n.ID,
"number": n.Number,
"title": n.Title,
"url": n.URL,
"state": n.State,
})
}
data[f] = map[string]interface{}{
"nodes": items,
"totalCount": issue.Blocking.TotalCount,
}
default:
sf := fieldByName(v, f)
data[f] = sf.Interface()
Expand Down
Loading
Loading