Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit 3535dc4

Browse files
authored
feat: add envs create-from-repo subcommand (#212)
1 parent 96c67b8 commit 3535dc4

File tree

2 files changed

+90
-11
lines changed

2 files changed

+90
-11
lines changed

coder-sdk/env.go

+30-10
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,17 @@ const (
7373

7474
// CreateEnvironmentRequest is used to configure a new environment.
7575
type CreateEnvironmentRequest struct {
76-
Name string `json:"name"`
77-
ImageID string `json:"image_id"`
78-
OrgID string `json:"org_id"`
79-
ImageTag string `json:"image_tag"`
80-
CPUCores float32 `json:"cpu_cores"`
81-
MemoryGB float32 `json:"memory_gb"`
82-
DiskGB int `json:"disk_gb"`
83-
GPUs int `json:"gpus"`
84-
Services []string `json:"services"`
85-
UseContainerVM bool `json:"use_container_vm"`
76+
Name string `json:"name"`
77+
ImageID string `json:"image_id"`
78+
OrgID string `json:"org_id"`
79+
ImageTag string `json:"image_tag"`
80+
CPUCores float32 `json:"cpu_cores"`
81+
MemoryGB float32 `json:"memory_gb"`
82+
DiskGB int `json:"disk_gb"`
83+
GPUs int `json:"gpus"`
84+
Services []string `json:"services"`
85+
UseContainerVM bool `json:"use_container_vm"`
86+
Template *Template `json:"template"`
8687
}
8788

8889
// CreateEnvironment sends a request to create an environment.
@@ -94,6 +95,25 @@ func (c Client) CreateEnvironment(ctx context.Context, req CreateEnvironmentRequ
9495
return &env, nil
9596
}
9697

98+
// Template is used to configure a new environment from a repo.
99+
// It is currently in alpha and subject to API-breaking change.
100+
type Template struct {
101+
RepositoryURL string `json:"repository_url"`
102+
// Optional. The default branch will be used if not provided.
103+
Branch string `json:"branch"`
104+
// Optional. The template name will be used if not provided.
105+
Name string `json:"name"`
106+
}
107+
108+
// CreateEnvironmentFromRepo sends a request to create an environment from a repository.
109+
func (c Client) CreateEnvironmentFromRepo(ctx context.Context, orgID string, req Template) (*Environment, error) {
110+
var env Environment
111+
if err := c.requestBody(ctx, http.MethodPost, "/api/private/orgs/"+orgID+"/environments/from-repo", req, &env); err != nil {
112+
return nil, err
113+
}
114+
return &env, nil
115+
}
116+
97117
// Environments lists environments returned by the given filter.
98118
// TODO: add the filter options, explore performance issue.
99119
func (c Client) Environments(ctx context.Context) ([]Environment, error) {

internal/cmd/envs.go

+60-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func envsCmd() *cobra.Command {
3232
watchBuildLogCommand(),
3333
rebuildEnvCommand(),
3434
createEnvCmd(),
35+
createEnvFromRepoCmd(),
3536
editEnvCmd(),
3637
)
3738
return cmd
@@ -184,7 +185,6 @@ coder envs create my-new-powerful-env --cpu 12 --disk 100 --memory 16 --image ub
184185
if multiOrgMember && org == "" {
185186
return xerrors.New("org is required for multi-org members")
186187
}
187-
188188
importedImg, err := findImg(ctx, client, findImgConf{
189189
email: coder.Me,
190190
imgName: img,
@@ -252,6 +252,65 @@ coder envs create my-new-powerful-env --cpu 12 --disk 100 --memory 16 --image ub
252252
return cmd
253253
}
254254

255+
func createEnvFromRepoCmd() *cobra.Command {
256+
var (
257+
branch string
258+
name string
259+
follow bool
260+
)
261+
262+
cmd := &cobra.Command{
263+
Use: "create-from-repo [environment_name]",
264+
Short: "create a new environment from a git repository.",
265+
Args: xcobra.ExactArgs(1),
266+
Long: "Create a new Coder environment from a Git repository.",
267+
Hidden: true,
268+
Example: `# create a new environment from git repository template
269+
coder envs create-from-repo github.com/cdr/m
270+
coder envs create-from-repo github.com/cdr/m --branch envs-as-code`,
271+
RunE: func(cmd *cobra.Command, args []string) error {
272+
ctx := cmd.Context()
273+
274+
client, err := newClient(ctx)
275+
if err != nil {
276+
return err
277+
}
278+
279+
// ExactArgs(1) ensures our name value can't panic on an out of bounds.
280+
createReq := &coder.Template{
281+
RepositoryURL: args[0],
282+
Branch: branch,
283+
Name: name,
284+
}
285+
286+
env, err := client.CreateEnvironment(ctx, coder.CreateEnvironmentRequest{
287+
Template: createReq,
288+
})
289+
if err != nil {
290+
return xerrors.Errorf("create environment: %w", err)
291+
}
292+
293+
if follow {
294+
clog.LogSuccess("creating environment...")
295+
if err := trailBuildLogs(ctx, client, env.ID); err != nil {
296+
return err
297+
}
298+
return nil
299+
}
300+
301+
clog.LogSuccess("creating environment...",
302+
clog.BlankLine,
303+
clog.Tipf(`run "coder envs watch-build %s" to trail the build logs`, env.Name),
304+
)
305+
return nil
306+
},
307+
}
308+
cmd.Flags().StringVarP(&branch, "branch", "b", "master", "name of the branch to create the environment from.")
309+
cmd.Flags().StringVarP(&name, "name", "n", "coder.yaml", "name of the config file.")
310+
cmd.Flags().BoolVar(&follow, "follow", false, "follow buildlog after initiating rebuild")
311+
return cmd
312+
}
313+
255314
func editEnvCmd() *cobra.Command {
256315
var (
257316
org string

0 commit comments

Comments
 (0)