diff --git a/pkg/cmd/secret/list/list.go b/pkg/cmd/secret/list/list.go index 97c3ac27a..35d8db675 100644 --- a/pkg/cmd/secret/list/list.go +++ b/pkg/cmd/secret/list/list.go @@ -26,6 +26,7 @@ type ListOptions struct { BaseRepo func() (ghrepo.Interface, error) OrgName string + EnvName string } func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command { @@ -38,12 +39,16 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman cmd := &cobra.Command{ Use: "list", Short: "List secrets", - Long: "List secrets for a repository or organization", + Long: "List secrets for a repository, environment, or organization", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { // support `-R, --repo` override opts.BaseRepo = f.BaseRepo + if err := cmdutil.MutuallyExclusive("specify only one of `--org` or `--env`", opts.OrgName != "", opts.EnvName != ""); err != nil { + return err + } + if runF != nil { return runF(opts) } @@ -53,6 +58,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman } cmd.Flags().StringVarP(&opts.OrgName, "org", "o", "", "List secrets for an organization") + cmd.Flags().StringVarP(&opts.EnvName, "env", "e", "", "List secrets for an environment") return cmd } @@ -64,6 +70,7 @@ func listRun(opts *ListOptions) error { } orgName := opts.OrgName + envName := opts.EnvName var baseRepo ghrepo.Interface if orgName == "" { @@ -75,7 +82,11 @@ func listRun(opts *ListOptions) error { var secrets []*Secret if orgName == "" { - secrets, err = getRepoSecrets(client, baseRepo) + if envName == "" { + secrets, err = getRepoSecrets(client, baseRepo) + } else { + secrets, err = getEnvSecrets(client, baseRepo, envName) + } } else { var cfg config.Config var host string @@ -171,6 +182,11 @@ func getOrgSecrets(client httpClient, host, orgName string) ([]*Secret, error) { return secrets, nil } +func getEnvSecrets(client httpClient, repo ghrepo.Interface, envName string) ([]*Secret, error) { + path := fmt.Sprintf("repos/%s/environments/%s/secrets", ghrepo.FullName(repo), envName) + return getSecrets(client, repo.RepoHost(), path) +} + func getRepoSecrets(client httpClient, repo ghrepo.Interface) ([]*Secret, error) { return getSecrets(client, repo.RepoHost(), fmt.Sprintf("repos/%s/actions/secrets", ghrepo.FullName(repo))) diff --git a/pkg/cmd/secret/list/list_test.go b/pkg/cmd/secret/list/list_test.go index e3975b1e6..42504a961 100644 --- a/pkg/cmd/secret/list/list_test.go +++ b/pkg/cmd/secret/list/list_test.go @@ -40,6 +40,13 @@ func Test_NewCmdList(t *testing.T) { OrgName: "UmbrellaCorporation", }, }, + { + name: "env", + cli: "-eDevelopment", + wants: ListOptions{ + EnvName: "Development", + }, + }, } for _, tt := range tests { @@ -66,7 +73,7 @@ func Test_NewCmdList(t *testing.T) { assert.NoError(t, err) assert.Equal(t, tt.wants.OrgName, gotOpts.OrgName) - + assert.Equal(t, tt.wants.EnvName, gotOpts.EnvName) }) } } @@ -122,16 +129,44 @@ func Test_listRun(t *testing.T) { "SECRET_THREE\t1975-11-30\tSELECTED", }, }, + { + name: "env tty", + tty: true, + opts: &ListOptions{ + EnvName: "Development", + }, + wantOut: []string{ + "SECRET_ONE.*Updated 1988-10-11", + "SECRET_TWO.*Updated 2020-12-04", + "SECRET_THREE.*Updated 1975-11-30", + }, + }, + { + name: "env not tty", + tty: false, + opts: &ListOptions{ + EnvName: "Development", + }, + wantOut: []string{ + "SECRET_ONE\t1988-10-11", + "SECRET_TWO\t2020-12-04", + "SECRET_THREE\t1975-11-30", + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { reg := &httpmock.Registry{} + path := "repos/owner/repo/actions/secrets" + if tt.opts.EnvName != "" { + path = fmt.Sprintf("repos/owner/repo/environments/%s/secrets", tt.opts.EnvName) + } + t0, _ := time.Parse("2006-01-02", "1988-10-11") t1, _ := time.Parse("2006-01-02", "2020-12-04") t2, _ := time.Parse("2006-01-02", "1975-11-30") - path := "repos/owner/repo/actions/secrets" payload := secretsPayload{} payload.Secrets = []*Secret{ { diff --git a/pkg/cmd/secret/secret.go b/pkg/cmd/secret/secret.go index e8b82a41d..dc04fc85c 100644 --- a/pkg/cmd/secret/secret.go +++ b/pkg/cmd/secret/secret.go @@ -15,8 +15,8 @@ func NewCmdSecret(f *cmdutil.Factory) *cobra.Command { Use: "secret ", Short: "Manage GitHub secrets", Long: heredoc.Doc(` - Secrets can be set at the repository or organization level for use in GitHub Actions. - Run "gh help secret set" to learn how to get started. + Secrets can be set at the repository, environment, or organization level for use in + GitHub Actions. Run "gh help secret set" to learn how to get started. `), }