mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-02-03 13:11:48 +02:00
draft: docker support
This commit is contained in:
parent
48b21c3690
commit
b9e8ed64d1
@ -4,15 +4,21 @@ builds:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
# - darwin
|
||||
# - windows
|
||||
goarch:
|
||||
- 386
|
||||
# - 386
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
# - arm
|
||||
# - arm64
|
||||
checksum:
|
||||
name_template: '{{ .ProjectName }}_checksums.txt'
|
||||
docker:
|
||||
- goos: linux
|
||||
goarch: amd64
|
||||
binary: goreleaser
|
||||
dockerfile: Dockerfile
|
||||
image: caarlos0/goreleaser
|
||||
archive:
|
||||
name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
|
||||
replacements:
|
||||
|
4
Dockerfile
Normal file
4
Dockerfile
Normal file
@ -0,0 +1,4 @@
|
||||
FROM scratch
|
||||
COPY goreleaser /goreleaser
|
||||
ENTRYPOINT ["/goreleaser"]
|
||||
|
@ -159,6 +159,19 @@ type Checksum struct {
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// Docker image config
|
||||
type Docker struct {
|
||||
Binary string `yaml:",omitempty"`
|
||||
Goos string `yaml:",omitempty"`
|
||||
Goarch string `yaml:",omitempty"`
|
||||
Goarm string `yaml:",omitempty"`
|
||||
Image string `yaml:",omitempty"`
|
||||
Dockerfile string `yaml:",omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// Project includes all project configuration
|
||||
type Project struct {
|
||||
ProjectName string `yaml:"project_name,omitempty"`
|
||||
@ -170,6 +183,7 @@ type Project struct {
|
||||
Snapcraft Snapcraft `yaml:",omitempty"`
|
||||
Snapshot Snapshot `yaml:",omitempty"`
|
||||
Checksum Checksum `yaml:",omitempty"`
|
||||
Docker []Docker `yaml:",omitempty"`
|
||||
|
||||
// this is a hack ¯\_(ツ)_/¯
|
||||
SingleBuild Build `yaml:"build,omitempty"`
|
||||
@ -231,6 +245,9 @@ func checkOverflows(config Project) error {
|
||||
}
|
||||
overflow.check(config.Snapshot.XXX, "snapshot")
|
||||
overflow.check(config.Checksum.XXX, "checksum")
|
||||
for i, docker := range config.Docker {
|
||||
overflow.check(docker.XXX, fmt.Sprintf("docker[%d]", i))
|
||||
}
|
||||
return overflow.err()
|
||||
}
|
||||
|
||||
|
@ -10,17 +10,12 @@ import (
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/pipeline"
|
||||
"github.com/goreleaser/goreleaser/pipeline/archive"
|
||||
"github.com/goreleaser/goreleaser/pipeline/brew"
|
||||
"github.com/goreleaser/goreleaser/pipeline/build"
|
||||
"github.com/goreleaser/goreleaser/pipeline/checksums"
|
||||
"github.com/goreleaser/goreleaser/pipeline/cleandist"
|
||||
"github.com/goreleaser/goreleaser/pipeline/defaults"
|
||||
"github.com/goreleaser/goreleaser/pipeline/docker"
|
||||
"github.com/goreleaser/goreleaser/pipeline/env"
|
||||
"github.com/goreleaser/goreleaser/pipeline/fpm"
|
||||
"github.com/goreleaser/goreleaser/pipeline/git"
|
||||
"github.com/goreleaser/goreleaser/pipeline/release"
|
||||
"github.com/goreleaser/goreleaser/pipeline/snapcraft"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
@ -30,12 +25,13 @@ var pipes = []pipeline.Pipe{
|
||||
env.Pipe{}, // load and validate environment variables
|
||||
cleandist.Pipe{}, // ensure ./dist is clean
|
||||
build.Pipe{}, // build
|
||||
archive.Pipe{}, // archive (tar.gz, zip, etc)
|
||||
fpm.Pipe{}, // archive via fpm (deb, rpm, etc)
|
||||
snapcraft.Pipe{}, // archive via snapcraft (snap)
|
||||
checksums.Pipe{}, // checksums of the files
|
||||
release.Pipe{}, // release to github
|
||||
brew.Pipe{}, // push to brew tap
|
||||
// archive.Pipe{}, // archive (tar.gz, zip, etc)
|
||||
// fpm.Pipe{}, // archive via fpm (deb, rpm, etc)
|
||||
// snapcraft.Pipe{}, // archive via snapcraft (snap)
|
||||
// checksums.Pipe{}, // checksums of the files
|
||||
// release.Pipe{}, // release to github
|
||||
// brew.Pipe{}, // push to brew tap
|
||||
docker.Pipe{}, // create and push docker images
|
||||
}
|
||||
|
||||
// Flags interface represents an extractor of cli flags
|
||||
|
107
pipeline/docker/docker.go
Normal file
107
pipeline/docker/docker.go
Normal file
@ -0,0 +1,107 @@
|
||||
// Package docker provides a Pipe that creates and pushes a Docker image
|
||||
package docker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/pipeline"
|
||||
)
|
||||
|
||||
// Pipe for checksums
|
||||
type Pipe struct{}
|
||||
|
||||
// Description of the pipe
|
||||
func (Pipe) Description() string {
|
||||
return "Creating Docker images"
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
func (Pipe) Run(ctx *context.Context) (err error) {
|
||||
if ctx.Config.Docker[0].Image == "" {
|
||||
return pipeline.Skip("docker section is not configured")
|
||||
}
|
||||
if ctx.Config.Release.Draft {
|
||||
return pipeline.Skip("release is marked as draft")
|
||||
}
|
||||
for _, docker := range ctx.Config.Docker {
|
||||
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
|
||||
}
|
||||
var err = doRun(ctx, folder, docker, binary)
|
||||
if err != nil && !pipeline.IsSkip(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processDocker(ctx *context.Context, docker config.Docker) error {
|
||||
|
||||
}
|
||||
|
||||
func doRun(ctx *context.Context, folder string, docker config.Docker, binary context.Binary) error {
|
||||
var root = filepath.Join(ctx.Config.Dist, folder)
|
||||
var dockerfile = filepath.Join(root, "Dockerfile")
|
||||
var image = fmt.Sprintf("%s:%s", docker.Image, ctx.Version)
|
||||
|
||||
bts, err := ioutil.ReadFile(docker.Dockerfile)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to read dockerfile")
|
||||
}
|
||||
if err := ioutil.WriteFile(dockerfile, bts, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
log.WithField("file", dockerfile).Info("wrote dockerfile")
|
||||
if err := dockerBuild(root, image); err != nil {
|
||||
return err
|
||||
}
|
||||
if !ctx.Publish {
|
||||
return pipeline.Skip("--skip-publish is set")
|
||||
}
|
||||
if err := dockerPush(image); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func dockerBuild(root, image string) error {
|
||||
log.Infof("building docker image: %s", image)
|
||||
var cmd = exec.Command("docker", "build", "-t", image, root)
|
||||
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
|
||||
}
|
||||
|
||||
func dockerPush(image string) error {
|
||||
log.Infof("pushing docker image: %s", image)
|
||||
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
|
||||
}
|
@ -12,6 +12,11 @@ type Pipe interface {
|
||||
Run(ctx *context.Context) error
|
||||
}
|
||||
|
||||
func IsSkip(err error) bool {
|
||||
_, ok := err.(ErrSkip)
|
||||
return ok
|
||||
}
|
||||
|
||||
// ErrSkip occurs when a pipe is skipped for some reason
|
||||
type ErrSkip struct {
|
||||
reason string
|
||||
|
Loading…
x
Reference in New Issue
Block a user