Skip to content

Commit 07dfb5f

Browse files
Add runtime configuration support for deploy and get commands (#17)
Allows using `-c` to read app name from config file instead of requiring a `--app` param
1 parent ea930e6 commit 07dfb5f

4 files changed

Lines changed: 97 additions & 17 deletions

File tree

cmd/deploy.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/MakeNowJust/heredoc"
1313
"github.com/cli/go-gh/v2/pkg/api"
14+
"github.com/github/gh-runtime-cli/internal/config"
1415
"github.com/spf13/cobra"
1516
)
1617

@@ -19,6 +20,7 @@ type deployCmdFlags struct {
1920
app string
2021
revisionName string
2122
sha string
23+
config string
2224
}
2325

2426
func zipDirectory(sourceDir, destinationZip string) error {
@@ -91,25 +93,35 @@ func init() {
9193
Use: "deploy",
9294
Short: "Deploy app to GitHub Runtime",
9395
Long: heredoc.Doc(`
94-
Deploys a directory to a GitHub Runtime app
96+
Deploys a directory to a GitHub Runtime app.
97+
You can specify the app name using --app flag, --config flag to read from a runtime config file,
98+
or it will automatically read from runtime.config.json in the current directory if it exists.
9599
`),
96100
Example: heredoc.Doc(`
97101
$ gh runtime deploy --dir ./dist --app my-app [--sha <sha>]
98102
# => Deploys the contents of the 'dist' directory to the app named 'my-app'.
103+
104+
$ gh runtime deploy --dir ./dist --config runtime.config.json
105+
# => Deploys using app name from the config file.
106+
107+
$ gh runtime deploy --dir ./dist
108+
# => Deploys using app name from runtime.config.json in current directory (if it exists).
99109
`),
100110
RunE: func(cmd *cobra.Command, args []string) error {
101111
if deployCmdFlags.dir == "" {
102112
return fmt.Errorf("--dir flag is required")
103113
}
104-
if deployCmdFlags.app == "" {
105-
return fmt.Errorf("--app flag is required")
114+
115+
appName, err := config.ResolveAppName(deployCmdFlags.app, deployCmdFlags.config)
116+
if err != nil {
117+
return err
106118
}
107119

108120
if _, err := os.Stat(deployCmdFlags.dir); os.IsNotExist(err) {
109121
return fmt.Errorf("directory '%s' does not exist", deployCmdFlags.dir)
110122
}
111123

112-
_, err := os.ReadDir(deployCmdFlags.dir)
124+
_, err = os.ReadDir(deployCmdFlags.dir)
113125
if err != nil {
114126
return fmt.Errorf("error reading directory '%s': %v", deployCmdFlags.dir, err)
115127
}
@@ -127,7 +139,7 @@ func init() {
127139
return fmt.Errorf("error creating REST client: %v", err)
128140
}
129141

130-
deploymentsUrl := fmt.Sprintf("runtime/%s/deployment/bundle", deployCmdFlags.app)
142+
deploymentsUrl := fmt.Sprintf("runtime/%s/deployment/bundle", appName)
131143
params := url.Values{}
132144

133145
if deployCmdFlags.revisionName != "" {
@@ -161,6 +173,7 @@ func init() {
161173
}
162174
deployCmd.Flags().StringVarP(&deployCmdFlags.dir, "dir", "d", "", "The directory to deploy")
163175
deployCmd.Flags().StringVarP(&deployCmdFlags.app, "app", "a", "", "The app to deploy")
176+
deployCmd.Flags().StringVarP(&deployCmdFlags.config, "config", "c", "", "Path to runtime config file")
164177
deployCmd.Flags().StringVarP(&deployCmdFlags.revisionName, "revision-name", "r", "", "The revision name to deploy")
165178
deployCmd.Flags().StringVarP(&deployCmdFlags.sha, "sha", "s", "", "SHA of the app being deployed")
166179

cmd/get.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@ package cmd
33
import (
44
"fmt"
55
"net/url"
6+
67
"github.com/MakeNowJust/heredoc"
78
"github.com/cli/go-gh/v2/pkg/api"
9+
"github.com/github/gh-runtime-cli/internal/config"
810
"github.com/spf13/cobra"
911
)
1012

1113
type getCmdFlags struct {
12-
app string
13-
revisionName string
14+
app string
15+
revisionName string
16+
config string
1417
}
1518

1619
type serverResponse struct {
@@ -23,18 +26,27 @@ func init() {
2326
Use: "get",
2427
Short: "Get details of a GitHub Runtime app",
2528
Long: heredoc.Doc(`
26-
Get details of a GitHub Runtime app
29+
Get details of a GitHub Runtime app.
30+
You can specify the app name using --app flag, --config flag to read from a runtime config file,
31+
or it will automatically read from runtime.config.json in the current directory if it exists.
2732
`),
2833
Example: heredoc.Doc(`
2934
$ gh runtime get --app my-app
3035
# => Retrieves details of the app named 'my-app'
36+
37+
$ gh runtime get --config runtime.config.json
38+
# => Retrieves details using app name from the config file.
39+
40+
$ gh runtime get
41+
# => Retrieves details using app name from runtime.config.json in current directory (if it exists).
3142
`),
3243
RunE: func(cmd *cobra.Command, args []string) error {
33-
if getCmdFlags.app == "" {
34-
return fmt.Errorf("--app flag is required")
44+
appName, err := config.ResolveAppName(getCmdFlags.app, getCmdFlags.config)
45+
if err != nil {
46+
return err
3547
}
3648

37-
getUrl := fmt.Sprintf("runtime/%s/deployment", getCmdFlags.app)
49+
getUrl := fmt.Sprintf("runtime/%s/deployment", appName)
3850
params := url.Values{}
3951
if getCmdFlags.revisionName != "" {
4052
params.Add("revision_name", getCmdFlags.revisionName)
@@ -60,6 +72,7 @@ func init() {
6072
}
6173

6274
getCmd.Flags().StringVarP(&getCmdFlags.app, "app", "a", "", "The app to retrieve details for")
75+
getCmd.Flags().StringVarP(&getCmdFlags.config, "config", "c", "", "Path to runtime config file")
6376
getCmd.Flags().StringVarP(&getCmdFlags.revisionName, "revision-name", "r", "", "The revision name to use for the app")
6477
rootCmd.AddCommand(getCmd)
6578
}

cmd/init.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/MakeNowJust/heredoc"
1010
"github.com/cli/go-gh/v2/pkg/api"
11+
"github.com/github/gh-runtime-cli/internal/config"
1112
"github.com/spf13/cobra"
1213
)
1314

@@ -16,10 +17,6 @@ type initCmdFlags struct {
1617
out string
1718
}
1819

19-
type runtimeConfig struct {
20-
App string `json:"app"`
21-
}
22-
2320
type appResponse struct {
2421
AppUrl string `json:"app_url"`
2522
}
@@ -67,7 +64,7 @@ func init() {
6764
}
6865

6966
// Create runtime config
70-
config := runtimeConfig{
67+
configStruct := config.RuntimeConfig{
7168
App: initCmdFlags.app,
7269
}
7370

@@ -84,7 +81,7 @@ func init() {
8481
}
8582
}
8683

87-
configBytes, err := json.MarshalIndent(config, "", " ")
84+
configBytes, err := json.MarshalIndent(configStruct, "", " ")
8885
if err != nil {
8986
return fmt.Errorf("error creating configuration: %v", err)
9087
}

internal/config/config.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package config
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
)
8+
9+
// RuntimeConfig represents the structure of the runtime configuration file
10+
type RuntimeConfig struct {
11+
App string `json:"app"`
12+
}
13+
14+
// ReadRuntimeConfig reads and parses a runtime configuration file
15+
func ReadRuntimeConfig(configPath string) (string, error) {
16+
configBytes, err := os.ReadFile(configPath)
17+
if err != nil {
18+
return "", fmt.Errorf("error reading config file '%s': %w", configPath, err)
19+
}
20+
21+
var config RuntimeConfig
22+
err = json.Unmarshal(configBytes, &config)
23+
if err != nil {
24+
return "", fmt.Errorf("error parsing config file '%s': %w", configPath, err)
25+
}
26+
27+
return config.App, nil
28+
}
29+
30+
// ResolveAppName resolves the app name using the priority order:
31+
// 1. appFlag (--app) if provided
32+
// 2. configPath (--config) if provided
33+
// 3. runtime.config.json in current directory if it exists
34+
// Returns an error if no app name can be resolved
35+
func ResolveAppName(appFlag, configPath string) (string, error) {
36+
// Priority 1: Use --app flag if provided
37+
if appFlag != "" {
38+
return appFlag, nil
39+
}
40+
41+
// Priority 2: Use --config file if provided
42+
if configPath != "" {
43+
return ReadRuntimeConfig(configPath)
44+
}
45+
46+
// Priority 3: Try default runtime.config.json
47+
if _, err := os.Stat("runtime.config.json"); err == nil {
48+
appName, err := ReadRuntimeConfig("runtime.config.json")
49+
if err != nil {
50+
return "", fmt.Errorf("found runtime.config.json but failed to read it: %v", err)
51+
}
52+
return appName, nil
53+
}
54+
55+
// No app name could be resolved
56+
return "", fmt.Errorf("--app flag is required, --config must be specified, or runtime.config.json must exist in current directory")
57+
}

0 commit comments

Comments
 (0)