Skip to content

Commit 3e36596

Browse files
author
vilmibm
committed
ability to paste secrets in a prompt
1 parent 5a2ec54 commit 3e36596

File tree

2 files changed

+50
-19
lines changed

2 files changed

+50
-19
lines changed

pkg/cmd/secret/set/set.go

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ import (
1010
"regexp"
1111
"strings"
1212

13+
"github.com/AlecAivazis/survey/v2"
1314
"github.com/MakeNowJust/heredoc"
1415
"github.com/cli/cli/api"
1516
"github.com/cli/cli/internal/config"
1617
"github.com/cli/cli/internal/ghrepo"
1718
"github.com/cli/cli/pkg/cmd/secret/shared"
1819
"github.com/cli/cli/pkg/cmdutil"
1920
"github.com/cli/cli/pkg/iostreams"
21+
"github.com/cli/cli/pkg/prompt"
2022
"github.com/spf13/cobra"
2123
"golang.org/x/crypto/nacl/box"
2224
)
@@ -48,19 +50,25 @@ func NewCmdSet(f *cmdutil.Factory, runF func(*SetOptions) error) *cobra.Command
4850
Short: "Create or update secrets",
4951
Long: "Locally encrypt a new or updated secret at either the repository or organization level and send it to GitHub for storage.",
5052
Example: heredoc.Doc(`
51-
$ gh secret set FROM_FLAG -b"some literal value"
52-
$ gh secret set FROM_ENV -b"${ENV_VALUE}"
53-
$ gh secret set FROM_FILE < file.json
54-
$ gh secret set ORG_SECRET -bval --org=anOrg --visibility=all
55-
$ gh secret set ORG_SECRET -bval --org=anOrg --repos="repo1,repo2,repo3"
53+
Paste secret in prompt
54+
$ gh secret set MYSECRET
55+
56+
Use environment variable as secret value
57+
$ gh secret set MYSECRET -b"${ENV_VALUE}"
58+
59+
Use file as secret value
60+
$ gh secret set MYSECRET < file.json
61+
62+
Set organization level secret visible to entire organization
63+
$ gh secret set MYSECRET -bval --org=anOrg --visibility=all
64+
65+
Set organization level secret visible only to certain repositories
66+
$ gh secret set MYSECRET -bval --org=anOrg --repos="repo1,repo2,repo3"
5667
`),
5768
Args: func(cmd *cobra.Command, args []string) error {
5869
if len(args) != 1 {
5970
return &cmdutil.FlagError{Err: errors.New("must pass single secret name")}
6071
}
61-
if !cmd.Flags().Changed("body") && opts.IO.IsStdinTTY() {
62-
return &cmdutil.FlagError{Err: errors.New("no --body specified but nothing on STIDN")}
63-
}
6472
return nil
6573
},
6674
RunE: func(cmd *cobra.Command, args []string) error {
@@ -209,12 +217,22 @@ func validSecretName(name string) error {
209217

210218
func getBody(opts *SetOptions) ([]byte, error) {
211219
if opts.Body == "" {
212-
body, err := ioutil.ReadAll(opts.IO.In)
213-
if err != nil {
214-
return nil, fmt.Errorf("failed to read from STDIN: %w", err)
215-
}
220+
if opts.IO.CanPrompt() {
221+
err := prompt.SurveyAskOne(&survey.Password{
222+
Message: "Paste your secret",
223+
}, &opts.Body)
224+
if err != nil {
225+
return nil, err
226+
}
227+
fmt.Fprintln(opts.IO.Out)
228+
} else {
229+
body, err := ioutil.ReadAll(opts.IO.In)
230+
if err != nil {
231+
return nil, fmt.Errorf("failed to read from STDIN: %w", err)
232+
}
216233

217-
return body, nil
234+
return body, nil
235+
}
218236
}
219237

220238
return []byte(opts.Body), nil

pkg/cmd/secret/set/set_test.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/cli/cli/pkg/cmdutil"
1515
"github.com/cli/cli/pkg/httpmock"
1616
"github.com/cli/cli/pkg/iostreams"
17+
"github.com/cli/cli/pkg/prompt"
1718
"github.com/google/shlex"
1819
"github.com/stretchr/testify/assert"
1920
)
@@ -51,12 +52,6 @@ func TestNewCmdSet(t *testing.T) {
5152
cli: "cool_secret good_secret",
5253
wantsErr: true,
5354
},
54-
{
55-
name: "no body, stdin is terminal",
56-
cli: "cool_secret",
57-
stdinTTY: true,
58-
wantsErr: true,
59-
},
6055
{
6156
name: "visibility without org",
6257
cli: "cool_secret -vall",
@@ -326,3 +321,21 @@ func Test_getBody(t *testing.T) {
326321
})
327322
}
328323
}
324+
325+
func Test_getBodyPrompt(t *testing.T) {
326+
io, _, _, _ := iostreams.Test()
327+
328+
io.SetStdinTTY(true)
329+
io.SetStdoutTTY(true)
330+
331+
as, teardown := prompt.InitAskStubber()
332+
defer teardown()
333+
334+
as.StubOne("cool secret")
335+
336+
body, err := getBody(&SetOptions{
337+
IO: io,
338+
})
339+
assert.NoError(t, err)
340+
assert.Equal(t, string(body), "cool secret")
341+
}

0 commit comments

Comments
 (0)