You've already forked goreleaser
mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-07-17 01:42:37 +02:00
feat: checksums.split (#4707)
closes #4618 closes #4641 --------- Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
280e68431a
commit
54ee014b50
@ -153,6 +153,8 @@ const (
|
|||||||
ExtraReplaces = "Replaces"
|
ExtraReplaces = "Replaces"
|
||||||
ExtraDigest = "Digest"
|
ExtraDigest = "Digest"
|
||||||
ExtraSize = "Size"
|
ExtraSize = "Size"
|
||||||
|
ExtraChecksum = "Checksum"
|
||||||
|
ExtraChecksumOf = "ChecksumOf"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Extras represents the extra fields in an artifact.
|
// Extras represents the extra fields in an artifact.
|
||||||
@ -258,7 +260,12 @@ func (a Artifact) Checksum(algorithm string) (string, error) {
|
|||||||
if _, err := io.Copy(h, file); err != nil {
|
if _, err := io.Copy(h, file); err != nil {
|
||||||
return "", fmt.Errorf("failed to checksum: %w", err)
|
return "", fmt.Errorf("failed to checksum: %w", err)
|
||||||
}
|
}
|
||||||
return hex.EncodeToString(h.Sum(nil)), nil
|
check := hex.EncodeToString(h.Sum(nil))
|
||||||
|
if a.Extra == nil {
|
||||||
|
a.Extra = make(Extras)
|
||||||
|
}
|
||||||
|
a.Extra[ExtraChecksum] = fmt.Sprintf("%s:%s", algorithm, check)
|
||||||
|
return check, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var noRefresh = func() error { return nil }
|
var noRefresh = func() error { return nil }
|
||||||
|
@ -36,23 +36,72 @@ func (Pipe) Skip(ctx *context.Context) bool { return ctx.Config.Checksum.Disable
|
|||||||
|
|
||||||
// Default sets the pipe defaults.
|
// Default sets the pipe defaults.
|
||||||
func (Pipe) Default(ctx *context.Context) error {
|
func (Pipe) Default(ctx *context.Context) error {
|
||||||
if ctx.Config.Checksum.NameTemplate == "" {
|
cs := &ctx.Config.Checksum
|
||||||
ctx.Config.Checksum.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
|
if cs.Algorithm == "" {
|
||||||
|
cs.Algorithm = "sha256"
|
||||||
|
}
|
||||||
|
if cs.NameTemplate == "" {
|
||||||
|
if cs.Split {
|
||||||
|
cs.NameTemplate = "{{ .ArtifactName }}.{{ .Algorithm }}"
|
||||||
|
} else {
|
||||||
|
cs.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
|
||||||
}
|
}
|
||||||
if ctx.Config.Checksum.Algorithm == "" {
|
|
||||||
ctx.Config.Checksum.Algorithm = "sha256"
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the pipe.
|
// Run the pipe.
|
||||||
func (Pipe) Run(ctx *context.Context) error {
|
func (Pipe) Run(ctx *context.Context) error {
|
||||||
|
if ctx.Config.Checksum.Split {
|
||||||
|
return splitChecksum(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return singleChecksum(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitChecksum(ctx *context.Context) error {
|
||||||
|
artifactList, err := buildArtifactList(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, art := range artifactList {
|
||||||
|
filename, err := tmpl.New(ctx).
|
||||||
|
WithArtifact(art).
|
||||||
|
WithExtraFields(tmpl.Fields{
|
||||||
|
"Algorithm": ctx.Config.Checksum.Algorithm,
|
||||||
|
}).
|
||||||
|
Apply(ctx.Config.Checksum.NameTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("checksum: name template: %w", err)
|
||||||
|
}
|
||||||
|
filepath := filepath.Join(ctx.Config.Dist, filename)
|
||||||
|
if err := refreshOne(ctx, *art, filepath); err != nil {
|
||||||
|
return fmt.Errorf("checksum: %s: %w", art.Path, err)
|
||||||
|
}
|
||||||
|
ctx.Artifacts.Add(&artifact.Artifact{
|
||||||
|
Type: artifact.Checksum,
|
||||||
|
Path: filepath,
|
||||||
|
Name: filename,
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
artifact.ExtraChecksumOf: art.Path,
|
||||||
|
artifact.ExtraRefresh: func() error {
|
||||||
|
log.WithField("file", filename).Info("refreshing checksums")
|
||||||
|
return refreshOne(ctx, *art, filepath)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func singleChecksum(ctx *context.Context) error {
|
||||||
filename, err := tmpl.New(ctx).Apply(ctx.Config.Checksum.NameTemplate)
|
filename, err := tmpl.New(ctx).Apply(ctx.Config.Checksum.NameTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
filepath := filepath.Join(ctx.Config.Dist, filename)
|
filepath := filepath.Join(ctx.Config.Dist, filename)
|
||||||
if err := refresh(ctx, filepath); err != nil {
|
if err := refreshAll(ctx, filepath); err != nil {
|
||||||
if errors.Is(err, errNoArtifacts) {
|
if errors.Is(err, errNoArtifacts) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -65,44 +114,28 @@ func (Pipe) Run(ctx *context.Context) error {
|
|||||||
Extra: map[string]interface{}{
|
Extra: map[string]interface{}{
|
||||||
artifact.ExtraRefresh: func() error {
|
artifact.ExtraRefresh: func() error {
|
||||||
log.WithField("file", filename).Info("refreshing checksums")
|
log.WithField("file", filename).Info("refreshing checksums")
|
||||||
return refresh(ctx, filepath)
|
return refreshAll(ctx, filepath)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func refresh(ctx *context.Context, filepath string) error {
|
func refreshOne(ctx *context.Context, art artifact.Artifact, path string) error {
|
||||||
lock.Lock()
|
check, err := art.Checksum(ctx.Config.Checksum.Algorithm)
|
||||||
defer lock.Unlock()
|
|
||||||
filter := artifact.Or(
|
|
||||||
artifact.ByType(artifact.UploadableArchive),
|
|
||||||
artifact.ByType(artifact.UploadableBinary),
|
|
||||||
artifact.ByType(artifact.UploadableSourceArchive),
|
|
||||||
artifact.ByType(artifact.LinuxPackage),
|
|
||||||
artifact.ByType(artifact.SBOM),
|
|
||||||
)
|
|
||||||
if len(ctx.Config.Checksum.IDs) > 0 {
|
|
||||||
filter = artifact.And(filter, artifact.ByIDs(ctx.Config.Checksum.IDs...))
|
|
||||||
}
|
|
||||||
|
|
||||||
artifactList := ctx.Artifacts.Filter(filter).List()
|
|
||||||
|
|
||||||
extraFiles, err := extrafiles.Find(ctx, ctx.Config.Checksum.ExtraFiles)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return os.WriteFile(path, []byte(check), 0o644)
|
||||||
|
}
|
||||||
|
|
||||||
for name, path := range extraFiles {
|
func refreshAll(ctx *context.Context, filepath string) error {
|
||||||
artifactList = append(artifactList, &artifact.Artifact{
|
lock.Lock()
|
||||||
Name: name,
|
defer lock.Unlock()
|
||||||
Path: path,
|
|
||||||
Type: artifact.UploadableFile,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(artifactList) == 0 {
|
artifactList, err := buildArtifactList(ctx)
|
||||||
return errNoArtifacts
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
g := semerrgroup.New(ctx.Parallelism)
|
g := semerrgroup.New(ctx.Parallelism)
|
||||||
@ -141,6 +174,39 @@ func refresh(ctx *context.Context, filepath string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildArtifactList(ctx *context.Context) ([]*artifact.Artifact, error) {
|
||||||
|
filter := artifact.Or(
|
||||||
|
artifact.ByType(artifact.UploadableArchive),
|
||||||
|
artifact.ByType(artifact.UploadableBinary),
|
||||||
|
artifact.ByType(artifact.UploadableSourceArchive),
|
||||||
|
artifact.ByType(artifact.LinuxPackage),
|
||||||
|
artifact.ByType(artifact.SBOM),
|
||||||
|
)
|
||||||
|
if len(ctx.Config.Checksum.IDs) > 0 {
|
||||||
|
filter = artifact.And(filter, artifact.ByIDs(ctx.Config.Checksum.IDs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
artifactList := ctx.Artifacts.Filter(filter).List()
|
||||||
|
|
||||||
|
extraFiles, err := extrafiles.Find(ctx, ctx.Config.Checksum.ExtraFiles)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, path := range extraFiles {
|
||||||
|
artifactList = append(artifactList, &artifact.Artifact{
|
||||||
|
Name: name,
|
||||||
|
Path: path,
|
||||||
|
Type: artifact.UploadableFile,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(artifactList) == 0 {
|
||||||
|
return nil, errNoArtifacts
|
||||||
|
}
|
||||||
|
return artifactList, nil
|
||||||
|
}
|
||||||
|
|
||||||
func checksums(algorithm string, a *artifact.Artifact) (string, error) {
|
func checksums(algorithm string, a *artifact.Artifact) (string, error) {
|
||||||
log.WithField("file", a.Name).Debug("checksumming")
|
log.WithField("file", a.Name).Debug("checksumming")
|
||||||
sha, err := a.Checksum(algorithm)
|
sha, err := a.Checksum(algorithm)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package checksums
|
package checksums
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -103,6 +104,66 @@ func TestPipe(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPipeSplit(t *testing.T) {
|
||||||
|
const binary = "binary"
|
||||||
|
const archive = binary + ".tar.gz"
|
||||||
|
const linuxPackage = binary + ".rpm"
|
||||||
|
const sum = "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc"
|
||||||
|
|
||||||
|
folder := t.TempDir()
|
||||||
|
file := filepath.Join(folder, binary)
|
||||||
|
require.NoError(t, os.WriteFile(file, []byte("some string"), 0o644))
|
||||||
|
ctx := testctx.NewWithCfg(
|
||||||
|
config.Project{
|
||||||
|
Dist: folder,
|
||||||
|
ProjectName: "foo",
|
||||||
|
Checksum: config.Checksum{
|
||||||
|
Split: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
ctx.Artifacts.Add(&artifact.Artifact{
|
||||||
|
Name: binary,
|
||||||
|
Path: file,
|
||||||
|
Type: artifact.UploadableBinary,
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
artifact.ExtraID: "id-1",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
ctx.Artifacts.Add(&artifact.Artifact{
|
||||||
|
Name: archive,
|
||||||
|
Path: file,
|
||||||
|
Type: artifact.UploadableArchive,
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
artifact.ExtraID: "id-2",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
ctx.Artifacts.Add(&artifact.Artifact{
|
||||||
|
Name: linuxPackage,
|
||||||
|
Path: file,
|
||||||
|
Type: artifact.LinuxPackage,
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
artifact.ExtraID: "id-3",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, Pipe{}.Default(ctx))
|
||||||
|
require.NoError(t, Pipe{}.Run(ctx))
|
||||||
|
|
||||||
|
require.NoError(t, ctx.Artifacts.Visit(func(a *artifact.Artifact) error {
|
||||||
|
return a.Refresh()
|
||||||
|
}))
|
||||||
|
|
||||||
|
checks := ctx.Artifacts.Filter(artifact.ByType(artifact.Checksum)).List()
|
||||||
|
require.Len(t, checks, 3)
|
||||||
|
|
||||||
|
for _, check := range checks {
|
||||||
|
require.NotEmpty(t, check.Extra[artifact.ExtraChecksumOf])
|
||||||
|
bts, err := os.ReadFile(check.Path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, sum, string(bts))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRefreshModifying(t *testing.T) {
|
func TestRefreshModifying(t *testing.T) {
|
||||||
const binary = "binary"
|
const binary = "binary"
|
||||||
folder := t.TempDir()
|
folder := t.TempDir()
|
||||||
@ -134,6 +195,37 @@ func TestRefreshModifying(t *testing.T) {
|
|||||||
require.NotEqual(t, string(previous), string(current))
|
require.NotEqual(t, string(previous), string(current))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRefreshModifyingSplit(t *testing.T) {
|
||||||
|
const binary = "binary"
|
||||||
|
folder := t.TempDir()
|
||||||
|
file := filepath.Join(folder, binary)
|
||||||
|
require.NoError(t, os.WriteFile(file, []byte("some string"), 0o644))
|
||||||
|
ctx := testctx.NewWithCfg(config.Project{
|
||||||
|
Dist: folder,
|
||||||
|
ProjectName: binary,
|
||||||
|
Checksum: config.Checksum{
|
||||||
|
Split: true,
|
||||||
|
},
|
||||||
|
Env: []string{"FOO=bar"},
|
||||||
|
}, testctx.WithCurrentTag("1.2.3"))
|
||||||
|
ctx.Artifacts.Add(&artifact.Artifact{
|
||||||
|
Name: binary,
|
||||||
|
Path: file,
|
||||||
|
Type: artifact.UploadableBinary,
|
||||||
|
})
|
||||||
|
require.NoError(t, Pipe{}.Default(ctx))
|
||||||
|
require.NoError(t, Pipe{}.Run(ctx))
|
||||||
|
checks := ctx.Artifacts.Filter(artifact.ByType(artifact.Checksum)).List()
|
||||||
|
require.Len(t, checks, 1)
|
||||||
|
previous, err := os.ReadFile(checks[0].Path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, os.WriteFile(file, []byte("some other string"), 0o644))
|
||||||
|
require.NoError(t, checks[0].Refresh())
|
||||||
|
current, err := os.ReadFile(checks[0].Path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEqual(t, string(previous), string(current))
|
||||||
|
}
|
||||||
|
|
||||||
func TestPipeFileNotExist(t *testing.T) {
|
func TestPipeFileNotExist(t *testing.T) {
|
||||||
folder := t.TempDir()
|
folder := t.TempDir()
|
||||||
ctx := testctx.NewWithCfg(
|
ctx := testctx.NewWithCfg(
|
||||||
@ -164,7 +256,8 @@ func TestPipeInvalidNameTemplate(t *testing.T) {
|
|||||||
"{{ .Pro }_checksums.txt",
|
"{{ .Pro }_checksums.txt",
|
||||||
"{{.Env.NOPE}}",
|
"{{.Env.NOPE}}",
|
||||||
} {
|
} {
|
||||||
t.Run(template, func(t *testing.T) {
|
for _, split := range []bool{true, false} {
|
||||||
|
t.Run(fmt.Sprintf("split_%v_%s", split, template), func(t *testing.T) {
|
||||||
folder := t.TempDir()
|
folder := t.TempDir()
|
||||||
ctx := testctx.NewWithCfg(
|
ctx := testctx.NewWithCfg(
|
||||||
config.Project{
|
config.Project{
|
||||||
@ -173,6 +266,7 @@ func TestPipeInvalidNameTemplate(t *testing.T) {
|
|||||||
Checksum: config.Checksum{
|
Checksum: config.Checksum{
|
||||||
NameTemplate: template,
|
NameTemplate: template,
|
||||||
Algorithm: "sha256",
|
Algorithm: "sha256",
|
||||||
|
Split: split,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
testctx.WithCurrentTag("1.2.3"),
|
testctx.WithCurrentTag("1.2.3"),
|
||||||
@ -185,6 +279,7 @@ func TestPipeInvalidNameTemplate(t *testing.T) {
|
|||||||
testlib.RequireTemplateError(t, Pipe{}.Run(ctx))
|
testlib.RequireTemplateError(t, Pipe{}.Run(ctx))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) {
|
func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) {
|
||||||
@ -236,6 +331,21 @@ func TestDefault(t *testing.T) {
|
|||||||
require.Equal(t, "sha256", ctx.Config.Checksum.Algorithm)
|
require.Equal(t, "sha256", ctx.Config.Checksum.Algorithm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultSPlit(t *testing.T) {
|
||||||
|
ctx := testctx.NewWithCfg(config.Project{
|
||||||
|
Checksum: config.Checksum{
|
||||||
|
Split: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, Pipe{}.Default(ctx))
|
||||||
|
require.Equal(
|
||||||
|
t,
|
||||||
|
"{{ .ArtifactName }}.{{ .Algorithm }}",
|
||||||
|
ctx.Config.Checksum.NameTemplate,
|
||||||
|
)
|
||||||
|
require.Equal(t, "sha256", ctx.Config.Checksum.Algorithm)
|
||||||
|
}
|
||||||
|
|
||||||
func TestDefaultSet(t *testing.T) {
|
func TestDefaultSet(t *testing.T) {
|
||||||
ctx := testctx.NewWithCfg(config.Project{
|
ctx := testctx.NewWithCfg(config.Project{
|
||||||
Checksum: config.Checksum{
|
Checksum: config.Checksum{
|
||||||
|
@ -17,21 +17,39 @@ const bodyTemplateText = `{{ with .Header }}{{ . }}{{ "\n" }}{{ end }}
|
|||||||
|
|
||||||
func describeBody(ctx *context.Context) (bytes.Buffer, error) {
|
func describeBody(ctx *context.Context) (bytes.Buffer, error) {
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
var checksum string
|
fields := tmpl.Fields{}
|
||||||
if l := ctx.Artifacts.Filter(artifact.ByType(artifact.Checksum)).List(); len(l) > 0 {
|
|
||||||
if err := l[0].Refresh(); err != nil {
|
checksums := ctx.Artifacts.Filter(artifact.ByType(artifact.Checksum))
|
||||||
|
|
||||||
|
if err := checksums.Visit(func(a *artifact.Artifact) error {
|
||||||
|
return a.Refresh()
|
||||||
|
}); err != nil {
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
bts, err := os.ReadFile(l[0].Path)
|
|
||||||
|
checksumsList := checksums.List()
|
||||||
|
switch len(checksumsList) {
|
||||||
|
case 0:
|
||||||
|
// do nothing
|
||||||
|
case 1:
|
||||||
|
bts, err := os.ReadFile(checksumsList[0].Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
checksum = string(bts)
|
fields["Checksums"] = string(bts)
|
||||||
|
default:
|
||||||
|
checkMap := map[string]string{}
|
||||||
|
for _, check := range checksumsList {
|
||||||
|
bts, err := os.ReadFile(check.Path)
|
||||||
|
if err != nil {
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
checkMap[artifact.ExtraOr(*check, artifact.ExtraChecksumOf, "")] = string(bts)
|
||||||
|
}
|
||||||
|
fields["Checksums"] = checkMap
|
||||||
}
|
}
|
||||||
|
|
||||||
t := tmpl.New(ctx).WithExtraFields(tmpl.Fields{
|
t := tmpl.New(ctx).WithExtraFields(fields)
|
||||||
"Checksums": checksum,
|
|
||||||
})
|
|
||||||
|
|
||||||
header, err := t.Apply(ctx.Config.Release.Header)
|
header, err := t.Apply(ctx.Config.Release.Header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -34,6 +34,49 @@ func TestDontEscapeHTML(t *testing.T) {
|
|||||||
require.Contains(t, out.String(), changelog)
|
require.Contains(t, out.String(), changelog)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDescribeBodyMultipleChecksums(t *testing.T) {
|
||||||
|
ctx := testctx.NewWithCfg(
|
||||||
|
config.Project{
|
||||||
|
Release: config.Release{
|
||||||
|
Header: "## Yada yada yada\nsomething\n",
|
||||||
|
Footer: `
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checksums
|
||||||
|
|
||||||
|
` + "```\n{{ range $key, $value := .Checksums }}{{ $value }} {{ $key }}\n{{ end }}```\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
testctx.WithCurrentTag("v1.0"),
|
||||||
|
func(ctx *context.Context) { ctx.ReleaseNotes = "nothing" },
|
||||||
|
)
|
||||||
|
|
||||||
|
checksums := map[string]string{
|
||||||
|
"bar.zip": "f674623cf1edd0f753e620688cedee4e7c0e837ac1e53c0cbbce132ffe35fd52",
|
||||||
|
"foo.zip": "271a74b75a12f6c3affc88df101f9ef29af79717b1b2f4bdd5964aacf65bcf40",
|
||||||
|
}
|
||||||
|
for name, check := range checksums {
|
||||||
|
name := name
|
||||||
|
check := check
|
||||||
|
checksumPath := filepath.Join(t.TempDir(), name+".sha256")
|
||||||
|
ctx.Artifacts.Add(&artifact.Artifact{
|
||||||
|
Name: name + ".sha256",
|
||||||
|
Path: checksumPath,
|
||||||
|
Type: artifact.Checksum,
|
||||||
|
Extra: map[string]interface{}{
|
||||||
|
artifact.ExtraChecksumOf: name,
|
||||||
|
artifact.ExtraRefresh: func() error {
|
||||||
|
return os.WriteFile(checksumPath, []byte(check), 0o644)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
out, err := describeBody(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
golden.RequireEqual(t, out.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
func TestDescribeBodyWithHeaderAndFooter(t *testing.T) {
|
func TestDescribeBodyWithHeaderAndFooter(t *testing.T) {
|
||||||
changelog := "feature1: description\nfeature2: other description"
|
changelog := "feature1: description\nfeature2: other description"
|
||||||
ctx := testctx.NewWithCfg(
|
ctx := testctx.NewWithCfg(
|
||||||
|
14
internal/pipe/release/testdata/TestDescribeBodyMultipleChecksums.golden
vendored
Normal file
14
internal/pipe/release/testdata/TestDescribeBodyMultipleChecksums.golden
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
## Yada yada yada
|
||||||
|
something
|
||||||
|
|
||||||
|
nothing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checksums
|
||||||
|
|
||||||
|
```
|
||||||
|
f674623cf1edd0f753e620688cedee4e7c0e837ac1e53c0cbbce132ffe35fd52 bar.zip
|
||||||
|
271a74b75a12f6c3affc88df101f9ef29af79717b1b2f4bdd5964aacf65bcf40 foo.zip
|
||||||
|
```
|
||||||
|
|
@ -1030,6 +1030,7 @@ type Snapshot struct {
|
|||||||
type Checksum struct {
|
type Checksum struct {
|
||||||
NameTemplate string `yaml:"name_template,omitempty" json:"name_template,omitempty"`
|
NameTemplate string `yaml:"name_template,omitempty" json:"name_template,omitempty"`
|
||||||
Algorithm string `yaml:"algorithm,omitempty" json:"algorithm,omitempty"`
|
Algorithm string `yaml:"algorithm,omitempty" json:"algorithm,omitempty"`
|
||||||
|
Split bool `yaml:"split,omitempty" json:"split,omitempty"`
|
||||||
IDs []string `yaml:"ids,omitempty" json:"ids,omitempty"`
|
IDs []string `yaml:"ids,omitempty" json:"ids,omitempty"`
|
||||||
Disable bool `yaml:"disable,omitempty" json:"disable,omitempty"`
|
Disable bool `yaml:"disable,omitempty" json:"disable,omitempty"`
|
||||||
ExtraFiles []ExtraFile `yaml:"extra_files,omitempty" json:"extra_files,omitempty"`
|
ExtraFiles []ExtraFile `yaml:"extra_files,omitempty" json:"extra_files,omitempty"`
|
||||||
|
@ -10,7 +10,8 @@ The `checksum` section allows customizations of the filename:
|
|||||||
checksum:
|
checksum:
|
||||||
# You can change the name of the checksums file.
|
# You can change the name of the checksums file.
|
||||||
#
|
#
|
||||||
# Default: {{ .ProjectName }}_{{ .Version }}_checksums.txt
|
# Default: '{{ .ProjectName }}_{{ .Version }}_checksums.txt'
|
||||||
|
# or, when split is set: '{{ .ArtifactName }}.{{ .Algorithm }}'
|
||||||
# Templates: allowed
|
# Templates: allowed
|
||||||
name_template: "{{ .ProjectName }}_checksums.txt"
|
name_template: "{{ .ProjectName }}_checksums.txt"
|
||||||
|
|
||||||
@ -20,6 +21,10 @@ checksum:
|
|||||||
# Default: sha256.
|
# Default: sha256.
|
||||||
algorithm: sha256
|
algorithm: sha256
|
||||||
|
|
||||||
|
# If true, will create one checksum file for each artifact.
|
||||||
|
# Since: v1.25
|
||||||
|
split: true
|
||||||
|
|
||||||
# IDs of artifacts to include in the checksums file.
|
# IDs of artifacts to include in the checksums file.
|
||||||
#
|
#
|
||||||
# If left empty, all published binaries, archives, linux packages and source archives
|
# If left empty, all published binaries, archives, linux packages and source archives
|
||||||
|
@ -134,8 +134,8 @@ In the nFPM name template field, you can use those extra fields:
|
|||||||
In the `release.body` field, you can use these extra fields:
|
In the `release.body` field, you can use these extra fields:
|
||||||
|
|
||||||
| Key | Description |
|
| Key | Description |
|
||||||
| ------------ | ----------------------------------------------------------------------------------- |
|
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| `.Checksums` | the current checksum file contents. Only available in the release body. Since v1.19 |
|
| `.Checksums` | the current checksum file contents, or a map of filename/checksum contents if `checksum.split` is set. Only available in the release body. Since v1.19 |
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user