github.com/tilt-dev/tilt@v0.36.0/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 addLogFilterFlags(cmd, "log-") 53 addLogFilterResourcesFlag(cmd) 54 55 cmd.Flags().BoolVar(&logActionsFlag, "logactions", false, "log all actions and state changes") 56 cmd.Flags().Lookup("logactions").Hidden = true 57 cmd.Flags().StringVar(&c.outputSnapshotOnExit, "output-snapshot-on-exit", "", 58 "If specified, Tilt will dump a snapshot of its state to the specified path when it exits") 59 cmd.Flags().DurationVar(&ciTimeout, "timeout", model.CITimeoutDefault, 60 "Timeout to wait for CI to pass. Set to 0 for no timeout.") 61 62 return cmd 63 } 64 65 func (c *ciCmd) run(ctx context.Context, args []string) error { 66 a := analytics.Get(ctx) 67 a.Incr("cmd.ci", nil) 68 defer a.Flush(time.Second) 69 70 deferred := logger.NewDeferredLogger(ctx) 71 ctx = redirectLogs(ctx, deferred) 72 73 log.SetFlags(log.Flags() &^ (log.Ldate | log.Ltime)) 74 75 webHost := provideWebHost() 76 webURL, _ := provideWebURL(webHost, provideWebPort()) 77 startLine := prompt.StartStatusLine(webURL, webHost) 78 log.Print(startLine) 79 log.Print(buildStamp()) 80 81 if ok, reason := analytics.IsAnalyticsDisabledFromEnv(); ok { 82 log.Printf("Tilt analytics disabled: %s", reason) 83 } 84 85 cmdCIDeps, err := wireCmdCI(ctx, a, "ci") 86 if err != nil { 87 deferred.SetOutput(deferred.Original()) 88 return err 89 } 90 91 upper := cmdCIDeps.Upper 92 93 l := store.NewLogActionLogger(ctx, upper.Dispatch) 94 deferred.SetOutput(l) 95 ctx = redirectLogs(ctx, l) 96 if c.outputSnapshotOnExit != "" { 97 defer cmdCIDeps.Snapshotter.WriteSnapshot(ctx, c.outputSnapshotOnExit) 98 } 99 100 err = upper.Start(ctx, args, cmdCIDeps.TiltBuild, 101 c.fileName, store.TerminalModeStream, a.UserOpt(), cmdCIDeps.Token, 102 string(cmdCIDeps.CloudAddress)) 103 if err == nil { 104 _, _ = fmt.Fprintln(colorable.NewColorableStdout(), 105 color.GreenString("SUCCESS. All workloads are healthy.")) 106 } 107 return err 108 } 109 110 var ciTimeout time.Duration