Skip to content
Closed
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
51 changes: 45 additions & 6 deletions internal/command/update.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package command

import (
"context"
"fmt"

"github.com/spf13/cobra"

"github.com/basecamp/once/internal/docker"
"github.com/basecamp/once/internal/version"
)

Expand All @@ -13,12 +17,47 @@ type updateCommand struct {
func newUpdateCommand() *updateCommand {
u := &updateCommand{}
u.cmd = &cobra.Command{
Use: "update",
Short: "Update once to the latest version",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return version.NewUpdater().UpdateBinary()
},
Use: "update [app]",
Short: "Update once to the latest version, or update a specific application",
Args: cobra.MaximumNArgs(1),
RunE: WithNamespace(u.run),
}
return u
}

// Private

func (u *updateCommand) run(ctx context.Context, ns *docker.Namespace, cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return version.NewUpdater().UpdateBinary()
}

appName := args[0]
progress := func(p docker.DeployProgress) {
switch p.Stage {
case docker.DeployStageDownloading:
fmt.Printf("Downloading: %d%%\n", p.Percentage)
case docker.DeployStageStarting:
fmt.Println("Starting...")
case docker.DeployStageFinished:
fmt.Println("Finished")
}
}

var changed bool
err := withApplication(ns, appName, "updating", func(app *docker.Application) error {
var err error
changed, err = app.Update(ctx, progress)
return err
})
Comment on lines +38 to +43
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This updates the app regardless of whether it's currently running. Since app.Update deploys a new container and re-registers with the proxy, once update <app> could unintentionally start an app that was previously stopped. If the intention is to match the background runner logic, add a guard (e.g., require app.Running or otherwise avoid deploying when the app is stopped) and return a clear message/error when the app isn't running.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's a problem, if you use this command I assume you plan to deploy the app

if err != nil {
return err
}

if changed {
fmt.Printf("Updated %s\n", appName)
} else {
fmt.Printf("%s is already up to date\n", appName)
}
return nil
}
Loading