1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-03-17 20:47:50 +02:00

feat: log generated artifact sizes (#3954)

This adds a log with the size of the generated binaries/packages/etc in
the end of the build process, and also adds it to the artifacts.json

closes #3949

TODO:

- [x] tests
- [x] docs
- [ ] ??

---------

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
Carlos Alexandro Becker 2023-04-23 20:27:16 -03:00 committed by GitHub
parent 3324f01bb5
commit f3e1170a89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 150 additions and 1 deletions

View File

@ -13,6 +13,8 @@ snapshot:
gomod:
proxy: true
report_sizes: true
builds:
- env:
- CGO_ENABLED=0

View File

@ -138,6 +138,7 @@ const (
ExtraRefresh = "Refresh"
ExtraReplaces = "Replaces"
ExtraDigest = "Digest"
ExtraSize = "Size"
)
// Extras represents the extra fields in an artifact.

View File

@ -0,0 +1,48 @@
package reportsizes
import (
"os"
"path/filepath"
"github.com/caarlos0/log"
"github.com/docker/go-units"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/pkg/context"
)
type Pipe struct{}
func (Pipe) Skip(ctx *context.Context) bool { return !ctx.Config.ReportSizes }
func (Pipe) String() string { return "size reports" }
func (Pipe) Run(ctx *context.Context) error {
cwd, err := os.Getwd()
if err != nil {
return err
}
return ctx.Artifacts.Filter(artifact.Or(
artifact.ByType(artifact.Binary),
artifact.ByType(artifact.UniversalBinary),
artifact.ByType(artifact.UploadableArchive),
artifact.ByType(artifact.PublishableSnapcraft),
artifact.ByType(artifact.LinuxPackage),
artifact.ByType(artifact.CArchive),
artifact.ByType(artifact.CShared),
artifact.ByType(artifact.Header),
)).Visit(func(a *artifact.Artifact) error {
stat, err := os.Stat(a.Path)
if err != nil {
return err
}
relpath := a.Path
if filepath.IsAbs(a.Path) {
relpath, err = filepath.Rel(cwd, a.Path)
if err != nil {
return err
}
}
a.Extra[artifact.ExtraSize] = stat.Size()
log.WithField("path", relpath).Info(units.BytesSize(float64(stat.Size())))
return nil
})
}

View File

@ -0,0 +1,67 @@
package reportsizes
import (
"os"
"path/filepath"
"testing"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/goreleaser/goreleaser/internal/testctx"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/stretchr/testify/require"
)
func TestString(t *testing.T) {
require.NotEmpty(t, Pipe{}.String())
}
func TestSkip(t *testing.T) {
t.Run("skip", func(t *testing.T) {
require.True(t, Pipe{}.Skip(testctx.NewWithCfg(config.Project{
ReportSizes: false,
})))
})
t.Run("dont skip", func(t *testing.T) {
require.False(t, Pipe{}.Skip(testctx.NewWithCfg(config.Project{
ReportSizes: true,
})))
})
}
func TestRun(t *testing.T) {
ctx := testctx.New()
for i, tp := range []artifact.Type{
artifact.Binary,
artifact.UniversalBinary,
artifact.UploadableArchive,
artifact.PublishableSnapcraft,
artifact.LinuxPackage,
artifact.CArchive,
artifact.CShared,
artifact.Header,
} {
if i%2 == 0 {
cw, err := os.Getwd()
require.NoError(t, err)
ctx.Artifacts.Add(&artifact.Artifact{
Name: "foo",
Path: filepath.Join(cw, "reportsizes.go"),
Extra: map[string]any{},
Type: tp,
})
continue
}
ctx.Artifacts.Add(&artifact.Artifact{
Name: "foo",
Path: "reportsizes.go",
Extra: map[string]any{},
Type: tp,
})
}
require.NoError(t, Pipe{}.Run(ctx))
for _, art := range ctx.Artifacts.List() {
require.NotZero(t, artifact.ExtraOr[int64](*art, artifact.ExtraSize, 0))
}
}

View File

@ -25,6 +25,7 @@ import (
"github.com/goreleaser/goreleaser/internal/pipe/nfpm"
"github.com/goreleaser/goreleaser/internal/pipe/prebuild"
"github.com/goreleaser/goreleaser/internal/pipe/publish"
"github.com/goreleaser/goreleaser/internal/pipe/reportsizes"
"github.com/goreleaser/goreleaser/internal/pipe/sbom"
"github.com/goreleaser/goreleaser/internal/pipe/scoop"
"github.com/goreleaser/goreleaser/internal/pipe/semver"
@ -77,7 +78,7 @@ var BuildPipeline = []Piper{
// BuildCmdPipeline is the pipeline run by goreleaser build.
// nolint:gochecknoglobals
var BuildCmdPipeline = append(BuildPipeline, metadata.Pipe{})
var BuildCmdPipeline = append(BuildPipeline, metadata.Pipe{}, reportsizes.Pipe{})
// Pipeline contains all pipe implementations in order.
// nolint: gochecknoglobals
@ -109,6 +110,8 @@ var Pipeline = append(
scoop.Pipe{},
// create chocolatey pkg and publish
chocolatey.Pipe{},
// reports artifacts sizes to the log and to artifacts.json
reportsizes.Pipe{},
// create and push docker images
docker.Pipe{},
// publishes artifacts

View File

@ -975,6 +975,7 @@ type Project struct {
SBOMs []SBOM `yaml:"sboms,omitempty" json:"sboms,omitempty"`
Chocolateys []Chocolatey `yaml:"chocolateys,omitempty" json:"chocolateys,omitempty"`
Git Git `yaml:"git,omitempty" json:"git,omitempty"`
ReportSizes bool `yaml:"report_sizes,omitempty" json:"report_sizes,omitempty"`
UniversalBinaries []UniversalBinary `yaml:"universal_binaries,omitempty" json:"universal_binaries,omitempty"`

View File

@ -0,0 +1,26 @@
# Report Sizes
> Since v1.18
You might want to enable this if you want to keep an eye on your binary/package
sizes.
It'll report the size of each artifact of the following types to the build
output, as well as on `dist/artifacts.json`:
- `Binary,`
- `UniversalBinary,`
- `UploadableArchive,`
- `PublishableSnapcraft,`
- `LinuxPackage,`
- `CArchive,`
- `CShared,`
- `Header,`
Here's the available configuration options:
```yaml
# .goreleaser.yaml
# Whether to enable the size reporting or not.
report_sizes: true
```

View File

@ -116,6 +116,7 @@ nav:
- customization/docker_manifest.md
- customization/ko.md
- customization/sbom.md
- customization/reportsizes.md
- Signing:
- Checksums and artifacts: customization/sign.md
- Docker Images and Manifests: customization/docker_sign.md