mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-10 03:47:03 +02:00
874d698564
here's an idea: `goreleaser healthcheck` It'll check if the needed dependencies (docker, git, etc) are available in the path... this way users can preemptively run it before releasing or to debug issues. What do you think? Here's how it looks like: <img width="1007" alt="CleanShot 2023-03-02 at 23 24 26@2x" src="https://user-images.githubusercontent.com/245435/222615682-d9cd0733-d900-43d1-9166-23b2be589b3a.png"> --------- Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
241 lines
6.5 KiB
Go
241 lines
6.5 KiB
Go
package sign
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/goreleaser/goreleaser/internal/artifact"
|
|
"github.com/goreleaser/goreleaser/internal/gio"
|
|
"github.com/goreleaser/goreleaser/internal/testctx"
|
|
"github.com/goreleaser/goreleaser/internal/testlib"
|
|
"github.com/goreleaser/goreleaser/pkg/config"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestDockerSignDescription(t *testing.T) {
|
|
require.NotEmpty(t, DockerPipe{}.String())
|
|
}
|
|
|
|
func TestDockerSignDefault(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
DockerSigns: []config.Sign{{}},
|
|
})
|
|
err := DockerPipe{}.Default(ctx)
|
|
require.NoError(t, err)
|
|
require.Equal(t, "cosign", ctx.Config.DockerSigns[0].Cmd)
|
|
require.Equal(t, "", ctx.Config.DockerSigns[0].Signature)
|
|
require.Equal(t, []string{"sign", "--key=cosign.key", "${artifact}@${digest}", "--yes"}, ctx.Config.DockerSigns[0].Args)
|
|
require.Equal(t, "none", ctx.Config.DockerSigns[0].Artifacts)
|
|
}
|
|
|
|
func TestDockerSignDisabled(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
DockerSigns: []config.Sign{
|
|
{Artifacts: "none"},
|
|
},
|
|
})
|
|
err := DockerPipe{}.Publish(ctx)
|
|
require.EqualError(t, err, "artifact signing is disabled")
|
|
}
|
|
|
|
func TestDockerSignInvalidArtifacts(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
DockerSigns: []config.Sign{
|
|
{Artifacts: "foo"},
|
|
},
|
|
})
|
|
err := DockerPipe{}.Publish(ctx)
|
|
require.EqualError(t, err, "invalid list of artifacts to sign: foo")
|
|
}
|
|
|
|
func TestDockerSignArtifacts(t *testing.T) {
|
|
testlib.CheckPath(t, "cosign")
|
|
key := "cosign.key"
|
|
cmd := "sh"
|
|
args := []string{"-c", "echo ${artifact}@${digest} > ${signature} && cosign sign --key=" + key + " --upload=false ${artifact}@${digest} --yes > ${signature}"}
|
|
password := "password"
|
|
|
|
img1 := "ghcr.io/caarlos0/goreleaser-docker-manifest-actions-example:1.2.1-amd64"
|
|
img1Digest := "sha256:d7bf8be1b156cc0cd9d2e33765a69bc968d4ef6b2dea9b207d63129b9709862a"
|
|
img2 := "ghcr.io/caarlos0/goreleaser-docker-manifest-actions-example:1.2.1-arm64v8"
|
|
img2Digest := "sha256:551801b7f42f8c33bfabb06e25804c2aca14776d2b7df33e07de54e887910b72"
|
|
man1 := "ghcr.io/caarlos0/goreleaser-docker-manifest-actions-example:1.2.1"
|
|
man1Digest := "sha256:b5db21408555f1ef5d68008a0a03a7caba3f29b62c64f1404e139b005a20bf03"
|
|
|
|
for name, cfg := range map[string]struct {
|
|
Signs []config.Sign
|
|
Expected []string
|
|
}{
|
|
"no signature file": {
|
|
Expected: nil, // no sigs
|
|
Signs: []config.Sign{
|
|
{
|
|
Artifacts: "all",
|
|
Stdin: &password,
|
|
Cmd: "cosign",
|
|
Args: []string{"sign", "--key=" + key, "--upload=false", "${artifact}", "--yes"},
|
|
},
|
|
},
|
|
},
|
|
"only certificate": {
|
|
Expected: []string{
|
|
"ghcrio-caarlos0-goreleaser-docker-manifest-actions-example-121-amd64.pem",
|
|
"ghcrio-caarlos0-goreleaser-docker-manifest-actions-example-121-arm64v8.pem",
|
|
"ghcrio-caarlos0-goreleaser-docker-manifest-actions-example-121.pem",
|
|
},
|
|
Signs: []config.Sign{
|
|
{
|
|
Artifacts: "all",
|
|
Stdin: &password,
|
|
Cmd: "cosign",
|
|
Certificate: `{{ replace (replace (replace .Env.artifact "/" "-") ":" "-") "." "" }}.pem`,
|
|
Args: []string{"sign", "--output-certificate=${certificate}", "--key=" + key, "--upload=false", "${artifact}@${digest}", "--yes"},
|
|
},
|
|
},
|
|
},
|
|
"sign all": {
|
|
Expected: []string{
|
|
"all_img1.sig",
|
|
"all_img2.sig",
|
|
"all_man1.sig",
|
|
},
|
|
Signs: []config.Sign{
|
|
{
|
|
Artifacts: "all",
|
|
Stdin: &password,
|
|
Signature: `all_${artifactID}.sig`,
|
|
Cmd: cmd,
|
|
Args: args,
|
|
},
|
|
},
|
|
},
|
|
"sign all filtering id": {
|
|
Expected: []string{"all_filter_by_id_img2.sig"},
|
|
Signs: []config.Sign{
|
|
{
|
|
Artifacts: "all",
|
|
IDs: []string{"img2"},
|
|
Stdin: &password,
|
|
Signature: "all_filter_by_id_${artifactID}.sig",
|
|
Cmd: cmd,
|
|
Args: args,
|
|
},
|
|
},
|
|
},
|
|
"sign images only": {
|
|
Expected: []string{
|
|
"images_img1.sig",
|
|
"images_img2.sig",
|
|
},
|
|
Signs: []config.Sign{
|
|
{
|
|
Artifacts: "images",
|
|
Stdin: &password,
|
|
Signature: "images_${artifactID}.sig",
|
|
Cmd: cmd,
|
|
Args: args,
|
|
},
|
|
},
|
|
},
|
|
"sign manifests only": {
|
|
Expected: []string{"manifests_man1.sig"},
|
|
Signs: []config.Sign{
|
|
{
|
|
Artifacts: "manifests",
|
|
Stdin: &password,
|
|
Signature: "manifests_${artifactID}.sig",
|
|
Cmd: cmd,
|
|
Args: args,
|
|
},
|
|
},
|
|
},
|
|
// TODO: keyless test?
|
|
} {
|
|
t.Run(name, func(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
DockerSigns: cfg.Signs,
|
|
})
|
|
wd, err := os.Getwd()
|
|
require.NoError(t, err)
|
|
tmp := testlib.Mktmp(t)
|
|
require.NoError(t, gio.Copy(filepath.Join(wd, "testdata/cosign/"), tmp))
|
|
ctx.Config.Dist = "dist"
|
|
require.NoError(t, os.Mkdir("dist", 0o755))
|
|
|
|
ctx.Artifacts.Add(&artifact.Artifact{
|
|
Name: img1,
|
|
Path: img1,
|
|
Type: artifact.DockerImage,
|
|
Extra: map[string]interface{}{
|
|
artifact.ExtraID: "img1",
|
|
artifact.ExtraDigest: img1Digest,
|
|
},
|
|
})
|
|
ctx.Artifacts.Add(&artifact.Artifact{
|
|
Name: img2,
|
|
Path: img2,
|
|
Type: artifact.DockerImage,
|
|
Extra: map[string]interface{}{
|
|
artifact.ExtraID: "img2",
|
|
artifact.ExtraDigest: img2Digest,
|
|
},
|
|
})
|
|
ctx.Artifacts.Add(&artifact.Artifact{
|
|
Name: man1,
|
|
Path: man1,
|
|
Type: artifact.DockerManifest,
|
|
Extra: map[string]interface{}{
|
|
artifact.ExtraID: "man1",
|
|
artifact.ExtraDigest: man1Digest,
|
|
},
|
|
})
|
|
|
|
require.NoError(t, DockerPipe{}.Default(ctx))
|
|
require.NoError(t, DockerPipe{}.Publish(ctx))
|
|
var sigs []string
|
|
for _, sig := range ctx.Artifacts.Filter(
|
|
artifact.Or(
|
|
artifact.ByType(artifact.Signature),
|
|
artifact.ByType(artifact.Certificate),
|
|
),
|
|
).List() {
|
|
sigs = append(sigs, sig.Name)
|
|
require.Truef(t, strings.HasPrefix(sig.Path, ctx.Config.Dist), "signature %q is not in dist dir %q", sig.Path, ctx.Config.Dist)
|
|
}
|
|
require.Equal(t, cfg.Expected, sigs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDockerSkip(t *testing.T) {
|
|
t.Run("skip", func(t *testing.T) {
|
|
require.True(t, DockerPipe{}.Skip(testctx.New()))
|
|
})
|
|
|
|
t.Run("skip sign", func(t *testing.T) {
|
|
ctx := testctx.New(testctx.SkipSign)
|
|
require.True(t, DockerPipe{}.Skip(ctx))
|
|
})
|
|
|
|
t.Run("dont skip", func(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
DockerSigns: []config.Sign{
|
|
{},
|
|
},
|
|
})
|
|
require.False(t, DockerPipe{}.Skip(ctx))
|
|
})
|
|
}
|
|
|
|
func TestDockerDependencies(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
DockerSigns: []config.Sign{
|
|
{Cmd: "cosign"},
|
|
{Cmd: "gpg2"},
|
|
},
|
|
})
|
|
require.Equal(t, []string{"cosign", "gpg2"}, DockerPipe{}.Dependencies(ctx))
|
|
}
|