Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7982ad7

Browse files
authored
feat: expose premium trial form via CLI (#15054)
This PRcloses#14856
1 parent78ff375 commit7982ad7

File tree

6 files changed

+233
-9
lines changed

6 files changed

+233
-9
lines changed

‎.github/workflows/pr-deploy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ jobs:
425425
--first-user-username coder \
426426
--first-user-email pr${{ env.PR_NUMBER }}@coder.com \
427427
--first-user-password $password \
428-
--first-user-trial \
428+
--first-user-trial=false \
429429
--use-token-as-session \
430430
https://${{ env.PR_HOSTNAME }}
431431

‎cli/login.go

Lines changed: 124 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,59 @@ func (r *RootCmd) login() *serpent.Command {
267267
trial=v=="yes"||v=="y"
268268
}
269269

270+
vartrialInfo codersdk.CreateFirstUserTrialInfo
271+
iftrial {
272+
iftrialInfo.FirstName=="" {
273+
trialInfo.FirstName,err=promptTrialInfo(inv,"firstName")
274+
iferr!=nil {
275+
returnerr
276+
}
277+
}
278+
iftrialInfo.LastName=="" {
279+
trialInfo.LastName,err=promptTrialInfo(inv,"lastName")
280+
iferr!=nil {
281+
returnerr
282+
}
283+
}
284+
iftrialInfo.PhoneNumber=="" {
285+
trialInfo.PhoneNumber,err=promptTrialInfo(inv,"phoneNumber")
286+
iferr!=nil {
287+
returnerr
288+
}
289+
}
290+
iftrialInfo.JobTitle=="" {
291+
trialInfo.JobTitle,err=promptTrialInfo(inv,"jobTitle")
292+
iferr!=nil {
293+
returnerr
294+
}
295+
}
296+
iftrialInfo.CompanyName=="" {
297+
trialInfo.CompanyName,err=promptTrialInfo(inv,"companyName")
298+
iferr!=nil {
299+
returnerr
300+
}
301+
}
302+
iftrialInfo.Country=="" {
303+
trialInfo.Country,err=promptCountry(inv)
304+
iferr!=nil {
305+
returnerr
306+
}
307+
}
308+
iftrialInfo.Developers=="" {
309+
trialInfo.Developers,err=promptDevelopers(inv)
310+
iferr!=nil {
311+
returnerr
312+
}
313+
}
314+
}
315+
270316
_,err=client.CreateFirstUser(ctx, codersdk.CreateFirstUserRequest{
271-
Email:email,
272-
Username:username,
273-
Name:name,
274-
Password:password,
275-
Trial:trial,
317+
Email:email,
318+
Username:username,
319+
Name:name,
320+
Password:password,
321+
Trial:trial,
322+
TrialInfo:trialInfo,
276323
})
277324
iferr!=nil {
278325
returnxerrors.Errorf("create initial user: %w",err)
@@ -449,3 +496,75 @@ func openURL(inv *serpent.Invocation, urlToOpen string) error {
449496

450497
returnbrowser.OpenURL(urlToOpen)
451498
}
499+
500+
funcpromptTrialInfo(inv*serpent.Invocation,fieldNamestring) (string,error) {
501+
value,err:=cliui.Prompt(inv, cliui.PromptOptions{
502+
Text:fmt.Sprintf("Please enter %s:",pretty.Sprint(cliui.DefaultStyles.Field,fieldName)),
503+
Validate:func(sstring)error {
504+
ifstrings.TrimSpace(s)=="" {
505+
returnxerrors.Errorf("%s is required",fieldName)
506+
}
507+
returnnil
508+
},
509+
})
510+
iferr!=nil {
511+
iferrors.Is(err,cliui.Canceled) {
512+
return"",nil
513+
}
514+
return"",err
515+
}
516+
returnvalue,nil
517+
}
518+
519+
funcpromptDevelopers(inv*serpent.Invocation) (string,error) {
520+
options:= []string{"1-100","101-500","501-1000","1001-2500","2500+"}
521+
selection,err:=cliui.Select(inv, cliui.SelectOptions{
522+
Options:options,
523+
HideSearch:false,
524+
Message:"Select the number of developers:",
525+
})
526+
iferr!=nil {
527+
return"",xerrors.Errorf("select developers: %w",err)
528+
}
529+
returnselection,nil
530+
}
531+
532+
funcpromptCountry(inv*serpent.Invocation) (string,error) {
533+
countries:= []string{
534+
"Afghanistan","Åland Islands","Albania","Algeria","American Samoa","Andorra","Angola","Anguilla","Antarctica","Antigua and Barbuda",
535+
"Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados",
536+
"Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia, Plurinational State of","Bonaire, Sint Eustatius and Saba","Bosnia and Herzegovina","Botswana",
537+
"Bouvet Island","Brazil","British Indian Ocean Territory","Brunei Darussalam","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Canada",
538+
"Cape Verde","Cayman Islands","Central African Republic","Chad","Chile","China","Christmas Island","Cocos (Keeling) Islands","Colombia","Comoros",
539+
"Congo","Congo, the Democratic Republic of the","Cook Islands","Costa Rica","Côte d'Ivoire","Croatia","Cuba","Curaçao","Cyprus","Czech Republic",
540+
"Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia",
541+
"Ethiopia","Falkland Islands (Malvinas)","Faroe Islands","Fiji","Finland","France","French Guiana","French Polynesia","French Southern Territories","Gabon",
542+
"Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guadeloupe","Guam",
543+
"Guatemala","Guernsey","Guinea","Guinea-Bissau","Guyana","Haiti","Heard Island and McDonald Islands","Holy See (Vatican City State)","Honduras","Hong Kong",
544+
"Hungary","Iceland","India","Indonesia","Iran, Islamic Republic of","Iraq","Ireland","Isle of Man","Israel","Italy",
545+
"Jamaica","Japan","Jersey","Jordan","Kazakhstan","Kenya","Kiribati","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait",
546+
"Kyrgyzstan","Lao People's Democratic Republic","Latvia","Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg",
547+
"Macao","Macedonia, the Former Yugoslav Republic of","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Martinique",
548+
"Mauritania","Mauritius","Mayotte","Mexico","Micronesia, Federated States of","Moldova, Republic of","Monaco","Mongolia","Montenegro","Montserrat",
549+
"Morocco","Mozambique","Myanmar","Namibia","Nauru","Nepal","Netherlands","New Caledonia","New Zealand","Nicaragua",
550+
"Niger","Nigeria","Niue","Norfolk Island","Northern Mariana Islands","Norway","Oman","Pakistan","Palau","Palestine, State of",
551+
"Panama","Papua New Guinea","Paraguay","Peru","Philippines","Pitcairn","Poland","Portugal","Puerto Rico","Qatar",
552+
"Réunion","Romania","Russian Federation","Rwanda","Saint Barthélemy","Saint Helena, Ascension and Tristan da Cunha","Saint Kitts and Nevis","Saint Lucia","Saint Martin (French part)","Saint Pierre and Miquelon",
553+
"Saint Vincent and the Grenadines","Samoa","San Marino","Sao Tome and Principe","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore",
554+
"Sint Maarten (Dutch part)","Slovakia","Slovenia","Solomon Islands","Somalia","South Africa","South Georgia and the South Sandwich Islands","South Sudan","Spain","Sri Lanka",
555+
"Sudan","Suriname","Svalbard and Jan Mayen","Swaziland","Sweden","Switzerland","Syrian Arab Republic","Taiwan, Province of China","Tajikistan","Tanzania, United Republic of",
556+
"Thailand","Timor-Leste","Togo","Tokelau","Tonga","Trinidad and Tobago","Tunisia","Turkey","Turkmenistan","Turks and Caicos Islands",
557+
"Tuvalu","Uganda","Ukraine","United Arab Emirates","United Kingdom","United States","United States Minor Outlying Islands","Uruguay","Uzbekistan","Vanuatu",
558+
"Venezuela, Bolivarian Republic of","Vietnam","Virgin Islands, British","Virgin Islands, U.S.","Wallis and Futuna","Western Sahara","Yemen","Zambia","Zimbabwe",
559+
}
560+
561+
selection,err:=cliui.Select(inv, cliui.SelectOptions{
562+
Options:countries,
563+
Message:"Select the country:",
564+
HideSearch:false,
565+
})
566+
iferr!=nil {
567+
return"",xerrors.Errorf("select country: %w",err)
568+
}
569+
returnselection,nil
570+
}

‎cli/login_test.go

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,58 @@ func TestLogin(t *testing.T) {
9696
"password",coderdtest.FirstUserParams.Password,
9797
"password",coderdtest.FirstUserParams.Password,// confirm
9898
"trial","yes",
99+
"firstName",coderdtest.TrialUserParams.FirstName,
100+
"lastName",coderdtest.TrialUserParams.LastName,
101+
"phoneNumber",coderdtest.TrialUserParams.PhoneNumber,
102+
"jobTitle",coderdtest.TrialUserParams.JobTitle,
103+
"companyName",coderdtest.TrialUserParams.CompanyName,
104+
// `developers` and `country` `cliui.Select` automatically selects the first option during tests.
105+
}
106+
fori:=0;i<len(matches);i+=2 {
107+
match:=matches[i]
108+
value:=matches[i+1]
109+
pty.ExpectMatch(match)
110+
pty.WriteLine(value)
111+
}
112+
pty.ExpectMatch("Welcome to Coder")
113+
<-doneChan
114+
ctx:=testutil.Context(t,testutil.WaitShort)
115+
resp,err:=client.LoginWithPassword(ctx, codersdk.LoginWithPasswordRequest{
116+
Email:coderdtest.FirstUserParams.Email,
117+
Password:coderdtest.FirstUserParams.Password,
118+
})
119+
require.NoError(t,err)
120+
client.SetSessionToken(resp.SessionToken)
121+
me,err:=client.User(ctx,codersdk.Me)
122+
require.NoError(t,err)
123+
assert.Equal(t,coderdtest.FirstUserParams.Username,me.Username)
124+
assert.Equal(t,coderdtest.FirstUserParams.Name,me.Name)
125+
assert.Equal(t,coderdtest.FirstUserParams.Email,me.Email)
126+
})
127+
128+
t.Run("InitialUserTTYWithNoTrial",func(t*testing.T) {
129+
t.Parallel()
130+
client:=coderdtest.New(t,nil)
131+
// The --force-tty flag is required on Windows, because the `isatty` library does not
132+
// accurately detect Windows ptys when they are not attached to a process:
133+
// https://github.com/mattn/go-isatty/issues/59
134+
doneChan:=make(chanstruct{})
135+
root,_:=clitest.New(t,"login","--force-tty",client.URL.String())
136+
pty:=ptytest.New(t).Attach(root)
137+
gofunc() {
138+
deferclose(doneChan)
139+
err:=root.Run()
140+
assert.NoError(t,err)
141+
}()
142+
143+
matches:= []string{
144+
"first user?","yes",
145+
"username",coderdtest.FirstUserParams.Username,
146+
"name",coderdtest.FirstUserParams.Name,
147+
"email",coderdtest.FirstUserParams.Email,
148+
"password",coderdtest.FirstUserParams.Password,
149+
"password",coderdtest.FirstUserParams.Password,// confirm
150+
"trial","no",
99151
}
100152
fori:=0;i<len(matches);i+=2 {
101153
match:=matches[i]
@@ -142,6 +194,12 @@ func TestLogin(t *testing.T) {
142194
"password",coderdtest.FirstUserParams.Password,
143195
"password",coderdtest.FirstUserParams.Password,// confirm
144196
"trial","yes",
197+
"firstName",coderdtest.TrialUserParams.FirstName,
198+
"lastName",coderdtest.TrialUserParams.LastName,
199+
"phoneNumber",coderdtest.TrialUserParams.PhoneNumber,
200+
"jobTitle",coderdtest.TrialUserParams.JobTitle,
201+
"companyName",coderdtest.TrialUserParams.CompanyName,
202+
// `developers` and `country` `cliui.Select` automatically selects the first option during tests.
145203
}
146204
fori:=0;i<len(matches);i+=2 {
147205
match:=matches[i]
@@ -185,6 +243,12 @@ func TestLogin(t *testing.T) {
185243
"password",coderdtest.FirstUserParams.Password,
186244
"password",coderdtest.FirstUserParams.Password,// confirm
187245
"trial","yes",
246+
"firstName",coderdtest.TrialUserParams.FirstName,
247+
"lastName",coderdtest.TrialUserParams.LastName,
248+
"phoneNumber",coderdtest.TrialUserParams.PhoneNumber,
249+
"jobTitle",coderdtest.TrialUserParams.JobTitle,
250+
"companyName",coderdtest.TrialUserParams.CompanyName,
251+
// `developers` and `country` `cliui.Select` automatically selects the first option during tests.
188252
}
189253
fori:=0;i<len(matches);i+=2 {
190254
match:=matches[i]
@@ -220,6 +284,17 @@ func TestLogin(t *testing.T) {
220284
)
221285
pty:=ptytest.New(t).Attach(inv)
222286
w:=clitest.StartWithWaiter(t,inv)
287+
pty.ExpectMatch("firstName")
288+
pty.WriteLine(coderdtest.TrialUserParams.FirstName)
289+
pty.ExpectMatch("lastName")
290+
pty.WriteLine(coderdtest.TrialUserParams.LastName)
291+
pty.ExpectMatch("phoneNumber")
292+
pty.WriteLine(coderdtest.TrialUserParams.PhoneNumber)
293+
pty.ExpectMatch("jobTitle")
294+
pty.WriteLine(coderdtest.TrialUserParams.JobTitle)
295+
pty.ExpectMatch("companyName")
296+
pty.WriteLine(coderdtest.TrialUserParams.CompanyName)
297+
// `developers` and `country` `cliui.Select` automatically selects the first option during tests.
223298
pty.ExpectMatch("Welcome to Coder")
224299
w.RequireSuccess()
225300
ctx:=testutil.Context(t,testutil.WaitShort)
@@ -248,6 +323,17 @@ func TestLogin(t *testing.T) {
248323
)
249324
pty:=ptytest.New(t).Attach(inv)
250325
w:=clitest.StartWithWaiter(t,inv)
326+
pty.ExpectMatch("firstName")
327+
pty.WriteLine(coderdtest.TrialUserParams.FirstName)
328+
pty.ExpectMatch("lastName")
329+
pty.WriteLine(coderdtest.TrialUserParams.LastName)
330+
pty.ExpectMatch("phoneNumber")
331+
pty.WriteLine(coderdtest.TrialUserParams.PhoneNumber)
332+
pty.ExpectMatch("jobTitle")
333+
pty.WriteLine(coderdtest.TrialUserParams.JobTitle)
334+
pty.ExpectMatch("companyName")
335+
pty.WriteLine(coderdtest.TrialUserParams.CompanyName)
336+
// `developers` and `country` `cliui.Select` automatically selects the first option during tests.
251337
pty.ExpectMatch("Welcome to Coder")
252338
w.RequireSuccess()
253339
ctx:=testutil.Context(t,testutil.WaitShort)
@@ -299,12 +385,21 @@ func TestLogin(t *testing.T) {
299385
// Validate that we reprompt for matching passwords.
300386
pty.ExpectMatch("Passwords do not match")
301387
pty.ExpectMatch("Enter a "+pretty.Sprint(cliui.DefaultStyles.Field,"password"))
302-
303388
pty.WriteLine(coderdtest.FirstUserParams.Password)
304389
pty.ExpectMatch("Confirm")
305390
pty.WriteLine(coderdtest.FirstUserParams.Password)
306391
pty.ExpectMatch("trial")
307392
pty.WriteLine("yes")
393+
pty.ExpectMatch("firstName")
394+
pty.WriteLine(coderdtest.TrialUserParams.FirstName)
395+
pty.ExpectMatch("lastName")
396+
pty.WriteLine(coderdtest.TrialUserParams.LastName)
397+
pty.ExpectMatch("phoneNumber")
398+
pty.WriteLine(coderdtest.TrialUserParams.PhoneNumber)
399+
pty.ExpectMatch("jobTitle")
400+
pty.WriteLine(coderdtest.TrialUserParams.JobTitle)
401+
pty.ExpectMatch("companyName")
402+
pty.WriteLine(coderdtest.TrialUserParams.CompanyName)
308403
pty.ExpectMatch("Welcome to Coder")
309404
<-doneChan
310405
})

‎coderd/coderdtest/coderdtest.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,16 @@ var FirstUserParams = codersdk.CreateFirstUserRequest{
653653
Name:"Test User",
654654
}
655655

656+
varTrialUserParams= codersdk.CreateFirstUserTrialInfo{
657+
FirstName:"John",
658+
LastName:"Doe",
659+
PhoneNumber:"9999999999",
660+
JobTitle:"Engineer",
661+
CompanyName:"Acme Inc",
662+
Country:"United States",
663+
Developers:"10-50",
664+
}
665+
656666
// CreateFirstUser creates a user with preset credentials and authenticates
657667
// with the passed in codersdk client.
658668
funcCreateFirstUser(t testing.TB,client*codersdk.Client) codersdk.CreateFirstUserResponse {

‎scripts/develop.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ fatal() {
164164

165165
if [!-f"${PROJECT_ROOT}/.coderv2/developsh-did-first-setup" ];then
166166
# Try to create the initial admin user.
167-
if"${CODER_DEV_SHIM}" login http://127.0.0.1:3000 --first-user-username=admin --first-user-email=admin@coder.com --first-user-password="${password}" --first-user-full-name="Admin User" --first-user-trial=true;then
167+
if"${CODER_DEV_SHIM}" login http://127.0.0.1:3000 --first-user-username=admin --first-user-email=admin@coder.com --first-user-password="${password}" --first-user-full-name="Admin User" --first-user-trial=false;then
168168
# Only create this file if an admin user was successfully
169169
# created, otherwise we won't retry on a later attempt.
170170
touch"${PROJECT_ROOT}/.coderv2/developsh-did-first-setup"

‎site/src/pages/SetupPage/countries.tsx

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp