Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Add runtime configuration support for deploy and get commands
  • Loading branch information
salvador-barboza committed Sep 30, 2025
commit 9c4116fff8c67215798ad97ad65d60c9f5a0c995
29 changes: 29 additions & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cmd

import (
"encoding/json"
"fmt"
"os"
)

// runtimeConfig represents the structure of the runtime configuration file
type runtimeConfig struct {
App string `json:"app"`
}

// readRuntimeConfig reads and parses a runtime configuration file,
// returning the app name specified in the config
func readRuntimeConfig(configPath string) (string, error) {
configBytes, err := os.ReadFile(configPath)
if err != nil {
return "", fmt.Errorf("error reading config file '%s': %w", configPath, err)
}

var config runtimeConfig
err = json.Unmarshal(configBytes, &config)
if err != nil {
return "", fmt.Errorf("error parsing config file '%s': %w", configPath, err)
}

return config.App, nil
}
Comment thread
salvador-barboza marked this conversation as resolved.
Outdated
42 changes: 38 additions & 4 deletions cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/MakeNowJust/heredoc"
"github.com/cli/go-gh/v2/pkg/api"
"github.com/github/gh-runtime-cli/internal/config"
"github.com/spf13/cobra"
)

Expand All @@ -19,6 +20,7 @@ type deployCmdFlags struct {
app string
revisionName string
sha string
config string
}

func zipDirectory(sourceDir, destinationZip string) error {
Expand Down Expand Up @@ -91,18 +93,49 @@ func init() {
Use: "deploy",
Short: "Deploy app to GitHub Runtime",
Long: heredoc.Doc(`
Deploys a directory to a GitHub Runtime app
Deploys a directory to a GitHub Runtime app.
You can specify the app name using --app flag, --config flag to read from a runtime config file,
or it will automatically read from runtime.config.json in the current directory if it exists.
`),
Example: heredoc.Doc(`
$ gh runtime deploy --dir ./dist --app my-app [--sha <sha>]
# => Deploys the contents of the 'dist' directory to the app named 'my-app'.

$ gh runtime deploy --dir ./dist --config runtime.config.json
# => Deploys using app name from the config file.

$ gh runtime deploy --dir ./dist
# => Deploys using app name from runtime.config.json in current directory (if it exists).
`),
RunE: func(cmd *cobra.Command, args []string) error {
if deployCmdFlags.dir == "" {
return fmt.Errorf("--dir flag is required")
}
if deployCmdFlags.app == "" {
return fmt.Errorf("--app flag is required")

appName := deployCmdFlags.app

// If config file is provided, read app name from it
if deployCmdFlags.config != "" {
configApp, err := config.ReadRuntimeConfig(deployCmdFlags.config)
if err != nil {
return err
}
if appName == "" {
appName = configApp
}
} else if appName == "" {
// Try to read from default config file if neither --app nor --config is provided
if _, err := os.Stat("runtime.config.json"); err == nil {
configApp, err := config.ReadRuntimeConfig("runtime.config.json")
if err != nil {
return fmt.Errorf("found runtime.config.json but failed to read it: %v", err)
}
appName = configApp
}
}

if appName == "" {
return fmt.Errorf("--app flag is required, --config must be specified, or runtime.config.json must exist in current directory")
}

if _, err := os.Stat(deployCmdFlags.dir); os.IsNotExist(err) {
Expand All @@ -127,7 +160,7 @@ func init() {
return fmt.Errorf("error creating REST client: %v", err)
}

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

if deployCmdFlags.revisionName != "" {
Expand Down Expand Up @@ -161,6 +194,7 @@ func init() {
}
deployCmd.Flags().StringVarP(&deployCmdFlags.dir, "dir", "d", "", "The directory to deploy")
deployCmd.Flags().StringVarP(&deployCmdFlags.app, "app", "a", "", "The app to deploy")
deployCmd.Flags().StringVarP(&deployCmdFlags.config, "config", "c", "", "Path to runtime config file")
deployCmd.Flags().StringVarP(&deployCmdFlags.revisionName, "revision-name", "r", "", "The revision name to deploy")
deployCmd.Flags().StringVarP(&deployCmdFlags.sha, "sha", "s", "", "SHA of the app being deployed")

Expand Down
47 changes: 41 additions & 6 deletions cmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ package cmd
import (
"fmt"
"net/url"
"os"

"github.com/MakeNowJust/heredoc"
"github.com/cli/go-gh/v2/pkg/api"
"github.com/github/gh-runtime-cli/internal/config"
"github.com/spf13/cobra"
)

type getCmdFlags struct {
app string
revisionName string
app string
revisionName string
config string
}

type serverResponse struct {
Expand All @@ -23,18 +27,48 @@ func init() {
Use: "get",
Short: "Get details of a GitHub Runtime app",
Long: heredoc.Doc(`
Get details of a GitHub Runtime app
Get details of a GitHub Runtime app.
You can specify the app name using --app flag, --config flag to read from a runtime config file,
or it will automatically read from runtime.config.json in the current directory if it exists.
`),
Example: heredoc.Doc(`
$ gh runtime get --app my-app
# => Retrieves details of the app named 'my-app'

$ gh runtime get --config runtime.config.json
# => Retrieves details using app name from the config file.

$ gh runtime get
# => Retrieves details using app name from runtime.config.json in current directory (if it exists).
`),
RunE: func(cmd *cobra.Command, args []string) error {
if getCmdFlags.app == "" {
return fmt.Errorf("--app flag is required")
appName := getCmdFlags.app

// If config file is provided, read app name from it
if getCmdFlags.config != "" {
configApp, err := config.ReadRuntimeConfig(getCmdFlags.config)
if err != nil {
return err
}
if appName == "" {
appName = configApp
}
} else if appName == "" {
// Try to read from default config file if neither --app nor --config is provided
if _, err := os.Stat("runtime.config.json"); err == nil {
configApp, err := config.ReadRuntimeConfig("runtime.config.json")
if err != nil {
return fmt.Errorf("found runtime.config.json but failed to read it: %v", err)
}
appName = configApp
}
}

if appName == "" {
return fmt.Errorf("--app flag is required, --config must be specified, or runtime.config.json must exist in current directory")
}

getUrl := fmt.Sprintf("runtime/%s/deployment", getCmdFlags.app)
getUrl := fmt.Sprintf("runtime/%s/deployment", appName)
params := url.Values{}
if getCmdFlags.revisionName != "" {
params.Add("revision_name", getCmdFlags.revisionName)
Expand All @@ -60,6 +94,7 @@ func init() {
}

getCmd.Flags().StringVarP(&getCmdFlags.app, "app", "a", "", "The app to retrieve details for")
getCmd.Flags().StringVarP(&getCmdFlags.config, "config", "c", "", "Path to runtime config file")
getCmd.Flags().StringVarP(&getCmdFlags.revisionName, "revision-name", "r", "", "The revision name to use for the app")
rootCmd.AddCommand(getCmd)
}
9 changes: 3 additions & 6 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/MakeNowJust/heredoc"
"github.com/cli/go-gh/v2/pkg/api"
"github.com/github/gh-runtime-cli/internal/config"
"github.com/spf13/cobra"
)

Expand All @@ -16,10 +17,6 @@ type initCmdFlags struct {
out string
}

type runtimeConfig struct {
App string `json:"app"`
}

type appResponse struct {
AppUrl string `json:"app_url"`
}
Expand Down Expand Up @@ -67,7 +64,7 @@ func init() {
}

// Create runtime config
config := runtimeConfig{
configStruct := config.RuntimeConfig{
App: initCmdFlags.app,
}

Expand All @@ -84,7 +81,7 @@ func init() {
}
}

configBytes, err := json.MarshalIndent(config, "", " ")
configBytes, err := json.MarshalIndent(configStruct, "", " ")
if err != nil {
return fmt.Errorf("error creating configuration: %v", err)
}
Expand Down
28 changes: 28 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package config

import (
"encoding/json"
"fmt"
"os"
)

// RuntimeConfig represents the structure of the runtime configuration file
type RuntimeConfig struct {
App string `json:"app"`
}

// ReadRuntimeConfig reads and parses a runtime configuration file
func ReadRuntimeConfig(configPath string) (string, error) {
configBytes, err := os.ReadFile(configPath)
if err != nil {
return "", fmt.Errorf("error reading config file '%s': %w", configPath, err)
}

var config RuntimeConfig
err = json.Unmarshal(configBytes, &config)
if err != nil {
return "", fmt.Errorf("error parsing config file '%s': %w", configPath, err)
}

return config.App, nil
}