You've already forked goreleaser
mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-11-06 09:09:29 +02:00
feat(docker): add buildpacks support (#2461)
* feat(docker): add buildpacks support Signed-off-by: Erkan Zileli <erkanzileli@gmail.com> * fix: move buildpacker imager code into own go file Signed-off-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com> * fix: use docker imager push method for buildpack imager push Signed-off-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com> * fix: return statement Signed-off-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com> * move test into api_buildback_test Signed-off-by: Furkan <furkan.turkal@trendyol.com> * fix: use buildpacks instead of buildpack Signed-off-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com> * fix(lint): fix lint issue * fix(buildpacks): use cwd instead of root directory * doc: add how to use a custom buildpack document Signed-off-by: Erkan Zileli <erkan.zileli@trendyol.com> * fix(doc): update docs as suggested Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> Co-authored-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com> Co-authored-by: Furkan <furkan.turkal@trendyol.com> Co-authored-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
40
internal/pipe/docker/api_buildpack.go
Normal file
40
internal/pipe/docker/api_buildpack.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type buildPackImager struct{}
|
||||||
|
|
||||||
|
func (i buildPackImager) Push(ctx context.Context, image string, flags []string) error {
|
||||||
|
return dockerImager{}.Push(ctx, image, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i buildPackImager) Build(ctx context.Context, root string, images, flags []string) error {
|
||||||
|
if err := runCommand(ctx, "", "pack", i.buildCommand(images, flags)...); err != nil {
|
||||||
|
return fmt.Errorf("failed to build %s: %w", images[0], err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i buildPackImager) buildCommand(images, flags []string) []string {
|
||||||
|
base := []string{"build", images[0]}
|
||||||
|
for j := 1; j < len(images); j++ {
|
||||||
|
base = append(base, "-t", images[j])
|
||||||
|
}
|
||||||
|
|
||||||
|
builderConfigured := false
|
||||||
|
for _, flag := range flags {
|
||||||
|
if strings.HasPrefix(flag, "-B") || strings.HasPrefix(flag, "--builder") {
|
||||||
|
builderConfigured = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !builderConfigured {
|
||||||
|
flags = append(flags, "--builder=gcr.io/buildpacks/builder:v1")
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(base, flags...)
|
||||||
|
}
|
||||||
48
internal/pipe/docker/api_buildpack_test.go
Normal file
48
internal/pipe/docker/api_buildpack_test.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuildCommandForBuildPack(t *testing.T) {
|
||||||
|
images := []string{"goreleaser/test_build_flag", "goreleaser/test_multiple_tags"}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
flags []string
|
||||||
|
expect []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no flags without builder",
|
||||||
|
flags: []string{},
|
||||||
|
expect: []string{"build", images[0], "-t", images[1], "--builder=gcr.io/buildpacks/builder:v1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single flag without builder",
|
||||||
|
flags: []string{"--clear-cache"},
|
||||||
|
expect: []string{"build", images[0], "-t", images[1], "--clear-cache", "--builder=gcr.io/buildpacks/builder:v1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple flags without builder",
|
||||||
|
flags: []string{"--clear-cache", "--verbose"},
|
||||||
|
expect: []string{"build", images[0], "-t", images[1], "--clear-cache", "--verbose", "--builder=gcr.io/buildpacks/builder:v1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "builder with --builder flag",
|
||||||
|
flags: []string{"--builder=heroku/buildpacks:20"},
|
||||||
|
expect: []string{"build", images[0], "-t", images[1], "--builder=heroku/buildpacks:20"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "builder with -B flag",
|
||||||
|
flags: []string{"-B=heroku/buildpacks:18"},
|
||||||
|
expect: []string{"build", images[0], "-t", images[1], "-B=heroku/buildpacks:18"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
imager := buildPackImager{}
|
||||||
|
require.Equal(t, tt.expect, imager.buildCommand(images, tt.flags))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ func init() {
|
|||||||
registerImager(useBuildx, dockerImager{
|
registerImager(useBuildx, dockerImager{
|
||||||
buildx: true,
|
buildx: true,
|
||||||
})
|
})
|
||||||
|
registerImager(useBuildPack, buildPackImager{})
|
||||||
}
|
}
|
||||||
|
|
||||||
type dockerManifester struct{}
|
type dockerManifester struct{}
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ import (
|
|||||||
const (
|
const (
|
||||||
dockerConfigExtra = "DockerConfig"
|
dockerConfigExtra = "DockerConfig"
|
||||||
|
|
||||||
useBuildx = "buildx"
|
useBuildx = "buildx"
|
||||||
useDocker = "docker"
|
useDocker = "docker"
|
||||||
|
useBuildPack = "buildpacks"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pipe for docker.
|
// Pipe for docker.
|
||||||
|
|||||||
@@ -929,6 +929,9 @@ func TestRunPipe(t *testing.T) {
|
|||||||
|
|
||||||
for name, docker := range table {
|
for name, docker := range table {
|
||||||
for imager := range imagers {
|
for imager := range imagers {
|
||||||
|
if imager == useBuildPack { // buildpack tests are different
|
||||||
|
continue
|
||||||
|
}
|
||||||
t.Run(name+" on "+imager, func(t *testing.T) {
|
t.Run(name+" on "+imager, func(t *testing.T) {
|
||||||
folder := t.TempDir()
|
folder := t.TempDir()
|
||||||
dist := filepath.Join(folder, "dist")
|
dist := filepath.Join(folder, "dist")
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ dockers:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
|
||||||
# Set the "backend" for the Docker pipe.
|
# Set the "backend" for the Docker pipe.
|
||||||
# Valid options are: docker, buildx, podman
|
# Valid options are: docker, buildx, podman, buildpacks
|
||||||
# podman is a GoReleaser Pro feature and is only available on Linux.
|
# podman is a GoReleaser Pro feature and is only available on Linux.
|
||||||
# Defaults to docker.
|
# Defaults to docker.
|
||||||
use: docker
|
use: docker
|
||||||
@@ -255,3 +255,30 @@ Also worth noticing that currently Podman only works on Linux machines.
|
|||||||
|
|
||||||
!!! info
|
!!! info
|
||||||
The Podman backend is a [GoReleaser Pro feature](/pro/).
|
The Podman backend is a [GoReleaser Pro feature](/pro/).
|
||||||
|
|
||||||
|
## Buildpacks
|
||||||
|
|
||||||
|
You can use [`buildpacks`](https://buildpacks.io) instead of `docker` by setting `use` to `buildpacks` on your config:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# .goreleaser.yml
|
||||||
|
dockers:
|
||||||
|
-
|
||||||
|
image_templates:
|
||||||
|
- "myuser/myimage"
|
||||||
|
use: buildpacks
|
||||||
|
```
|
||||||
|
|
||||||
|
Also, you can use a custom buildpack on `build_flag_templates` if you want.
|
||||||
|
By default, `gcr.io/buildpacks/builder:v1` will be used.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# .goreleaser.yml
|
||||||
|
dockers:
|
||||||
|
-
|
||||||
|
image_templates:
|
||||||
|
- "myuser/myimage"
|
||||||
|
use: buildpacks
|
||||||
|
build_flag_templates:
|
||||||
|
- "--builder=heroku/buildpacks:20"
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user