1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-24 04:16:27 +02:00

138 lines
3.6 KiB
Go
Raw Normal View History

2017-09-11 23:31:00 -03:00
// Package docker provides a Pipe that creates and pushes a Docker image
package docker
import (
"fmt"
2017-09-12 07:54:43 -03:00
"os"
2017-09-11 23:31:00 -03:00
"os/exec"
"path/filepath"
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/pipeline"
2017-09-12 20:58:02 -03:00
"github.com/apex/log"
2017-09-11 23:50:57 -03:00
"github.com/pkg/errors"
2017-09-11 23:31:00 -03:00
)
2017-09-12 00:22:02 -03:00
// ErrNoDocker is shown when docker cannot be found in $PATH
var ErrNoDocker = errors.New("docker not present in $PATH")
// Pipe for docker
2017-09-11 23:31:00 -03:00
type Pipe struct{}
// Description of the pipe
func (Pipe) Description() string {
return "Creating Docker images"
}
// Run the pipe
2017-09-12 00:22:02 -03:00
func (Pipe) Run(ctx *context.Context) error {
if len(ctx.Config.Dockers) == 0 || ctx.Config.Dockers[0].Image == "" {
2017-09-11 23:31:00 -03:00
return pipeline.Skip("docker section is not configured")
}
2017-09-12 00:22:02 -03:00
_, err := exec.LookPath("docker")
if err != nil {
return ErrNoDocker
}
2017-09-14 21:19:56 -03:00
return doRun(ctx)
}
func doRun(ctx *context.Context) error {
2017-09-11 23:42:36 -03:00
for _, docker := range ctx.Config.Dockers {
2017-09-11 23:31:00 -03:00
var imagePlatform = docker.Goos + docker.Goarch + docker.Goarm
for platform, groups := range ctx.Binaries {
if platform != imagePlatform {
continue
}
for folder, binaries := range groups {
for _, binary := range binaries {
if binary.Name != docker.Binary {
continue
}
2017-09-14 21:19:56 -03:00
var err = process(ctx, folder, docker, binary)
2017-09-11 23:31:00 -03:00
if err != nil && !pipeline.IsSkip(err) {
return err
}
}
}
}
}
return nil
}
2017-09-14 21:19:56 -03:00
func process(ctx *context.Context, folder string, docker config.Docker, binary context.Binary) error {
2017-09-11 23:31:00 -03:00
var root = filepath.Join(ctx.Config.Dist, folder)
2017-09-12 10:04:56 -03:00
var dockerfile = filepath.Join(root, filepath.Base(docker.Dockerfile))
var image = fmt.Sprintf("%s:%s", docker.Image, ctx.Version)
2017-09-14 20:16:49 -03:00
var latest = fmt.Sprintf("%s:latest", docker.Image)
2017-09-11 23:31:00 -03:00
2017-09-12 07:54:43 -03:00
if err := os.Link(docker.Dockerfile, dockerfile); err != nil {
return errors.Wrap(err, "failed to link dockerfile")
2017-09-11 23:31:00 -03:00
}
2017-09-12 10:04:56 -03:00
if err := dockerBuild(root, dockerfile, image); err != nil {
2017-09-11 23:31:00 -03:00
return err
}
2017-09-14 20:16:49 -03:00
if docker.Latest {
if err := dockerTag(image, latest); err != nil {
return err
}
}
2017-09-12 07:54:43 -03:00
2017-09-22 09:26:19 -03:00
// TODO: improve this so it can log it to stdout
2017-09-11 23:31:00 -03:00
if !ctx.Publish {
return pipeline.Skip("--skip-publish is set")
}
2017-09-12 00:29:12 -03:00
if ctx.Config.Release.Draft {
return pipeline.Skip("release is marked as draft")
}
2017-09-11 23:31:00 -03:00
if err := dockerPush(image); err != nil {
return err
}
ctx.AddDocker(image)
2017-09-22 09:26:19 -03:00
if !docker.Latest {
return nil
}
if err := dockerTag(image, latest); err != nil {
return err
}
return dockerPush(latest)
2017-09-11 23:31:00 -03:00
}
2017-09-12 10:04:56 -03:00
func dockerBuild(root, dockerfile, image string) error {
2017-09-11 23:42:36 -03:00
log.WithField("image", image).Info("building docker image")
2017-09-12 10:04:56 -03:00
var cmd = exec.Command("docker", "build", "-f", dockerfile, "-t", image, root)
2017-09-11 23:31:00 -03:00
log.WithField("cmd", cmd).Debug("executing")
out, err := cmd.CombinedOutput()
if err != nil {
return errors.Wrapf(err, "failed to build docker image: \n%s", string(out))
}
log.Debugf("docker build output: \n%s", string(out))
return nil
}
2017-09-14 20:16:49 -03:00
func dockerTag(image, tag string) error {
2017-09-14 21:35:11 -03:00
log.WithField("image", image).WithField("tag", tag).Info("tagging docker image")
2017-09-14 20:16:49 -03:00
var cmd = exec.Command("docker", "tag", image, tag)
log.WithField("cmd", cmd).Debug("executing")
out, err := cmd.CombinedOutput()
if err != nil {
return errors.Wrapf(err, "failed to tag docker image: \n%s", string(out))
}
log.Debugf("docker tag output: \n%s", string(out))
return nil
}
2017-09-22 09:26:35 -03:00
func dockerPush(images string) error {
2017-09-11 23:42:36 -03:00
log.WithField("image", image).Info("pushing docker image")
2017-09-11 23:31:00 -03:00
var cmd = exec.Command("docker", "push", image)
log.WithField("cmd", cmd).Debug("executing")
out, err := cmd.CombinedOutput()
if err != nil {
return errors.Wrapf(err, "failed to push docker image: \n%s", string(out))
}
log.Debugf("docker push output: \n%s", string(out))
return nil
}