github.com/goenning/goreleaser@v0.36.0/goreleaserlib/goreleaser.go (about)

     1  package goreleaserlib
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/apex/log"
    10  	"github.com/goreleaser/goreleaser/config"
    11  	"github.com/goreleaser/goreleaser/context"
    12  	"github.com/goreleaser/goreleaser/pipeline"
    13  	"github.com/goreleaser/goreleaser/pipeline/archive"
    14  	"github.com/goreleaser/goreleaser/pipeline/brew"
    15  	"github.com/goreleaser/goreleaser/pipeline/build"
    16  	"github.com/goreleaser/goreleaser/pipeline/changelog"
    17  	"github.com/goreleaser/goreleaser/pipeline/checksums"
    18  	"github.com/goreleaser/goreleaser/pipeline/cleandist"
    19  	"github.com/goreleaser/goreleaser/pipeline/defaults"
    20  	"github.com/goreleaser/goreleaser/pipeline/docker"
    21  	"github.com/goreleaser/goreleaser/pipeline/env"
    22  	"github.com/goreleaser/goreleaser/pipeline/fpm"
    23  	"github.com/goreleaser/goreleaser/pipeline/git"
    24  	"github.com/goreleaser/goreleaser/pipeline/release"
    25  	"github.com/goreleaser/goreleaser/pipeline/snapcraft"
    26  	yaml "gopkg.in/yaml.v2"
    27  )
    28  
    29  var pipes = []pipeline.Pipe{
    30  	defaults.Pipe{},  // load default configs
    31  	git.Pipe{},       // get and validate git repo state
    32  	changelog.Pipe{}, // builds the release changelog
    33  	env.Pipe{},       // load and validate environment variables
    34  	cleandist.Pipe{}, // ensure ./dist is clean
    35  	build.Pipe{},     // build
    36  	archive.Pipe{},   // archive (tar.gz, zip, etc)
    37  	fpm.Pipe{},       // archive via fpm (deb, rpm, etc)
    38  	snapcraft.Pipe{}, // archive via snapcraft (snap)
    39  	checksums.Pipe{}, // checksums of the files
    40  	docker.Pipe{},    // create and push docker images
    41  	release.Pipe{},   // release to github
    42  	brew.Pipe{},      // push to brew tap
    43  }
    44  
    45  // Flags interface represents an extractor of cli flags
    46  type Flags interface {
    47  	IsSet(s string) bool
    48  	String(s string) string
    49  	Int(s string) int
    50  	Bool(s string) bool
    51  }
    52  
    53  // Release runs the release process with the given flags
    54  func Release(flags Flags) error {
    55  	var file = getConfigFile(flags)
    56  	var notes = flags.String("release-notes")
    57  	if flags.Bool("debug") {
    58  		log.SetLevel(log.DebugLevel)
    59  	}
    60  	cfg, err := config.Load(file)
    61  	if err != nil {
    62  		// Allow file not found errors if config file was not
    63  		// explicitly specified
    64  		_, statErr := os.Stat(file)
    65  		if !os.IsNotExist(statErr) || flags.IsSet("config") {
    66  			return err
    67  		}
    68  		log.WithField("file", file).Warn("could not load config, using defaults")
    69  	}
    70  	var ctx = context.New(cfg)
    71  	ctx.Parallelism = flags.Int("parallelism")
    72  	ctx.Debug = flags.Bool("debug")
    73  	log.Debugf("parallelism: %v", ctx.Parallelism)
    74  	ctx.Validate = !flags.Bool("skip-validate")
    75  	ctx.Publish = !flags.Bool("skip-publish")
    76  	if notes != "" {
    77  		bts, err := ioutil.ReadFile(notes)
    78  		if err != nil {
    79  			return err
    80  		}
    81  		log.WithField("file", notes).Info("loaded custom release notes")
    82  		log.WithField("file", notes).Debugf("custon release notes: \n%s", string(bts))
    83  		ctx.ReleaseNotes = string(bts)
    84  	}
    85  	ctx.Snapshot = flags.Bool("snapshot")
    86  	if ctx.Snapshot {
    87  		log.Info("publishing disabled in snapshot mode")
    88  		ctx.Publish = false
    89  	}
    90  	ctx.RmDist = flags.Bool("rm-dist")
    91  	for _, pipe := range pipes {
    92  		log.Infof("\033[1m%s\033[0m", strings.ToUpper(pipe.Description()))
    93  		if err := handle(pipe.Run(ctx)); err != nil {
    94  			return err
    95  		}
    96  	}
    97  	log.Infof("\033[1mSUCCESS!\033[0m")
    98  	return nil
    99  }
   100  
   101  func handle(err error) error {
   102  	if err == nil {
   103  		return nil
   104  	}
   105  	if pipeline.IsSkip(err) {
   106  		log.WithField("reason", err.Error()).Warn("skipped")
   107  		return nil
   108  	}
   109  	return err
   110  }
   111  
   112  // InitProject creates an example goreleaser.yml in the current directory
   113  func InitProject(filename string) error {
   114  	if _, err := os.Stat(filename); !os.IsNotExist(err) {
   115  		if err != nil {
   116  			return err
   117  		}
   118  		return fmt.Errorf("%s already exists", filename)
   119  	}
   120  
   121  	var ctx = context.New(config.Project{})
   122  	var pipe = defaults.Pipe{}
   123  	if err := pipe.Run(ctx); err != nil {
   124  		return err
   125  	}
   126  	out, err := yaml.Marshal(ctx.Config)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	return ioutil.WriteFile(filename, out, 0644)
   132  }
   133  
   134  func getConfigFile(flags Flags) string {
   135  	var config = flags.String("config")
   136  	if flags.IsSet("config") {
   137  		return config
   138  	}
   139  	for _, f := range []string{
   140  		".goreleaser.yml",
   141  		".goreleaser.yaml",
   142  		"goreleaser.yml",
   143  		"goreleaser.yaml",
   144  	} {
   145  		_, ferr := os.Stat(f)
   146  		if ferr == nil || os.IsExist(ferr) {
   147  			return f
   148  		}
   149  	}
   150  	return config
   151  }