1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-04-11 11:42:15 +02:00

feat: multiple sign (#1088)

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
This commit is contained in:
Carlos Alexandro Becker 2019-07-21 18:46:46 -03:00 committed by GitHub
parent 04f17669cc
commit 5c16574c8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 152 additions and 78 deletions

View File

@ -5,10 +5,14 @@ import (
"os"
"os/exec"
"path/filepath"
"reflect"
"github.com/apex/log"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/deprecate"
"github.com/goreleaser/goreleaser/internal/pipe"
"github.com/goreleaser/goreleaser/internal/semerrgroup"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
)
@ -21,18 +25,26 @@ func (Pipe) String() string {
// Default sets the Pipes defaults.
func (Pipe) Default(ctx *context.Context) error {
cfg := &ctx.Config.Sign
if cfg.Cmd == "" {
cfg.Cmd = "gpg"
if len(ctx.Config.Signs) == 0 {
ctx.Config.Signs = append(ctx.Config.Signs, ctx.Config.Sign)
if !reflect.DeepEqual(ctx.Config.Sign, config.Sign{}) {
deprecate.Notice("sign")
}
}
if cfg.Signature == "" {
cfg.Signature = "${artifact}.sig"
}
if len(cfg.Args) == 0 {
cfg.Args = []string{"--output", "$signature", "--detach-sig", "$artifact"}
}
if cfg.Artifacts == "" {
cfg.Artifacts = "none"
for i := range ctx.Config.Signs {
cfg := &ctx.Config.Signs[i]
if cfg.Cmd == "" {
cfg.Cmd = "gpg"
}
if cfg.Signature == "" {
cfg.Signature = "${artifact}.sig"
}
if len(cfg.Args) == 0 {
cfg.Args = []string{"--output", "$signature", "--detach-sig", "$artifact"}
}
if cfg.Artifacts == "" {
cfg.Artifacts = "none"
}
}
return nil
}
@ -43,40 +55,47 @@ func (Pipe) Run(ctx *context.Context) error {
return pipe.ErrSkipSignEnabled
}
switch ctx.Config.Sign.Artifacts {
case "checksum":
return sign(ctx, ctx.Artifacts.Filter(artifact.ByType(artifact.Checksum)).List())
case "all":
return sign(ctx, ctx.Artifacts.Filter(
artifact.Or(
artifact.ByType(artifact.UploadableArchive),
artifact.ByType(artifact.UploadableBinary),
artifact.ByType(artifact.Checksum),
artifact.ByType(artifact.LinuxPackage),
)).List())
case "none":
return pipe.ErrSkipSignEnabled
default:
return fmt.Errorf("invalid list of artifacts to sign: %s", ctx.Config.Sign.Artifacts)
var g = semerrgroup.New(ctx.Parallelism)
for i := range ctx.Config.Signs {
cfg := ctx.Config.Signs[i]
g.Go(func() error {
switch cfg.Artifacts {
case "checksum":
var artifacts = ctx.Artifacts.
Filter(artifact.ByType(artifact.Checksum)).
List()
return sign(ctx, cfg, artifacts)
case "all":
var artifacts = ctx.Artifacts.
Filter(artifact.Or(
artifact.ByType(artifact.UploadableArchive),
artifact.ByType(artifact.UploadableBinary),
artifact.ByType(artifact.Checksum),
artifact.ByType(artifact.LinuxPackage),
)).List()
return sign(ctx, cfg, artifacts)
case "none":
return pipe.ErrSkipSignEnabled
default:
return fmt.Errorf("invalid list of artifacts to sign: %s", cfg.Artifacts)
}
})
}
return g.Wait()
}
func sign(ctx *context.Context, artifacts []artifact.Artifact) error {
func sign(ctx *context.Context, cfg config.Sign, artifacts []artifact.Artifact) error {
for _, a := range artifacts {
artifact, err := signone(ctx, a)
artifact, err := signone(ctx, cfg, a)
if err != nil {
return err
}
ctx.Artifacts.Add(*artifact)
}
return nil
}
func signone(ctx *context.Context, a artifact.Artifact) (*artifact.Artifact, error) {
cfg := ctx.Config.Sign
func signone(ctx *context.Context, cfg config.Sign, a artifact.Artifact) (*artifact.Artifact, error) {
env := ctx.Env
env["artifact"] = a.Path
env["signature"] = expand(cfg.Signature, env)

View File

@ -41,29 +41,33 @@ func TestSignDefault(t *testing.T) {
ctx := &context.Context{}
err := Pipe{}.Default(ctx)
assert.NoError(t, err)
assert.Equal(t, ctx.Config.Sign.Cmd, "gpg")
assert.Equal(t, ctx.Config.Sign.Signature, "${artifact}.sig")
assert.Equal(t, ctx.Config.Sign.Args, []string{"--output", "$signature", "--detach-sig", "$artifact"})
assert.Equal(t, ctx.Config.Sign.Artifacts, "none")
assert.Equal(t, ctx.Config.Signs[0].Cmd, "gpg")
assert.Equal(t, ctx.Config.Signs[0].Signature, "${artifact}.sig")
assert.Equal(t, ctx.Config.Signs[0].Args, []string{"--output", "$signature", "--detach-sig", "$artifact"})
assert.Equal(t, ctx.Config.Signs[0].Artifacts, "none")
}
func TestSignDisabled(t *testing.T) {
ctx := &context.Context{}
ctx.Config.Sign.Artifacts = "none"
ctx := context.New(config.Project{})
ctx.Config.Signs = []config.Sign{
{Artifacts: "none"},
}
err := Pipe{}.Run(ctx)
assert.EqualError(t, err, "artifact signing is disabled")
}
func TestSignSkipped(t *testing.T) {
ctx := &context.Context{}
ctx := context.New(config.Project{})
ctx.SkipSign = true
err := Pipe{}.Run(ctx)
assert.EqualError(t, err, "artifact signing is disabled")
}
func TestSignInvalidArtifacts(t *testing.T) {
ctx := &context.Context{}
ctx.Config.Sign.Artifacts = "foo"
ctx := context.New(config.Project{})
ctx.Config.Signs = []config.Sign{
{Artifacts: "foo"},
}
err := Pipe{}.Run(ctx)
assert.EqualError(t, err, "invalid list of artifacts to sign: foo")
}
@ -75,11 +79,27 @@ func TestSignArtifacts(t *testing.T) {
signaturePaths []string
signatureNames []string
}{
{
desc: "sign single",
ctx: context.New(
config.Project{
Sign: config.Sign{
Artifacts: "all",
},
},
),
signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "linux_amd64/artifact4.sig"},
signatureNames: []string{"artifact1.sig", "artifact2.sig", "artifact3_1.0.0_linux_amd64.sig", "checksum.sig", "artifact4_1.0.0_linux_amd64.sig"},
},
{
desc: "sign all artifacts",
ctx: context.New(
config.Project{
Sign: config.Sign{Artifacts: "all"},
Signs: []config.Sign{
{
Artifacts: "all",
},
},
},
),
signaturePaths: []string{"artifact1.sig", "artifact2.sig", "artifact3.sig", "checksum.sig", "linux_amd64/artifact4.sig"},
@ -89,7 +109,11 @@ func TestSignArtifacts(t *testing.T) {
desc: "sign only checksums",
ctx: context.New(
config.Project{
Sign: config.Sign{Artifacts: "checksum"},
Signs: []config.Sign{
{
Artifacts: "checksum",
},
},
},
),
signaturePaths: []string{"checksum.sig"},
@ -99,15 +123,17 @@ func TestSignArtifacts(t *testing.T) {
desc: "sign all artifacts with env",
ctx: context.New(
config.Project{
Sign: config.Sign{
Artifacts: "all",
Args: []string{
"-u",
"${TEST_USER}",
"--output",
"${signature}",
"--detach-sign",
"${artifact}",
Signs: []config.Sign{
{
Artifacts: "all",
Args: []string{
"-u",
"${TEST_USER}",
"--output",
"${signature}",
"--detach-sign",
"${artifact}",
},
},
},
Env: []string{
@ -175,7 +201,7 @@ func testSign(t *testing.T, ctx *context.Context, signaturePaths []string, signa
// configure the pipeline
// make sure we are using the test keyring
assert.NoError(t, Pipe{}.Default(ctx))
ctx.Config.Sign.Args = append([]string{"--homedir", keyring}, ctx.Config.Sign.Args...)
ctx.Config.Signs[0].Args = append([]string{"--homedir", keyring}, ctx.Config.Signs[0].Args...)
// run the pipeline
assert.NoError(t, Pipe{}.Run(ctx))

View File

@ -357,7 +357,8 @@ type Project struct {
Blobs []Blob `yaml:"blob,omitempty"`
Changelog Changelog `yaml:",omitempty"`
Dist string `yaml:",omitempty"`
Sign Sign `yaml:",omitempty"`
Sign Sign `yaml:",omitempty"` // TODO: remove this
Signs []Sign `yaml:",omitempty"`
EnvFiles EnvFiles `yaml:"env_files,omitempty"`
Before Before `yaml:",omitempty"`

View File

@ -33,6 +33,29 @@ to this:
-->
### sign
> since 2019-07-20
Sign was deprecated in favor of its plural form.
Change this:
```yaml
sign:
# etc
```
to this:
```yaml
signs:
-
# etc
```
### brew
> since 2019-06-09

View File

@ -18,37 +18,42 @@ just add
```yaml
# goreleaser.yml
sign:
artifacts: checksum
signs:
- artifacts: checksum
```
To customize the signing pipeline you can use the following options:
```yml
# .goreleaser.yml
sign:
# name of the signature file.
# '${artifact}' is the path to the artifact that should be signed.
#
# signature: "${artifact}.sig"
signs:
-
# name of the signature file.
# '${artifact}' is the path to the artifact that should be signed.
#
# defaults to `${artifact}.sig`
signature: "${artifact}_sig"
# path to the signature command
#
# cmd: gpg
# path to the signature command
#
# defaults to `gpg`
cmd: gpg2
# command line arguments for the command
#
# to sign with a specific key use
# args: ["-u", "<key id, fingerprint, email, ...>", "--output", "${signature}", "--detach-sign", "${artifact}"]
#
# args: ["--output", "${signature}", "--detach-sign", "${artifact}"]
# command line arguments for the command
#
# to sign with a specific key use
# args: ["-u", "<key id, fingerprint, email, ...>", "--output", "${signature}", "--detach-sign", "${artifact}"]
#
# defaults to `["--output", "${signature}", "--detach-sign", "${artifact}"]`
args: ["--output", "${signature}", "${artifact}"]
# which artifacts to sign
#
# checksum: only checksum file(s)
# all: all artifacts
# none: no signing
#
# artifacts: none
# which artifacts to sign
#
# checksum: only checksum file(s)
# all: all artifacts
# none: no signing
#
# defaults to `none`
artifacts: all
```