github.com/joselitofilho/goreleaser@v0.155.1-0.20210123221854-e4891856c593/cmd/release.go (about)

     1  package cmd
     2  
     3  import (
     4  	"runtime"
     5  	"time"
     6  
     7  	"github.com/apex/log"
     8  	"github.com/caarlos0/ctrlc"
     9  	"github.com/fatih/color"
    10  	"github.com/goreleaser/goreleaser/internal/middleware"
    11  	"github.com/goreleaser/goreleaser/internal/pipeline"
    12  	"github.com/goreleaser/goreleaser/pkg/context"
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  type releaseCmd struct {
    17  	cmd  *cobra.Command
    18  	opts releaseOpts
    19  }
    20  
    21  type releaseOpts struct {
    22  	config        string
    23  	releaseNotes  string
    24  	releaseHeader string
    25  	releaseFooter string
    26  	snapshot      bool
    27  	skipPublish   bool
    28  	skipSign      bool
    29  	skipValidate  bool
    30  	rmDist        bool
    31  	deprecated    bool
    32  	parallelism   int
    33  	timeout       time.Duration
    34  }
    35  
    36  func newReleaseCmd() *releaseCmd {
    37  	var root = &releaseCmd{}
    38  	// nolint: dupl
    39  	var cmd = &cobra.Command{
    40  		Use:           "release",
    41  		Aliases:       []string{"r"},
    42  		Short:         "Releases the current project",
    43  		SilenceUsage:  true,
    44  		SilenceErrors: true,
    45  		Args:          cobra.NoArgs,
    46  		RunE: func(cmd *cobra.Command, args []string) error {
    47  			start := time.Now()
    48  
    49  			log.Infof(color.New(color.Bold).Sprint("releasing..."))
    50  
    51  			ctx, err := releaseProject(root.opts)
    52  			if err != nil {
    53  				return wrapError(err, color.New(color.Bold).Sprintf("release failed after %0.2fs", time.Since(start).Seconds()))
    54  			}
    55  
    56  			if ctx.Deprecated {
    57  				log.Warn(color.New(color.Bold).Sprintf("your config is using deprecated properties, check logs above for details"))
    58  			}
    59  
    60  			log.Infof(color.New(color.Bold).Sprintf("release succeeded after %0.2fs", time.Since(start).Seconds()))
    61  			return nil
    62  		},
    63  	}
    64  
    65  	cmd.Flags().StringVarP(&root.opts.config, "config", "f", "", "Load configuration from file")
    66  	cmd.Flags().StringVar(&root.opts.releaseNotes, "release-notes", "", "Load custom release notes from a markdown file")
    67  	cmd.Flags().StringVar(&root.opts.releaseHeader, "release-header", "", "Load custom release notes header from a markdown file")
    68  	cmd.Flags().StringVar(&root.opts.releaseFooter, "release-footer", "", "Load custom release notes footer from a markdown file")
    69  	cmd.Flags().BoolVar(&root.opts.snapshot, "snapshot", false, "Generate an unversioned snapshot release, skipping all validations and without publishing any artifacts")
    70  	cmd.Flags().BoolVar(&root.opts.skipPublish, "skip-publish", false, "Skips publishing artifacts")
    71  	cmd.Flags().BoolVar(&root.opts.skipSign, "skip-sign", false, "Skips signing the artifacts")
    72  	cmd.Flags().BoolVar(&root.opts.skipValidate, "skip-validate", false, "Skips several sanity checks")
    73  	cmd.Flags().BoolVar(&root.opts.rmDist, "rm-dist", false, "Remove the dist folder before building")
    74  	cmd.Flags().IntVarP(&root.opts.parallelism, "parallelism", "p", runtime.NumCPU(), "Amount tasks to run concurrently")
    75  	cmd.Flags().DurationVar(&root.opts.timeout, "timeout", 30*time.Minute, "Timeout to the entire release process")
    76  	cmd.Flags().BoolVar(&root.opts.deprecated, "deprecated", false, "Force print the deprecation message - tests only")
    77  	_ = cmd.Flags().MarkHidden("deprecated")
    78  
    79  	root.cmd = cmd
    80  	return root
    81  }
    82  
    83  func releaseProject(options releaseOpts) (*context.Context, error) {
    84  	cfg, err := loadConfig(options.config)
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  	ctx, cancel := context.NewWithTimeout(cfg, options.timeout)
    89  	defer cancel()
    90  	setupReleaseContext(ctx, options)
    91  	return ctx, ctrlc.Default.Run(ctx, func() error {
    92  		for _, pipe := range pipeline.Pipeline {
    93  			if err := middleware.Logging(
    94  				pipe.String(),
    95  				middleware.ErrHandler(pipe.Run),
    96  				middleware.DefaultInitialPadding,
    97  			)(ctx); err != nil {
    98  				return err
    99  			}
   100  		}
   101  		return nil
   102  	})
   103  }
   104  
   105  func setupReleaseContext(ctx *context.Context, options releaseOpts) *context.Context {
   106  	ctx.Parallelism = options.parallelism
   107  	log.Debugf("parallelism: %v", ctx.Parallelism)
   108  	ctx.ReleaseNotes = options.releaseNotes
   109  	ctx.ReleaseHeader = options.releaseHeader
   110  	ctx.ReleaseFooter = options.releaseFooter
   111  	ctx.Snapshot = options.snapshot
   112  	ctx.SkipPublish = ctx.Snapshot || options.skipPublish
   113  	ctx.SkipValidate = ctx.Snapshot || options.skipValidate
   114  	ctx.SkipSign = options.skipSign
   115  	ctx.RmDist = options.rmDist
   116  
   117  	// test only
   118  	ctx.Deprecated = options.deprecated
   119  	return ctx
   120  }