Thanks to visit codestin.com
Credit goes to github.com

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
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Set up env vars
env REPO=${SCRIPT_NAME}-${RANDOM_STRING}

# Use gh as a credential helper
exec gh auth setup-git

# Create a repository with a file so it has a default branch
exec gh repo create ${ORG}/${REPO} --add-readme --private

# Defer repo cleanup
defer gh repo delete --yes ${ORG}/${REPO}

# Create a fork
exec gh repo fork ${ORG}/${REPO} --org ${ORG} --fork-name ${REPO}-fork

# Defer fork cleanup
defer gh repo delete --yes ${ORG}/${REPO}-fork

# Sleep to allow the fork to be created before cloning
sleep 2

# Clone and move into the fork repo
exec gh repo clone ${ORG}/${REPO}-fork
cd ${REPO}-fork

# Secret list requires disambiguation
! exec gh secret list
stderr 'multiple remotes detected. please specify which repo to use by providing the -R, --repo argument'

# Secret set requires disambiguation
! exec gh secret set 'TEST_SECRET_NAME' --body 'TEST_SECRET_VALUE'
stderr 'multiple remotes detected. please specify which repo to use by providing the -R, --repo argument'

# Secret delete requires disambiguation
! exec gh secret delete 'TEST_SECRET_NAME'
stderr 'multiple remotes detected. please specify which repo to use by providing the -R, --repo argument'
1 change: 1 addition & 0 deletions pkg/cmd/factory/remote_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func (rr *remoteResolver) Resolver() func() (context.Remotes, error) {
sort.Sort(resolvedRemotes)

// Filter remotes by hosts
// Note that this is not caching correctly: https://github.com/cli/cli/issues/10103
cachedRemotes := resolvedRemotes.FilterByHosts(hosts)

// Filter again by default host if one is set
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/repo/setdefault/setdefault.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ func explainer() string {
- viewing and creating issues
- viewing and creating releases
- working with GitHub Actions
- adding repository and environment secrets`)

### NOTE: gh does not use the default repository for managing repository and environment secrets.`)
}

type iprompter interface {
Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/repo/setdefault/setdefault_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ func TestDefaultRun(t *testing.T) {
}
}
},
wantStdout: "This command sets the default remote repository to use when querying the\nGitHub API for the locally cloned repository.\n\ngh uses the default repository for things like:\n\n - viewing and creating pull requests\n - viewing and creating issues\n - viewing and creating releases\n - working with GitHub Actions\n - adding repository and environment secrets\n\n✓ Set OWNER2/REPO2 as the default repository for the current directory\n",
wantStdout: "This command sets the default remote repository to use when querying the\nGitHub API for the locally cloned repository.\n\ngh uses the default repository for things like:\n\n - viewing and creating pull requests\n - viewing and creating issues\n - viewing and creating releases\n - working with GitHub Actions\n\n### NOTE: gh does not use the default repository for managing repository and environment secrets.\n\n✓ Set OWNER2/REPO2 as the default repository for the current directory\n",
},
{
name: "interactive mode only one known host",
Expand Down Expand Up @@ -456,7 +456,7 @@ func TestDefaultRun(t *testing.T) {
}
}
},
wantStdout: "This command sets the default remote repository to use when querying the\nGitHub API for the locally cloned repository.\n\ngh uses the default repository for things like:\n\n - viewing and creating pull requests\n - viewing and creating issues\n - viewing and creating releases\n - working with GitHub Actions\n - adding repository and environment secrets\n\n✓ Set OWNER2/REPO2 as the default repository for the current directory\n",
wantStdout: "This command sets the default remote repository to use when querying the\nGitHub API for the locally cloned repository.\n\ngh uses the default repository for things like:\n\n - viewing and creating pull requests\n - viewing and creating issues\n - viewing and creating releases\n - working with GitHub Actions\n\n### NOTE: gh does not use the default repository for managing repository and environment secrets.\n\n✓ Set OWNER2/REPO2 as the default repository for the current directory\n",
},
}

Expand Down
29 changes: 20 additions & 9 deletions pkg/cmd/secret/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,19 @@ func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Co
`),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
// support `-R, --repo` override
// If the user specified a repo directly, then we're using the OverrideBaseRepoFunc set by EnableRepoOverride
// So there's no reason to use the specialised BaseRepoFunc that requires remote disambiguation.
opts.BaseRepo = f.BaseRepo
if !cmd.Flags().Changed("repo") {
// If they haven't specified a repo directly, then we will wrap the BaseRepoFunc in one that errors if
// there might be multiple valid remotes.
opts.BaseRepo = shared.RequireNoAmbiguityBaseRepoFunc(opts.BaseRepo, f.Remotes)
// But if we are able to prompt, then we will wrap that up in a BaseRepoFunc that can prompt the user to
// resolve the ambiguity.
if opts.IO.CanPrompt() {
opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.IOStreams, f.Prompter)
}
}

if err := cmdutil.MutuallyExclusive("specify only one of `--org`, `--env`, or `--user`", opts.OrgName != "", opts.EnvName != "", opts.UserSecrets); err != nil {
return err
Expand Down Expand Up @@ -88,6 +99,14 @@ func removeRun(opts *DeleteOptions) error {
return err
}

var baseRepo ghrepo.Interface
if secretEntity == shared.Repository || secretEntity == shared.Environment {
baseRepo, err = opts.BaseRepo()
if err != nil {
return err
}
}

Comment on lines +102 to +109
Copy link
Member

Choose a reason for hiding this comment

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

I assume this was moved higher up so any ambiguity errors are raised earlier before the other ways this can error.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeh, similar to #10209 (comment) I just wanted the repo disambiguation frontloaded to avoid going through a bunch of steps only to discover this at the end.

secretApp, err := shared.GetSecretApp(opts.Application, secretEntity)
if err != nil {
return err
Expand All @@ -97,14 +116,6 @@ func removeRun(opts *DeleteOptions) error {
return fmt.Errorf("%s secrets are not supported for %s", secretEntity, secretApp)
}

var baseRepo ghrepo.Interface
if secretEntity == shared.Repository || secretEntity == shared.Environment {
baseRepo, err = opts.BaseRepo()
if err != nil {
return err
}
}

cfg, err := opts.Config()
if err != nil {
return err
Expand Down
107 changes: 107 additions & 0 deletions pkg/cmd/secret/delete/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ package delete

import (
"bytes"
"io"
"net/http"
"testing"

ghContext "github.com/cli/cli/v2/context"
"github.com/cli/cli/v2/git"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/gh"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/internal/prompter"
"github.com/cli/cli/v2/pkg/cmd/secret/shared"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/httpmock"
"github.com/cli/cli/v2/pkg/iostreams"
Expand Down Expand Up @@ -120,6 +125,108 @@ func TestNewCmdDelete(t *testing.T) {
}
}

func TestNewCmdDeleteBaseRepoFuncs(t *testing.T) {
remotes := ghContext.Remotes{
&ghContext.Remote{
Remote: &git.Remote{
Name: "origin",
},
Repo: ghrepo.New("owner", "fork"),
},
&ghContext.Remote{
Remote: &git.Remote{
Name: "upstream",
},
Repo: ghrepo.New("owner", "repo"),
},
}

tests := []struct {
name string
args string
prompterStubs func(*prompter.MockPrompter)
wantRepo ghrepo.Interface
wantErr error
}{
{
name: "when there is a repo flag provided, the factory base repo func is used",
args: "SECRET_NAME --repo owner/repo",
wantRepo: ghrepo.New("owner", "repo"),
},
{
name: "when there is no repo flag provided, and no prompting, the base func requiring no ambiguity is used",
args: "SECRET_NAME",
wantErr: shared.AmbiguousBaseRepoError{
Remotes: remotes,
},
},
{
name: "when there is no repo flag provided, and can prompt, the base func resolving ambiguity is used",
args: "SECRET_NAME",
prompterStubs: func(pm *prompter.MockPrompter) {
pm.RegisterSelect(
"Select a repo",
[]string{"owner/fork", "owner/repo"},
func(_, _ string, opts []string) (int, error) {
return prompter.IndexFor(opts, "owner/fork")
},
)
},
wantRepo: ghrepo.New("owner", "fork"),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ios, _, _, _ := iostreams.Test()
var pm *prompter.MockPrompter
if tt.prompterStubs != nil {
ios.SetStdinTTY(true)
ios.SetStdoutTTY(true)
ios.SetStderrTTY(true)
pm = prompter.NewMockPrompter(t)
tt.prompterStubs(pm)
}

f := &cmdutil.Factory{
IOStreams: ios,
BaseRepo: func() (ghrepo.Interface, error) {
return ghrepo.FromFullName("owner/repo")
},
Prompter: pm,
Remotes: func() (ghContext.Remotes, error) {
return remotes, nil
},
}

argv, err := shlex.Split(tt.args)
assert.NoError(t, err)

var gotOpts *DeleteOptions
cmd := NewCmdDelete(f, func(opts *DeleteOptions) error {
gotOpts = opts
return nil
})
// Require to support --repo flag
cmdutil.EnableRepoOverride(cmd, f)
cmd.SetArgs(argv)
cmd.SetIn(&bytes.Buffer{})
cmd.SetOut(io.Discard)
cmd.SetErr(io.Discard)

_, err = cmd.ExecuteC()
require.NoError(t, err)

baseRepo, err := gotOpts.BaseRepo()
if tt.wantErr != nil {
require.Equal(t, tt.wantErr, err)
return
}
require.True(t, ghrepo.IsSame(tt.wantRepo, baseRepo))
})
}
}

func Test_removeRun_repo(t *testing.T) {
tests := []struct {
name string
Expand Down
21 changes: 18 additions & 3 deletions pkg/cmd/secret/list/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/gh"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/internal/prompter"
"github.com/cli/cli/v2/internal/tableprinter"
"github.com/cli/cli/v2/pkg/cmd/secret/shared"
"github.com/cli/cli/v2/pkg/cmdutil"
Expand All @@ -23,8 +24,10 @@ type ListOptions struct {
IO *iostreams.IOStreams
Config func() (gh.Config, error)
BaseRepo func() (ghrepo.Interface, error)
Now func() time.Time
Exporter cmdutil.Exporter
Prompter prompter.Prompter

Now func() time.Time
Exporter cmdutil.Exporter

OrgName string
EnvName string
Expand All @@ -48,6 +51,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
Config: f.Config,
HttpClient: f.HttpClient,
Now: time.Now,
Prompter: f.Prompter,
}

cmd := &cobra.Command{
Expand All @@ -63,8 +67,19 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
Aliases: []string{"ls"},
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
// support `-R, --repo` override
// If the user specified a repo directly, then we're using the OverrideBaseRepoFunc set by EnableRepoOverride
// So there's no reason to use the specialised BaseRepoFunc that requires remote disambiguation.
opts.BaseRepo = f.BaseRepo
if !cmd.Flags().Changed("repo") {
// If they haven't specified a repo directly, then we will wrap the BaseRepoFunc in one that errors if
// there might be multiple valid remotes.
opts.BaseRepo = shared.RequireNoAmbiguityBaseRepoFunc(opts.BaseRepo, f.Remotes)
// But if we are able to prompt, then we will wrap that up in a BaseRepoFunc that can prompt the user to
// resolve the ambiguity.
if opts.IO.CanPrompt() {
opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.IOStreams, f.Prompter)
}
}

if err := cmdutil.MutuallyExclusive("specify only one of `--org`, `--env`, or `--user`", opts.OrgName != "", opts.EnvName != "", opts.UserSecrets); err != nil {
return err
Expand Down
Loading
Loading