Merge branch 'trunk' into add-issue-create-editor

This commit is contained in:
Andy Feller 2024-07-15 15:21:03 -04:00 committed by GitHub
commit ae5a71bbe4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 141 additions and 9 deletions

View file

@ -299,7 +299,7 @@ jobs:
rpmsign --addsign dist/*.rpm
- name: Attest release artifacts
if: inputs.environment == 'production'
uses: actions/attest-build-provenance@bdd51370e0416ac948727f861e03c2f05d32d78e # v1.3.2
uses: actions/attest-build-provenance@5e9cb68e95676991667494a6a4e59b8a2f13e1d0 # v1.3.3
with:
subject-path: "dist/gh_*"
- name: Run createrepo

View file

@ -249,7 +249,7 @@ func RequiredStatusCheckRollupGraphQL(prID, after string, includeEvent bool) str
}`), afterClause, prID, eventField)
}
var IssueFields = []string{
var sharedIssuePRFields = []string{
"assignees",
"author",
"body",
@ -268,10 +268,20 @@ var IssueFields = []string{
"title",
"updatedAt",
"url",
}
// Some fields are only valid in the context of issues.
// They need to be enumerated separately in order to be filtered
// from existing code that expects to be able to pass Issue fields
// to PR queries, e.g. the PullRequestGraphql function.
var issueOnlyFields = []string{
"isPinned",
"stateReason",
}
var PullRequestFields = append(IssueFields,
var IssueFields = append(sharedIssuePRFields, issueOnlyFields...)
var PullRequestFields = append(sharedIssuePRFields,
"additions",
"autoMergeRequest",
"baseRefName",
@ -299,12 +309,6 @@ var PullRequestFields = append(IssueFields,
"statusCheckRollup",
)
// Some fields are only valid in the context of issues.
var issueOnlyFields = []string{
"isPinned",
"stateReason",
}
// IssueGraphQL constructs a GraphQL query fragment for a set of issue fields.
func IssueGraphQL(fields []string) string {
var q []string

View file

@ -16,11 +16,37 @@ import (
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/httpmock"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/cli/cli/v2/pkg/jsonfieldstest"
"github.com/cli/cli/v2/test"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
)
func TestJSONFields(t *testing.T) {
jsonfieldstest.ExpectCommandToSupportJSONFields(t, NewCmdView, []string{
"assignees",
"author",
"body",
"closed",
"comments",
"createdAt",
"closedAt",
"id",
"labels",
"milestone",
"number",
"projectCards",
"projectItems",
"reactionGroups",
"state",
"title",
"updatedAt",
"url",
"isPinned",
"stateReason",
})
}
func runCommand(rt http.RoundTripper, isTTY bool, cli string) (*test.CmdOut, error) {
ios, _, stdout, stderr := iostreams.Test()
ios.SetStdoutTTY(isTTY)

View file

@ -18,12 +18,61 @@ import (
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/httpmock"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/cli/cli/v2/pkg/jsonfieldstest"
"github.com/cli/cli/v2/test"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestJSONFields(t *testing.T) {
jsonfieldstest.ExpectCommandToSupportJSONFields(t, NewCmdView, []string{
"additions",
"assignees",
"author",
"autoMergeRequest",
"baseRefName",
"body",
"changedFiles",
"closed",
"closedAt",
"comments",
"commits",
"createdAt",
"deletions",
"files",
"headRefName",
"headRefOid",
"headRepository",
"headRepositoryOwner",
"id",
"isCrossRepository",
"isDraft",
"labels",
"latestReviews",
"maintainerCanModify",
"mergeCommit",
"mergeStateStatus",
"mergeable",
"mergedAt",
"mergedBy",
"milestone",
"number",
"potentialMergeCommit",
"projectCards",
"projectItems",
"reactionGroups",
"reviewDecision",
"reviewRequests",
"reviews",
"state",
"statusCheckRollup",
"title",
"updatedAt",
"url",
})
}
func Test_NewCmdView(t *testing.T) {
tests := []struct {
name string

View file

@ -88,6 +88,9 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
To create a remote repository non-interactively, supply the repository name and one of %[1]s--public%[1]s, %[1]s--private%[1]s, or %[1]s--internal%[1]s.
Pass %[1]s--clone%[1]s to clone the new repository locally.
If the %[1]sOWNER/%[1]s portion of the %[1]sOWNER/REPO%[1]s name argument is omitted, it
defaults to the name of the authenticating user.
To create a remote repository from an existing local repository, specify the source directory with %[1]s--source%[1]s.
By default, the remote repository name will be the name of the source directory.
Pass %[1]s--push%[1]s to push any local commits to the new repository.
@ -99,6 +102,9 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
# create a new remote repository and clone it locally
gh repo create my-project --public --clone
# create a new remote repository in a different organization
gh repo create my-org/my-project --public
# create a remote repository from the current directory
gh repo create my-project --private --source=. --remote=upstream
`),

View file

@ -0,0 +1,47 @@
package jsonfieldstest
import (
"strings"
"testing"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func jsonFieldsFor(cmd *cobra.Command) []string {
// This annotation is added by the `cmdutil.AddJSONFlags` function.
//
// This is an extremely janky way to get access to this information but due to the fact we pass
// around concrete cobra.Command structs, there's no viable way to have typed access to the fields.
//
// It's also kind of fragile because it's several hops away from the code that actually validates the usage
// of these flags, so it's possible for things to get out of sync.
stringFields, ok := cmd.Annotations["help:json-fields"]
if !ok {
return nil
}
return strings.Split(stringFields, ",")
}
// NewCmdFunc represents the typical function signature we use for creating commands e.g. `NewCmdView`.
//
// It is generic over `T` as each command construction has their own Options type e.g. `ViewOptions`
type NewCmdFunc[T any] func(f *cmdutil.Factory, runF func(*T) error) *cobra.Command
// ExpectCommandToSupportJSONFields asserts that the provided command supports exactly the provided fields.
// Ordering of the expected fields is not important.
//
// Make sure you are not pointing to the same slice of fields in the test and the implementation.
// It can be a little tedious to rewrite the fields inline in the test but it's significantly more useful because:
// - It forces the test author to think about and convey exactly the expected fields for a command
// - It avoids accidentally adding fields to a command, and the test passing unintentionally
func ExpectCommandToSupportJSONFields[T any](t *testing.T, fn NewCmdFunc[T], expectedFields []string) {
t.Helper()
actualFields := jsonFieldsFor(fn(&cmdutil.Factory{}, nil))
assert.Equal(t, len(actualFields), len(expectedFields), "expected number of fields to match")
require.ElementsMatch(t, expectedFields, actualFields)
}