github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/cli/ci.go (about) 1 package cli 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "time" 8 9 "github.com/fatih/color" 10 "github.com/mattn/go-colorable" 11 "github.com/spf13/cobra" 12 13 "github.com/tilt-dev/tilt/internal/analytics" 14 "github.com/tilt-dev/tilt/internal/hud/prompt" 15 "github.com/tilt-dev/tilt/internal/store" 16 "github.com/tilt-dev/tilt/pkg/logger" 17 "github.com/tilt-dev/tilt/pkg/model" 18 ) 19 20 type ciCmd struct { 21 fileName string 22 outputSnapshotOnExit string 23 } 24 25 func (c *ciCmd) name() model.TiltSubcommand { return "ci" } 26 27 func (c *ciCmd) register() *cobra.Command { 28 cmd := &cobra.Command{ 29 Use: "ci [<tilt flags>] [-- <Tiltfile args>]", 30 DisableFlagsInUseLine: true, 31 Short: "Start Tilt in CI/batch mode with the given Tiltfile args", 32 Long: fmt.Sprintf(` 33 Starts Tilt and runs resources defined in the Tiltfile. 34 35 Exits with failure if any build fails or any server crashes. 36 37 Exits with success if all tasks have completed successfully 38 and all servers are healthy. 39 40 While Tilt is running, you can view the UI at %s:%d 41 (configurable with --host and --port). 42 43 See blog post for additional information: https://blog.tilt.dev/2020/04/16/how-to-not-break-server-startup.html 44 `, defaultWebHost, defaultWebPort), 45 } 46 47 addStartServerFlags(cmd) 48 addDevServerFlags(cmd) 49 addTiltfileFlag(cmd, &c.fileName) 50 addKubeContextFlag(cmd) 51 addNamespaceFlag(cmd) 52 53 cmd.Flags().BoolVar(&logActionsFlag, "logactions", false, "log all actions and state changes") 54 cmd.Flags().Lookup("logactions").Hidden = true 55 cmd.Flags().StringVar(&c.outputSnapshotOnExit, "output-snapshot-on-exit", "", 56 "If specified, Tilt will dump a snapshot of its state to the specified path when it exits") 57 cmd.Flags().DurationVar(&ciTimeout, "timeout", model.CITimeoutDefault, 58 "Timeout to wait for CI to pass. Set to 0 for no timeout.") 59 60 return cmd 61 } 62 63 func (c *ciCmd) run(ctx context.Context, args []string) error { 64 a := analytics.Get(ctx) 65 a.Incr("cmd.ci", nil) 66 defer a.Flush(time.Second) 67 68 deferred := logger.NewDeferredLogger(ctx) 69 ctx = redirectLogs(ctx, deferred) 70 71 log.SetFlags(log.Flags() &^ (log.Ldate | log.Ltime)) 72 73 webHost := provideWebHost() 74 webURL, _ := provideWebURL(webHost, provideWebPort()) 75 startLine := prompt.StartStatusLine(webURL, webHost) 76 log.Print(startLine) 77 log.Print(buildStamp()) 78 79 if ok, reason := analytics.IsAnalyticsDisabledFromEnv(); ok { 80 log.Printf("Tilt analytics disabled: %s", reason) 81 } 82 83 cmdCIDeps, err := wireCmdCI(ctx, a, "ci") 84 if err != nil { 85 deferred.SetOutput(deferred.Original()) 86 return err 87 } 88 89 upper := cmdCIDeps.Upper 90 91 l := store.NewLogActionLogger(ctx, upper.Dispatch) 92 deferred.SetOutput(l) 93 ctx = redirectLogs(ctx, l) 94 if c.outputSnapshotOnExit != "" { 95 defer cmdCIDeps.Snapshotter.WriteSnapshot(ctx, c.outputSnapshotOnExit) 96 } 97 98 err = upper.Start(ctx, args, cmdCIDeps.TiltBuild, 99 c.fileName, store.TerminalModeStream, a.UserOpt(), cmdCIDeps.Token, 100 string(cmdCIDeps.CloudAddress)) 101 if err == nil { 102 _, _ = fmt.Fprintln(colorable.NewColorableStdout(), 103 color.GreenString("SUCCESS. All workloads are healthy.")) 104 } 105 return err 106 } 107 108 var ciTimeout time.Duration