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