Skip to content

Commit b166376

Browse files
authored
Merge pull request cli#3774 from browniebroke/feat/remove-env-secret
Add support for removing environment secrets
2 parents a1cedfc + 4b79edf commit b166376

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

pkg/cmd/secret/remove/remove.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type RemoveOptions struct {
2020

2121
SecretName string
2222
OrgName string
23+
EnvName string
2324
}
2425

2526
func NewCmdRemove(f *cmdutil.Factory, runF func(*RemoveOptions) error) *cobra.Command {
@@ -31,12 +32,16 @@ func NewCmdRemove(f *cmdutil.Factory, runF func(*RemoveOptions) error) *cobra.Co
3132

3233
cmd := &cobra.Command{
3334
Use: "remove <secret-name>",
34-
Short: "Remove an organization or repository secret",
35+
Short: "Remove an organization, environment, or repository secret",
3536
Args: cobra.ExactArgs(1),
3637
RunE: func(cmd *cobra.Command, args []string) error {
3738
// support `-R, --repo` override
3839
opts.BaseRepo = f.BaseRepo
3940

41+
if err := cmdutil.MutuallyExclusive("specify only one of `--org` or `--env`", opts.OrgName != "", opts.EnvName != ""); err != nil {
42+
return err
43+
}
44+
4045
opts.SecretName = args[0]
4146

4247
if runF != nil {
@@ -46,7 +51,8 @@ func NewCmdRemove(f *cmdutil.Factory, runF func(*RemoveOptions) error) *cobra.Co
4651
return removeRun(opts)
4752
},
4853
}
49-
cmd.Flags().StringVarP(&opts.OrgName, "org", "o", "", "List secrets for an organization")
54+
cmd.Flags().StringVarP(&opts.OrgName, "org", "o", "", "Remove a secret for an organization")
55+
cmd.Flags().StringVarP(&opts.EnvName, "env", "e", "", "Remove a secret for an environment")
5056

5157
return cmd
5258
}
@@ -59,6 +65,7 @@ func removeRun(opts *RemoveOptions) error {
5965
client := api.NewClientFromHTTP(c)
6066

6167
orgName := opts.OrgName
68+
envName := opts.EnvName
6269

6370
var baseRepo ghrepo.Interface
6471
if orgName == "" {
@@ -69,10 +76,12 @@ func removeRun(opts *RemoveOptions) error {
6976
}
7077

7178
var path string
72-
if orgName == "" {
73-
path = fmt.Sprintf("repos/%s/actions/secrets/%s", ghrepo.FullName(baseRepo), opts.SecretName)
74-
} else {
79+
if orgName != "" {
7580
path = fmt.Sprintf("orgs/%s/actions/secrets/%s", orgName, opts.SecretName)
81+
} else if envName != "" {
82+
path = fmt.Sprintf("repos/%s/environments/%s/secrets/%s", ghrepo.FullName(baseRepo), envName, opts.SecretName)
83+
} else {
84+
path = fmt.Sprintf("repos/%s/actions/secrets/%s", ghrepo.FullName(baseRepo), opts.SecretName)
7685
}
7786

7887
cfg, err := opts.Config()
@@ -96,7 +105,11 @@ func removeRun(opts *RemoveOptions) error {
96105
target = ghrepo.FullName(baseRepo)
97106
}
98107
cs := opts.IO.ColorScheme()
99-
fmt.Fprintf(opts.IO.Out, "%s Removed secret %s from %s\n", cs.SuccessIconWithColor(cs.Red), opts.SecretName, target)
108+
if envName != "" {
109+
fmt.Fprintf(opts.IO.Out, "%s Removed secret %s from %s environment on %s\n", cs.SuccessIconWithColor(cs.Red), opts.SecretName, envName, target)
110+
} else {
111+
fmt.Fprintf(opts.IO.Out, "%s Removed secret %s from %s\n", cs.SuccessIconWithColor(cs.Red), opts.SecretName, target)
112+
}
100113
}
101114

102115
return nil

pkg/cmd/secret/remove/remove_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ func TestNewCmdRemove(t *testing.T) {
4141
OrgName: "anOrg",
4242
},
4343
},
44+
{
45+
name: "env",
46+
cli: "cool --env anEnv",
47+
wants: RemoveOptions{
48+
SecretName: "cool",
49+
EnvName: "anEnv",
50+
},
51+
},
4452
}
4553

4654
for _, tt := range tests {
@@ -72,6 +80,7 @@ func TestNewCmdRemove(t *testing.T) {
7280

7381
assert.Equal(t, tt.wants.SecretName, gotOpts.SecretName)
7482
assert.Equal(t, tt.wants.OrgName, gotOpts.OrgName)
83+
assert.Equal(t, tt.wants.EnvName, gotOpts.EnvName)
7584
})
7685
}
7786

@@ -106,6 +115,36 @@ func Test_removeRun_repo(t *testing.T) {
106115
reg.Verify(t)
107116
}
108117

118+
func Test_removeRun_env(t *testing.T) {
119+
reg := &httpmock.Registry{}
120+
121+
reg.Register(
122+
httpmock.REST("DELETE", "repos/owner/repo/environments/development/secrets/cool_secret"),
123+
httpmock.StatusStringResponse(204, "No Content"))
124+
125+
io, _, _, _ := iostreams.Test()
126+
127+
opts := &RemoveOptions{
128+
IO: io,
129+
HttpClient: func() (*http.Client, error) {
130+
return &http.Client{Transport: reg}, nil
131+
},
132+
Config: func() (config.Config, error) {
133+
return config.NewBlankConfig(), nil
134+
},
135+
BaseRepo: func() (ghrepo.Interface, error) {
136+
return ghrepo.FromFullName("owner/repo")
137+
},
138+
SecretName: "cool_secret",
139+
EnvName: "development",
140+
}
141+
142+
err := removeRun(opts)
143+
assert.NoError(t, err)
144+
145+
reg.Verify(t)
146+
}
147+
109148
func Test_removeRun_org(t *testing.T) {
110149
tests := []struct {
111150
name string

0 commit comments

Comments
 (0)