1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-03-19 20:57:53 +02:00
goreleaser/internal/pipe/sign/sign_test.go
Carlos Alexandro Becker 2bf08f11a6
ci: run build/test workflow on windows too (#5263)
Maybe 3rd time is the charm!

This makes the CI build run on windows too, and fix broken tests/featuers on Windows.

Most of the changes are related to ignoring certain tests on windows, or making sure to use the right path separators.

More work to do in the future, probably!

#4293

---------

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
2024-11-16 10:30:39 -03:00

796 lines
22 KiB
Go

package sign
import (
"bytes"
"fmt"
"math/rand"
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/goreleaser/goreleaser/v2/internal/artifact"
"github.com/goreleaser/goreleaser/v2/internal/gio"
"github.com/goreleaser/goreleaser/v2/internal/git"
"github.com/goreleaser/goreleaser/v2/internal/skips"
"github.com/goreleaser/goreleaser/v2/internal/testctx"
"github.com/goreleaser/goreleaser/v2/internal/testlib"
"github.com/goreleaser/goreleaser/v2/internal/tmpl"
"github.com/goreleaser/goreleaser/v2/pkg/config"
"github.com/goreleaser/goreleaser/v2/pkg/context"
"github.com/stretchr/testify/require"
)
var (
originKeyring = "testdata/gnupg"
keyring string
)
const (
user = "nopass"
passwordUser = "password"
passwordUserTmpl = "{{ .Env.GPG_PASSWORD }}"
fakeGPGKeyID = "23E7505E"
)
func TestMain(m *testing.M) {
rand := rand.New(rand.NewSource(time.Now().UnixNano()))
keyring = filepath.Join(os.TempDir(), fmt.Sprintf("gorel_gpg_test.%d", rand.Int()))
fmt.Println("copying", originKeyring, "to", keyring)
if err := gio.Copy(originKeyring, keyring); err != nil {
fmt.Printf("failed to copy %s to %s: %s", originKeyring, keyring, err)
os.Exit(1)
}
m.Run()
_ = os.RemoveAll(keyring)
}
func TestDescription(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
}
func TestSignDefault(t *testing.T) {
_ = testlib.Mktmp(t)
testlib.GitInit(t)
ctx := testctx.NewWithCfg(config.Project{
Signs: []config.Sign{{}},
})
setGpg(t, ctx, "") // force empty gpg.program
require.NoError(t, Pipe{}.Default(ctx))
require.Equal(t, "gpg", ctx.Config.Signs[0].Cmd)
require.Equal(t, "${artifact}.sig", ctx.Config.Signs[0].Signature)
require.Equal(t, []string{"--output", "$signature", "--detach-sig", "$artifact"}, ctx.Config.Signs[0].Args)
require.Equal(t, "none", ctx.Config.Signs[0].Artifacts)
}
func TestDefaultGpgFromGitConfig(t *testing.T) {
_ = testlib.Mktmp(t)
testlib.GitInit(t)
ctx := testctx.NewWithCfg(config.Project{
Signs: []config.Sign{{}},
})
setGpg(t, ctx, "not-really-gpg")
require.NoError(t, Pipe{}.Default(ctx))
require.Equal(t, "not-really-gpg", ctx.Config.Signs[0].Cmd)
}
func TestSignDisabled(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{Signs: []config.Sign{{Artifacts: "none"}}})
err := Pipe{}.Run(ctx)
require.EqualError(t, err, "artifact signing is disabled")
}
func TestSignInvalidArtifacts(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{Signs: []config.Sign{{Artifacts: "foo"}}})
err := Pipe{}.Run(ctx)
require.EqualError(t, err, "invalid list of artifacts to sign: foo")
}
func TestSignArtifacts(t *testing.T) {
// dunno why this tries to use /usr/bin/gpg-agent on a windows machine
testlib.SkipIfWindows(t)
stdin := passwordUser
tmplStdin := passwordUserTmpl
tests := []struct {
desc string
ctx *context.Context
signaturePaths []string
signatureNames []string
certificateNames []string
expectedErrMsg string
expectedErrIs error
expectedErrAs any
user string
}{
{
desc: "sign cmd not found",
expectedErrIs: exec.ErrNotFound,
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Cmd: "not-a-valid-cmd",
},
},
}),
},
{
desc: "sign errors",
expectedErrMsg: "sign: exit failed",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Cmd: "exit",
Args: []string{"1"},
},
},
}),
},
{
desc: "invalid certificate template",
expectedErrAs: &tmpl.Error{},
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Cmd: "exit",
Certificate: "{{ .blah }}",
},
},
}),
},
{
desc: "invalid signature template",
expectedErrAs: &tmpl.Error{},
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Cmd: "exit",
Signature: "{{ .blah }}",
},
},
}),
},
{
desc: "invalid args template",
expectedErrAs: &tmpl.Error{},
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Cmd: "exit",
Args: []string{"${FOO}-{{ .foo }{{}}{"},
},
},
Env: []string{
"FOO=BAR",
},
}),
},
{
desc: "invalid env template",
expectedErrAs: &tmpl.Error{},
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Cmd: "exit",
Env: []string{"A={{ .blah }}"},
},
},
}),
},
{
desc: "sign all artifacts",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
},
},
}),
signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "checksum2.sig", "linux_amd64/artifact4.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
signatureNames: []string{"artifact1.sig", "artifact2.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "checksum2.sig", "artifact4_1.0.0_linux_amd64.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
},
{
desc: "sign archives",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "archive",
},
},
}),
signaturePaths: []string{"artifact1.sig", "artifact2.sig"},
signatureNames: []string{"artifact1.sig", "artifact2.sig"},
},
{
desc: "sign packages",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "package",
},
},
}),
signaturePaths: []string{"package1.deb.sig"},
signatureNames: []string{"package1.deb.sig"},
},
{
desc: "sign binaries",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "binary",
},
},
}),
signaturePaths: []string{"artifact3.sig", "linux_amd64/artifact4.sig"},
signatureNames: []string{"artifact3_1.0.0_linux_amd64.sig", "artifact4_1.0.0_linux_amd64.sig"},
},
{
desc: "multiple sign configs",
ctx: testctx.NewWithCfg(config.Project{
Env: []string{
"GPG_KEY_ID=" + fakeGPGKeyID,
},
Signs: []config.Sign{
{
ID: "s1",
Artifacts: "checksum",
},
{
ID: "s2",
Artifacts: "archive",
Signature: "${artifact}.{{ .Env.GPG_KEY_ID }}.sig",
},
},
}),
signaturePaths: []string{
"artifact1." + fakeGPGKeyID + ".sig",
"artifact2." + fakeGPGKeyID + ".sig",
"checksum.sig",
"checksum2.sig",
},
signatureNames: []string{
"artifact1." + fakeGPGKeyID + ".sig",
"artifact2." + fakeGPGKeyID + ".sig",
"checksum.sig",
"checksum2.sig",
},
},
{
desc: "sign filtered artifacts",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
IDs: []string{"foo"},
},
},
}),
signaturePaths: []string{"artifact1.sig", "artifact3.sig", "checksum.sig", "checksum2.sig", "artifact5.tar.gz.sig", "package1.deb.sig"},
signatureNames: []string{"artifact1.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "checksum2.sig", "artifact5.tar.gz.sig", "package1.deb.sig"},
},
{
desc: "sign only checksums",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "checksum",
},
},
}),
signaturePaths: []string{"checksum.sig", "checksum2.sig"},
signatureNames: []string{"checksum.sig", "checksum2.sig"},
},
{
desc: "sign only filtered checksums",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "checksum",
IDs: []string{"foo"},
},
},
}),
signaturePaths: []string{"checksum.sig", "checksum2.sig"},
signatureNames: []string{"checksum.sig", "checksum2.sig"},
},
{
desc: "sign only source",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "source",
},
},
}),
signaturePaths: []string{"artifact5.tar.gz.sig"},
signatureNames: []string{"artifact5.tar.gz.sig"},
},
{
desc: "sign only source filter by id",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "source",
IDs: []string{"should-not-be-used"},
},
},
}),
signaturePaths: []string{"artifact5.tar.gz.sig"},
signatureNames: []string{"artifact5.tar.gz.sig"},
},
{
desc: "sign only sbom",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "sbom",
},
},
}),
signaturePaths: []string{"artifact5.tar.gz.sbom.sig"},
signatureNames: []string{"artifact5.tar.gz.sbom.sig"},
},
{
desc: "sign all artifacts with env",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Args: []string{
"-u",
"${TEST_USER}",
"--output",
"${signature}",
"--detach-sign",
"${artifact}",
},
},
},
Env: []string{
fmt.Sprintf("TEST_USER=%s", user),
},
}),
signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "checksum2.sig", "linux_amd64/artifact4.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
signatureNames: []string{"artifact1.sig", "artifact2.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "checksum2.sig", "artifact4_1.0.0_linux_amd64.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
},
{
desc: "sign all artifacts with template",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Args: []string{
"-u",
"{{ .Env.SOME_TEST_USER }}",
"--output",
"${signature}",
"--detach-sign",
"${artifact}",
},
},
},
Env: []string{
fmt.Sprintf("SOME_TEST_USER=%s", user),
},
}),
signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "checksum2.sig", "linux_amd64/artifact4.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
signatureNames: []string{"artifact1.sig", "artifact2.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "checksum2.sig", "artifact4_1.0.0_linux_amd64.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
},
{
desc: "sign single with password from stdin",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Args: []string{
"-u",
passwordUser,
"--batch",
"--pinentry-mode",
"loopback",
"--passphrase-fd",
"0",
"--output",
"${signature}",
"--detach-sign",
"${artifact}",
},
Stdin: &stdin,
},
},
}),
signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "checksum2.sig", "linux_amd64/artifact4.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
signatureNames: []string{"artifact1.sig", "artifact2.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "checksum2.sig", "artifact4_1.0.0_linux_amd64.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
user: passwordUser,
},
{
desc: "sign single with password from templated stdin",
ctx: testctx.NewWithCfg(config.Project{
Env: []string{"GPG_PASSWORD=" + stdin},
Signs: []config.Sign{
{
Artifacts: "all",
Args: []string{
"-u",
passwordUser,
"--batch",
"--pinentry-mode",
"loopback",
"--passphrase-fd",
"0",
"--output",
"${signature}",
"--detach-sign",
"${artifact}",
},
Stdin: &tmplStdin,
},
},
}),
signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "checksum2.sig", "linux_amd64/artifact4.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
signatureNames: []string{"artifact1.sig", "artifact2.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "checksum2.sig", "artifact4_1.0.0_linux_amd64.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
user: passwordUser,
},
{
desc: "sign single with password from stdin_file",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Args: []string{
"-u",
passwordUser,
"--batch",
"--pinentry-mode",
"loopback",
"--passphrase-fd",
"0",
"--output",
"${signature}",
"--detach-sign",
"${artifact}",
},
StdinFile: filepath.Join(keyring, passwordUser),
},
},
}),
signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "checksum2.sig", "linux_amd64/artifact4.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
signatureNames: []string{"artifact1.sig", "artifact2.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "checksum2.sig", "artifact4_1.0.0_linux_amd64.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
user: passwordUser,
},
{
desc: "missing stdin_file",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Artifacts: "all",
Args: []string{
"--batch",
"--pinentry-mode",
"loopback",
"--passphrase-fd",
"0",
},
StdinFile: "/tmp/non-existing-file",
},
},
}),
expectedErrIs: os.ErrNotExist,
},
{
desc: "sign creating certificate",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Certificate: "${artifact}.pem",
Artifacts: "checksum",
},
},
}),
signaturePaths: []string{"checksum.sig", "checksum2.sig"},
signatureNames: []string{"checksum.sig", "checksum2.sig"},
certificateNames: []string{"checksum.pem", "checksum2.pem"},
},
{
desc: "sign all artifacts with env and certificate",
ctx: testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
Env: []string{"NOT_HONK=honk", "HONK={{ .Env.NOT_HONK }}"},
Certificate: `{{ trimsuffix (trimsuffix .Env.artifact ".tar.gz") ".deb" }}_${HONK}.pem`,
Artifacts: "all",
},
},
}),
signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "checksum2.sig", "linux_amd64/artifact4.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
signatureNames: []string{"artifact1.sig", "artifact2.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "checksum2.sig", "artifact4_1.0.0_linux_amd64.sig", "artifact5.tar.gz.sig", "artifact5.tar.gz.sbom.sig", "package1.deb.sig"},
certificateNames: []string{"artifact1_honk.pem", "artifact2_honk.pem", "artifact3_1.0.0_linux_amd64_honk.pem", "checksum_honk.pem", "checksum2_honk.pem", "artifact4_1.0.0_linux_amd64_honk.pem", "artifact5_honk.pem", "artifact5.tar.gz.sbom_honk.pem", "package1_honk.pem"},
},
}
for _, test := range tests {
if test.user == "" {
test.user = user
}
t.Run(test.desc, func(t *testing.T) {
testlib.CheckPath(t, "gpg")
testSign(
t,
test.ctx,
test.certificateNames,
test.signaturePaths,
test.signatureNames,
test.user,
test.expectedErrMsg,
test.expectedErrIs,
test.expectedErrAs,
)
})
}
}
func testSign(
tb testing.TB,
ctx *context.Context,
certificateNames, signaturePaths, signatureNames []string,
user, expectedErrMsg string,
expectedErrIs error,
expectedErrAs any,
) {
tb.Helper()
tmpdir := tb.TempDir()
ctx.Config.Dist = tmpdir
// create some fake artifacts
artifacts := []string{"artifact1", "artifact2", "artifact3", "checksum", "checksum2", "package1.deb"}
require.NoError(tb, os.Mkdir(filepath.Join(tmpdir, "linux_amd64"), os.ModePerm))
for _, f := range artifacts {
file := filepath.Join(tmpdir, f)
require.NoError(tb, os.WriteFile(file, []byte("foo"), 0o644))
}
require.NoError(tb, os.WriteFile(filepath.Join(tmpdir, "linux_amd64", "artifact4"), []byte("foo"), 0o644))
artifacts = append(artifacts, "linux_amd64/artifact4")
require.NoError(tb, os.WriteFile(filepath.Join(tmpdir, "artifact5.tar.gz"), []byte("foo"), 0o644))
artifacts = append(artifacts, "artifact5.tar.gz")
require.NoError(tb, os.WriteFile(filepath.Join(tmpdir, "artifact5.tar.gz.sbom"), []byte("sbom(foo)"), 0o644))
artifacts = append(artifacts, "artifact5.tar.gz.sbom")
ctx.Artifacts.Add(&artifact.Artifact{
Name: "artifact1",
Path: filepath.Join(tmpdir, "artifact1"),
Type: artifact.UploadableArchive,
Extra: map[string]interface{}{
artifact.ExtraID: "foo",
},
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: "artifact2",
Path: filepath.Join(tmpdir, "artifact2"),
Type: artifact.UploadableArchive,
Extra: map[string]interface{}{
artifact.ExtraID: "foo3",
},
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: "artifact3_1.0.0_linux_amd64",
Path: filepath.Join(tmpdir, "artifact3"),
Type: artifact.UploadableBinary,
Extra: map[string]interface{}{
artifact.ExtraID: "foo",
},
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: "checksum",
Path: filepath.Join(tmpdir, "checksum"),
Type: artifact.Checksum,
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: "checksum2",
Path: filepath.Join(tmpdir, "checksum2"),
Type: artifact.Checksum,
Extra: map[string]interface{}{
"Refresh": func() error {
file := filepath.Join(tmpdir, "checksum2")
return os.WriteFile(file, []byte("foo"), 0o644)
},
},
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: "artifact4_1.0.0_linux_amd64",
Path: filepath.Join(tmpdir, "linux_amd64", "artifact4"),
Type: artifact.UploadableBinary,
Extra: map[string]interface{}{
artifact.ExtraID: "foo3",
},
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: "artifact5.tar.gz",
Path: filepath.Join(tmpdir, "artifact5.tar.gz"),
Type: artifact.UploadableSourceArchive,
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: "artifact5.tar.gz.sbom",
Path: filepath.Join(tmpdir, "artifact5.tar.gz.sbom"),
Type: artifact.SBOM,
})
ctx.Artifacts.Add(&artifact.Artifact{
Name: "package1.deb",
Path: filepath.Join(tmpdir, "package1.deb"),
Type: artifact.LinuxPackage,
Extra: map[string]interface{}{
artifact.ExtraID: "foo",
},
})
// configure the pipeline
// make sure we are using the test keyring
require.NoError(tb, Pipe{}.Default(ctx))
for i := range ctx.Config.Signs {
ctx.Config.Signs[i].Args = append(
[]string{"--homedir", keyring},
ctx.Config.Signs[i].Args...,
)
}
err := Pipe{}.Run(ctx)
// run the pipeline
if expectedErrMsg != "" {
require.ErrorContains(tb, err, expectedErrMsg)
return
}
if expectedErrIs != nil {
require.ErrorIs(tb, err, expectedErrIs)
return
}
if expectedErrAs != nil {
require.ErrorAs(tb, err, expectedErrAs)
return
}
require.NoError(tb, err)
// ensure all artifacts have an ID
for _, arti := range ctx.Artifacts.Filter(
artifact.Or(
artifact.ByType(artifact.Signature),
artifact.ByType(artifact.Certificate),
),
).List() {
require.NotEmptyf(tb, arti.ID(), ".Extra.ID on %s", arti.Path)
}
certificates := ctx.Artifacts.Filter(artifact.ByType(artifact.Certificate)).List()
certNames := []string{}
for _, cert := range certificates {
certNames = append(certNames, cert.Name)
require.True(tb, strings.HasPrefix(cert.Path, ctx.Config.Dist))
}
assert.ElementsMatch(tb, certificateNames, certNames)
// verify that only the artifacts and the signatures are in the dist dir
gotFiles := []string{}
require.NoError(tb, filepath.Walk(tmpdir,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
relPath, err := filepath.Rel(tmpdir, path)
if err != nil {
return err
}
gotFiles = append(gotFiles, relPath)
return nil
}),
)
wantFiles := append(artifacts, signaturePaths...)
sort.Strings(wantFiles)
require.ElementsMatch(tb, wantFiles, gotFiles)
// verify the signatures
for _, sig := range signaturePaths {
verifySignature(tb, ctx, sig, user)
}
var signArtifacts []string
for _, sig := range ctx.Artifacts.Filter(artifact.ByType(artifact.Signature)).List() {
signArtifacts = append(signArtifacts, sig.Name)
}
// check signature is an artifact
require.ElementsMatch(tb, signArtifacts, signatureNames)
}
func verifySignature(tb testing.TB, ctx *context.Context, sig string, user string) {
tb.Helper()
artifact := strings.TrimSuffix(sig, filepath.Ext(sig))
artifact = strings.TrimSuffix(artifact, "."+fakeGPGKeyID)
// verify signature was made with key for user 'nopass'
cmd := exec.Command("gpg", "--homedir", keyring, "--verify", filepath.Join(ctx.Config.Dist, sig), filepath.Join(ctx.Config.Dist, artifact))
out, err := cmd.CombinedOutput()
require.NoError(tb, err, string(out))
// check if the signature matches the user we expect to do this properly we
// might need to have either separate keyrings or export the key from the
// keyring before we do the verification. For now we punt and look in the
// output.
if !bytes.Contains(out, []byte(user)) {
tb.Fatalf("%s: signature is not from %s: %s", sig, user, string(out))
}
}
func TestSeveralSignsWithTheSameID(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{
ID: "a",
},
{
ID: "a",
},
},
})
require.EqualError(t, Pipe{}.Default(ctx), "found 2 signs with the ID 'a', please fix your config")
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(testctx.New()))
})
t.Run("skip sign", func(t *testing.T) {
ctx := testctx.New(testctx.Skip(skips.Sign))
require.True(t, Pipe{}.Skip(ctx))
})
t.Run("dont skip", func(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{},
},
})
require.False(t, Pipe{}.Skip(ctx))
})
}
func TestDependencies(t *testing.T) {
ctx := testctx.NewWithCfg(config.Project{
Signs: []config.Sign{
{Cmd: "cosign"},
{Cmd: "gpg2"},
},
})
require.Equal(t, []string{"cosign", "gpg2"}, Pipe{}.Dependencies(ctx))
}
func setGpg(tb testing.TB, ctx *context.Context, p string) {
tb.Helper()
_, err := git.Run(ctx, "config", "--local", "--add", "gpg.program", p)
require.NoError(tb, err)
}