-
Notifications
You must be signed in to change notification settings - Fork 0
Add interactive feedback to remote builds #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
f7efbd3
1dada8e
eedf0dc
5577597
389e441
f202920
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,8 @@ package deploy | |
|
|
||
| import ( | ||
| "fmt" | ||
| "os" | ||
| "time" | ||
|
|
||
| "github.com/deviantony/pctl/internal/build" | ||
| "github.com/deviantony/pctl/internal/compose" | ||
|
|
@@ -12,6 +14,7 @@ import ( | |
|
|
||
| "github.com/charmbracelet/lipgloss" | ||
| "github.com/spf13/cobra" | ||
| "golang.org/x/term" | ||
| ) | ||
|
|
||
| var ( | ||
|
|
@@ -98,16 +101,43 @@ func runDeploy(cmd *cobra.Command, args []string) error { | |
| // Create Portainer client | ||
| client := portainer.NewClientWithTLS(cfg.PortainerURL, cfg.APIToken, cfg.SkipTLSVerify) | ||
|
|
||
| // Create build logger (use dashboard if interactive terminal with multiple services) | ||
| var logger build.BuildLogger = build.NewStyledBuildLogger("BUILD") | ||
| var dashboard *build.BuildDashboard | ||
|
|
||
| if term.IsTerminal(int(os.Stdout.Fd())) && len(servicesWithBuild) > 1 { | ||
| // Extract service names for dashboard | ||
| serviceNames := make([]string, len(servicesWithBuild)) | ||
| for i, svc := range servicesWithBuild { | ||
| serviceNames[i] = svc.ServiceName | ||
| } | ||
|
|
||
| // Create and start passive TUI dashboard | ||
| dashboard = build.NewBuildDashboard(serviceNames) | ||
| logger = build.NewDashboardBuildLogger(dashboard) | ||
| dashboard.Start() | ||
| } | ||
|
|
||
| // Create build orchestrator | ||
| logger := build.NewStyledBuildLogger("BUILD") | ||
| orchestrator := build.NewBuildOrchestrator(client, buildConfig, cfg.EnvironmentID, cfg.StackName, logger) | ||
|
|
||
| // Build services | ||
| imageTags, err := orchestrator.BuildServices(servicesWithBuild) | ||
| if err != nil { | ||
| // Stop dashboard before returning error | ||
| if dashboard != nil { | ||
| time.Sleep(1 * time.Second) | ||
| dashboard.Stop() | ||
| } | ||
| return fmt.Errorf("build failed: %w", err) | ||
| } | ||
|
|
||
| // Keep dashboard visible for a moment before stopping | ||
| if dashboard != nil { | ||
| time.Sleep(2 * time.Second) | ||
|
||
| dashboard.Stop() | ||
| } | ||
|
|
||
| // Transform compose file | ||
| transformer, err := compose.TransformComposeFile(composeContent, imageTags) | ||
| if err != nil { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,8 @@ package redeploy | |
|
|
||
| import ( | ||
| "fmt" | ||
| "os" | ||
| "time" | ||
|
|
||
| "github.com/deviantony/pctl/internal/build" | ||
| "github.com/deviantony/pctl/internal/compose" | ||
|
|
@@ -12,6 +14,7 @@ import ( | |
|
|
||
| "github.com/charmbracelet/lipgloss" | ||
| "github.com/spf13/cobra" | ||
| "golang.org/x/term" | ||
| ) | ||
|
|
||
| var ( | ||
|
|
@@ -111,16 +114,43 @@ func runRedeploy(cmd *cobra.Command, args []string) error { | |
| // Create Portainer client | ||
| client := portainer.NewClientWithTLS(cfg.PortainerURL, cfg.APIToken, cfg.SkipTLSVerify) | ||
|
|
||
| // Create build logger (use dashboard if interactive terminal with multiple services) | ||
| var logger build.BuildLogger = build.NewStyledBuildLogger("BUILD") | ||
| var dashboard *build.BuildDashboard | ||
|
|
||
| if term.IsTerminal(int(os.Stdout.Fd())) && len(servicesWithBuild) > 1 { | ||
| // Extract service names for dashboard | ||
| serviceNames := make([]string, len(servicesWithBuild)) | ||
| for i, svc := range servicesWithBuild { | ||
| serviceNames[i] = svc.ServiceName | ||
| } | ||
|
|
||
| // Create and start passive TUI dashboard | ||
| dashboard = build.NewBuildDashboard(serviceNames) | ||
| logger = build.NewDashboardBuildLogger(dashboard) | ||
| dashboard.Start() | ||
| } | ||
|
|
||
| // Create build orchestrator | ||
| logger := build.NewStyledBuildLogger("BUILD") | ||
| orchestrator := build.NewBuildOrchestrator(client, buildConfig, cfg.EnvironmentID, cfg.StackName, logger) | ||
|
|
||
| // Build services | ||
| imageTags, err := orchestrator.BuildServices(servicesWithBuild) | ||
| if err != nil { | ||
| // Stop dashboard before returning error | ||
| if dashboard != nil { | ||
| time.Sleep(1 * time.Second) | ||
|
||
| dashboard.Stop() | ||
| } | ||
| return fmt.Errorf("build failed: %w", err) | ||
| } | ||
|
|
||
| // Keep dashboard visible for a moment before stopping | ||
| if dashboard != nil { | ||
| time.Sleep(2 * time.Second) | ||
|
||
| dashboard.Stop() | ||
| } | ||
|
|
||
| // Transform compose file | ||
| transformer, err := compose.TransformComposeFile(composeContent, imageTags) | ||
| if err != nil { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The hardcoded sleep durations (1 second on error, 2 seconds on success) are magic numbers that make the code less maintainable. Consider:
dashboardErrorDisplayDuration,dashboardSuccessDisplayDuration)This would improve code readability and make it easier to adjust these values in the future.