Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type createCmdFlags struct {
app string
name string
visibility string
org string
environmentVariables []string
secrets []string
revisionName string
Expand All @@ -25,6 +26,7 @@ type createCmdFlags struct {
type createReq struct {
Name string `json:"friendly_name,omitempty"`
Visibility string `json:"visibility,omitempty"`
OrganizationLogin string `json:"organization_login,omitempty"`
EnvironmentVariables map[string]string `json:"environment_variables"`
Secrets map[string]string `json:"secrets"`
}
Expand All @@ -40,14 +42,23 @@ func init() {
Use: "create",
Short: "Create a GitHub Runtime app",
Long: heredoc.Doc(`
Create a GitHub Runtime app
Create a GitHub Runtime app.
`),
Example: heredoc.Doc(`
$ gh runtime create --app my-app --env key1=value1 --env key2=value2 --secret key3=value3 --secret key4=value4
# => Creates the app with the ID 'my-app'

$ gh runtime create --name my-new-app
# => Creates a new app with the given name

$ gh runtime create --app my-app --visibility only_owner
# => Creates the app visible only to the owner

$ gh runtime create --app my-app --visibility github
# => Creates the app visible to all GitHub users

$ gh runtime create --app my-app --visibility selected_orgs --org my-org
# => Creates the app visible to 'my-org' organization
`),
RunE: func(cmd *cobra.Command, args []string) error {
client, err := api.DefaultRESTClient()
Expand All @@ -70,7 +81,8 @@ func init() {

createCmd.Flags().StringVarP(&createCmdFlags.app, "app", "a", "", "The app ID to create")
createCmd.Flags().StringVarP(&createCmdFlags.name, "name", "n", "", "The name for the app")
createCmd.Flags().StringVarP(&createCmdFlags.visibility, "visibility", "v", "", "The visibility of the app (e.g. 'only_owner' or 'github')")
createCmd.Flags().StringVarP(&createCmdFlags.visibility, "visibility", "v", "", "The visibility of the app (e.g. 'only_owner', 'github', or 'selected_orgs')")
createCmd.Flags().StringVarP(&createCmdFlags.org, "org", "o", "", "The organization login to grant access (only valid with --visibility=selected_orgs)")
createCmd.Flags().StringSliceVarP(&createCmdFlags.environmentVariables, "env", "e", []string{}, "Environment variables to set on the app in the form 'key=value'")
createCmd.Flags().StringSliceVarP(&createCmdFlags.secrets, "secret", "s", []string{}, "Secrets to set on the app in the form 'key=value'")
createCmd.Flags().StringVarP(&createCmdFlags.revisionName, "revision-name", "r", "", "The revision name to use for the app")
Expand All @@ -83,9 +95,18 @@ func runCreate(client restClient, flags createCmdFlags) (createResp, error) {
return createResp{}, fmt.Errorf("either --app or --name flag is required")
}

if flags.org != "" && flags.visibility != "selected_orgs" {
return createResp{}, fmt.Errorf("--org can only be used with --visibility=selected_orgs")
}

if flags.visibility == "selected_orgs" && flags.org == "" {
return createResp{}, fmt.Errorf("--org is required when --visibility=selected_orgs")
}

requestBody := createReq{
Name: flags.name,
Visibility: flags.visibility,
OrganizationLogin: flags.org,
EnvironmentVariables: map[string]string{},
Secrets: map[string]string{},
}
Expand Down
34 changes: 34 additions & 0 deletions cmd/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,40 @@ func TestRunCreate_WithVisibility(t *testing.T) {
assert.Equal(t, "github", req.Visibility)
}

func TestRunCreate_OrgWithoutSelectedOrgsVisibility(t *testing.T) {
client := &mockRESTClient{}
_, err := runCreate(client, createCmdFlags{app: "my-app", org: "my-org"})
require.ErrorContains(t, err, "--org can only be used with --visibility=selected_orgs")

_, err = runCreate(client, createCmdFlags{app: "my-app", visibility: "github", org: "my-org"})
require.ErrorContains(t, err, "--org can only be used with --visibility=selected_orgs")
}

func TestRunCreate_SelectedOrgsVisibilityWithoutOrg(t *testing.T) {
client := &mockRESTClient{}
_, err := runCreate(client, createCmdFlags{app: "my-app", visibility: "selected_orgs"})
require.ErrorContains(t, err, "--org is required when --visibility=selected_orgs")
}

func TestRunCreate_WithOrgAndSelectedOrgsVisibility(t *testing.T) {
var capturedBody []byte
client := &mockRESTClient{
putFunc: func(_ string, body io.Reader, resp interface{}) error {
capturedBody, _ = io.ReadAll(body)
buildCreateResponse(createResp{AppUrl: "https://my-app.example.com"}, resp)
return nil
},
}

_, err := runCreate(client, createCmdFlags{app: "my-app", visibility: "selected_orgs", org: "my-org"})
require.NoError(t, err)

var req createReq
json.Unmarshal(capturedBody, &req)
assert.Equal(t, "selected_orgs", req.Visibility)
assert.Equal(t, "my-org", req.OrganizationLogin)
}

func TestRunCreate_ResponseWithID(t *testing.T) {
client := &mockRESTClient{
putFunc: func(_ string, _ io.Reader, resp interface{}) error {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/MakeNowJust/heredoc v1.0.0
github.com/cli/go-gh/v2 v2.12.2
github.com/spf13/cobra v1.10.1
github.com/stretchr/testify v1.10.0
)

require (
Expand All @@ -23,7 +24,6 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/spf13/pflag v1.0.9 // indirect
github.com/stretchr/testify v1.10.0 // indirect
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/term v0.30.0 // indirect
Expand Down
Loading