mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-26 04:22:05 +02:00
feat: allow multiple scoops (#3963)
This brings the scoops feature a bit more closer to similar pipes, like brew and krew. - It now supports multiple scoops - It improves some validations to prevent wrong manifests - It uses extra.binaries instead of extra.builds, as brew does too - extra.builds is now unused, will be removed in a subsequent PR - More tests were added as well closes #3941 --------- Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
parent
01e9810ab2
commit
eb823dee14
@ -212,14 +212,14 @@ aurs:
|
||||
# man pages
|
||||
install -Dm644 "./manpages/goreleaser.1.gz" "${pkgdir}/usr/share/man/man1/goreleaser.1.gz"
|
||||
|
||||
scoop:
|
||||
bucket:
|
||||
owner: goreleaser
|
||||
name: scoop-bucket
|
||||
folder: bucket
|
||||
homepage: https://goreleaser.com
|
||||
description: Deliver Go binaries as fast and easily as possible
|
||||
license: MIT
|
||||
scoops:
|
||||
- bucket:
|
||||
owner: goreleaser
|
||||
name: scoop-bucket
|
||||
folder: bucket
|
||||
homepage: https://goreleaser.com
|
||||
description: Deliver Go binaries as fast and easily as possible
|
||||
license: MIT
|
||||
|
||||
nfpms:
|
||||
- file_name_template: '{{ .ConventionalFileName }}'
|
||||
|
@ -131,7 +131,7 @@ const (
|
||||
ExtraID = "ID"
|
||||
ExtraBinary = "Binary"
|
||||
ExtraExt = "Ext"
|
||||
ExtraBuilds = "Builds"
|
||||
ExtraBuilds = "Builds" // deprecated
|
||||
ExtraFormat = "Format"
|
||||
ExtraWrappedIn = "WrappedIn"
|
||||
ExtraBinaries = "Binaries"
|
||||
|
@ -14,20 +14,43 @@ import (
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/client"
|
||||
"github.com/goreleaser/goreleaser/internal/commitauthor"
|
||||
"github.com/goreleaser/goreleaser/internal/deprecate"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
)
|
||||
|
||||
// ErrNoWindows when there is no build for windows (goos doesn't contain
|
||||
// windows) or archive.format is binary.
|
||||
type ErrNoWindows struct {
|
||||
goamd64 string
|
||||
// ErrIncorrectArchiveCount happens when a given filter evaluates 0 or more
|
||||
// than 1 archives.
|
||||
type ErrIncorrectArchiveCount struct {
|
||||
goamd64 string
|
||||
ids []string
|
||||
archives []*artifact.Artifact
|
||||
}
|
||||
|
||||
func (e ErrNoWindows) Error() string {
|
||||
return fmt.Sprintf("scoop requires a windows archive, but no archives matched goos=windows goarch=[386 amd64] goamd64=%s\nLearn more at https://goreleaser.com/errors/scoop-archive\n", e.goamd64) // nolint: revive
|
||||
func (e ErrIncorrectArchiveCount) Error() string {
|
||||
b := strings.Builder{}
|
||||
|
||||
_, _ = b.WriteString("scoop requires a single windows archive, ")
|
||||
if len(e.archives) == 0 {
|
||||
_, _ = b.WriteString("but no archives ")
|
||||
} else {
|
||||
_, _ = b.WriteString(fmt.Sprintf("but found %d archives ", len(e.archives)))
|
||||
}
|
||||
|
||||
_, _ = b.WriteString(fmt.Sprintf("matching the given filters: goos=windows goarch=[386 amd64] goamd64=%s ids=%s", e.goamd64, e.ids))
|
||||
|
||||
if len(e.archives) > 0 {
|
||||
names := make([]string, 0, len(e.archives))
|
||||
for _, a := range e.archives {
|
||||
names = append(names, a.Name)
|
||||
}
|
||||
_, _ = b.WriteString(fmt.Sprintf(": %s", names))
|
||||
}
|
||||
|
||||
_, _ = b.WriteString("\nLearn more at https://goreleaser.com/errors/scoop-archive\n")
|
||||
return b.String()
|
||||
}
|
||||
|
||||
const scoopConfigExtra = "ScoopConfig"
|
||||
@ -35,8 +58,10 @@ const scoopConfigExtra = "ScoopConfig"
|
||||
// Pipe that builds and publishes scoop manifests.
|
||||
type Pipe struct{}
|
||||
|
||||
func (Pipe) String() string { return "scoop manifests" }
|
||||
func (Pipe) Skip(ctx *context.Context) bool { return ctx.Config.Scoop.Bucket.Name == "" }
|
||||
func (Pipe) String() string { return "scoop manifests" }
|
||||
func (Pipe) Skip(ctx *context.Context) bool {
|
||||
return ctx.Config.Scoop.Bucket.Name == "" && len(ctx.Config.Scoops) == 0
|
||||
}
|
||||
|
||||
// Run creates the scoop manifest locally.
|
||||
func (Pipe) Run(ctx *context.Context) error {
|
||||
@ -44,7 +69,7 @@ func (Pipe) Run(ctx *context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return doRun(ctx, client)
|
||||
return runAll(ctx, client)
|
||||
}
|
||||
|
||||
// Publish scoop manifest.
|
||||
@ -53,47 +78,74 @@ func (Pipe) Publish(ctx *context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return doPublish(ctx, client)
|
||||
return publishAll(ctx, client)
|
||||
}
|
||||
|
||||
// Default sets the pipe defaults.
|
||||
func (Pipe) Default(ctx *context.Context) error {
|
||||
if ctx.Config.Scoop.Name == "" {
|
||||
ctx.Config.Scoop.Name = ctx.Config.ProjectName
|
||||
if ctx.Config.Scoop.Bucket.Name != "" {
|
||||
deprecate.Notice(ctx, "scoop")
|
||||
ctx.Config.Scoops = append(ctx.Config.Scoops, ctx.Config.Scoop)
|
||||
}
|
||||
ctx.Config.Scoop.CommitAuthor = commitauthor.Default(ctx.Config.Scoop.CommitAuthor)
|
||||
if ctx.Config.Scoop.CommitMessageTemplate == "" {
|
||||
ctx.Config.Scoop.CommitMessageTemplate = "Scoop update for {{ .ProjectName }} version {{ .Tag }}"
|
||||
}
|
||||
if ctx.Config.Scoop.Goamd64 == "" {
|
||||
ctx.Config.Scoop.Goamd64 = "v1"
|
||||
for i := range ctx.Config.Scoops {
|
||||
scoop := &ctx.Config.Scoops[i]
|
||||
if scoop.Name == "" {
|
||||
scoop.Name = ctx.Config.ProjectName
|
||||
}
|
||||
scoop.CommitAuthor = commitauthor.Default(scoop.CommitAuthor)
|
||||
if scoop.CommitMessageTemplate == "" {
|
||||
scoop.CommitMessageTemplate = "Scoop update for {{ .ProjectName }} version {{ .Tag }}"
|
||||
}
|
||||
if scoop.Goamd64 == "" {
|
||||
scoop.Goamd64 = "v1"
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func doRun(ctx *context.Context, cl client.ReleaserURLTemplater) error {
|
||||
scoop := ctx.Config.Scoop
|
||||
func runAll(ctx *context.Context, cl client.ReleaserURLTemplater) error {
|
||||
for _, scoop := range ctx.Config.Scoops {
|
||||
err := doRun(ctx, scoop, cl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
archives := ctx.Artifacts.Filter(
|
||||
artifact.And(
|
||||
artifact.ByGoos("windows"),
|
||||
artifact.ByType(artifact.UploadableArchive),
|
||||
artifact.Or(
|
||||
artifact.And(
|
||||
artifact.ByGoarch("amd64"),
|
||||
artifact.ByGoamd64(scoop.Goamd64),
|
||||
),
|
||||
artifact.ByGoarch("386"),
|
||||
func doRun(ctx *context.Context, scoop config.Scoop, cl client.ReleaserURLTemplater) error {
|
||||
filters := []artifact.Filter{
|
||||
artifact.ByGoos("windows"),
|
||||
artifact.ByType(artifact.UploadableArchive),
|
||||
artifact.Or(
|
||||
artifact.And(
|
||||
artifact.ByGoarch("amd64"),
|
||||
artifact.ByGoamd64(scoop.Goamd64),
|
||||
),
|
||||
artifact.ByGoarch("386"),
|
||||
),
|
||||
).List()
|
||||
}
|
||||
|
||||
if len(scoop.IDs) > 0 {
|
||||
filters = append(filters, artifact.ByIDs(scoop.IDs...))
|
||||
}
|
||||
|
||||
filtered := ctx.Artifacts.Filter(artifact.And(filters...))
|
||||
archives := filtered.List()
|
||||
for _, platArchives := range filtered.GroupByPlatform() {
|
||||
// there might be multiple archives, but only of for each platform
|
||||
if len(platArchives) != 1 {
|
||||
return ErrIncorrectArchiveCount{scoop.Goamd64, scoop.IDs, archives}
|
||||
}
|
||||
}
|
||||
// handle no archives found whatsoever
|
||||
if len(archives) == 0 {
|
||||
return ErrNoWindows{scoop.Goamd64}
|
||||
return ErrIncorrectArchiveCount{scoop.Goamd64, scoop.IDs, archives}
|
||||
}
|
||||
|
||||
filename := scoop.Name + ".json"
|
||||
|
||||
data, err := dataFor(ctx, cl, archives)
|
||||
data, err := dataFor(ctx, scoop, cl, archives)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -119,14 +171,24 @@ func doRun(ctx *context.Context, cl client.ReleaserURLTemplater) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func doPublish(ctx *context.Context, cl client.Client) error {
|
||||
manifests := ctx.Artifacts.Filter(artifact.ByType(artifact.ScoopManifest)).List()
|
||||
if len(manifests) == 0 { // should never happen
|
||||
return nil
|
||||
func publishAll(ctx *context.Context, cli client.Client) error {
|
||||
// even if one of them skips, we run them all, and then show return the skips all at once.
|
||||
// this is needed so we actually create the `dist/foo.rb` file, which is useful for debugging.
|
||||
skips := pipe.SkipMemento{}
|
||||
for _, manifest := range ctx.Artifacts.Filter(artifact.ByType(artifact.ScoopManifest)).List() {
|
||||
err := doPublish(ctx, manifest, cli)
|
||||
if err != nil && pipe.IsSkip(err) {
|
||||
skips.Remember(err)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return skips.Evaluate()
|
||||
}
|
||||
|
||||
manifest := manifests[0]
|
||||
|
||||
func doPublish(ctx *context.Context, manifest *artifact.Artifact, cl client.Client) error {
|
||||
scoop, err := artifact.Extra[config.Scoop](*manifest, scoopConfigExtra)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -231,26 +293,26 @@ func doBuildManifest(manifest Manifest) (bytes.Buffer, error) {
|
||||
return result, err
|
||||
}
|
||||
|
||||
func dataFor(ctx *context.Context, cl client.ReleaserURLTemplater, artifacts []*artifact.Artifact) (Manifest, error) {
|
||||
func dataFor(ctx *context.Context, scoop config.Scoop, cl client.ReleaserURLTemplater, artifacts []*artifact.Artifact) (Manifest, error) {
|
||||
manifest := Manifest{
|
||||
Version: ctx.Version,
|
||||
Architecture: map[string]Resource{},
|
||||
Homepage: ctx.Config.Scoop.Homepage,
|
||||
License: ctx.Config.Scoop.License,
|
||||
Description: ctx.Config.Scoop.Description,
|
||||
Persist: ctx.Config.Scoop.Persist,
|
||||
PreInstall: ctx.Config.Scoop.PreInstall,
|
||||
PostInstall: ctx.Config.Scoop.PostInstall,
|
||||
Depends: ctx.Config.Scoop.Depends,
|
||||
Shortcuts: ctx.Config.Scoop.Shortcuts,
|
||||
Homepage: scoop.Homepage,
|
||||
License: scoop.License,
|
||||
Description: scoop.Description,
|
||||
Persist: scoop.Persist,
|
||||
PreInstall: scoop.PreInstall,
|
||||
PostInstall: scoop.PostInstall,
|
||||
Depends: scoop.Depends,
|
||||
Shortcuts: scoop.Shortcuts,
|
||||
}
|
||||
|
||||
if ctx.Config.Scoop.URLTemplate == "" {
|
||||
if scoop.URLTemplate == "" {
|
||||
url, err := cl.ReleaseURLTemplate(ctx)
|
||||
if err != nil {
|
||||
return manifest, err
|
||||
}
|
||||
ctx.Config.Scoop.URLTemplate = url
|
||||
scoop.URLTemplate = url
|
||||
}
|
||||
|
||||
for _, artifact := range artifacts {
|
||||
@ -268,7 +330,7 @@ func dataFor(ctx *context.Context, cl client.ReleaserURLTemplater, artifacts []*
|
||||
continue
|
||||
}
|
||||
|
||||
url, err := tmpl.New(ctx).WithArtifact(artifact).Apply(ctx.Config.Scoop.URLTemplate)
|
||||
url, err := tmpl.New(ctx).WithArtifact(artifact).Apply(scoop.URLTemplate)
|
||||
if err != nil {
|
||||
return manifest, err
|
||||
}
|
||||
@ -280,7 +342,7 @@ func dataFor(ctx *context.Context, cl client.ReleaserURLTemplater, artifacts []*
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"artifactExtras": artifact.Extra,
|
||||
"fromURLTemplate": ctx.Config.Scoop.URLTemplate,
|
||||
"fromURLTemplate": scoop.URLTemplate,
|
||||
"templatedBrewURL": url,
|
||||
"sum": sum,
|
||||
}).Debug("scoop url templating")
|
||||
@ -302,14 +364,14 @@ func dataFor(ctx *context.Context, cl client.ReleaserURLTemplater, artifacts []*
|
||||
|
||||
func binaries(a artifact.Artifact) ([]string, error) {
|
||||
// nolint: prealloc
|
||||
var bins []string
|
||||
var result []string
|
||||
wrap := artifact.ExtraOr(a, artifact.ExtraWrappedIn, "")
|
||||
builds, err := artifact.Extra[[]artifact.Artifact](a, artifact.ExtraBuilds)
|
||||
bins, err := artifact.Extra[[]string](a, artifact.ExtraBinaries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, b := range builds {
|
||||
bins = append(bins, filepath.Join(wrap, b.Name))
|
||||
for _, b := range bins {
|
||||
result = append(result, filepath.Join(wrap, b))
|
||||
}
|
||||
return bins, nil
|
||||
return result, nil
|
||||
}
|
||||
|
@ -24,14 +24,46 @@ func TestDefault(t *testing.T) {
|
||||
testlib.Mktmp(t)
|
||||
|
||||
ctx := testctx.NewWithCfg(
|
||||
config.Project{ProjectName: "barr"},
|
||||
config.Project{
|
||||
ProjectName: "barr",
|
||||
Scoops: []config.Scoop{
|
||||
{
|
||||
Bucket: config.RepoRef{
|
||||
Name: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
testctx.GitHubTokenType,
|
||||
)
|
||||
require.NoError(t, Pipe{}.Default(ctx))
|
||||
require.Equal(t, ctx.Config.ProjectName, ctx.Config.Scoop.Name)
|
||||
require.NotEmpty(t, ctx.Config.Scoop.CommitAuthor.Name)
|
||||
require.NotEmpty(t, ctx.Config.Scoop.CommitAuthor.Email)
|
||||
require.NotEmpty(t, ctx.Config.Scoop.CommitMessageTemplate)
|
||||
require.Len(t, ctx.Config.Scoops, 1)
|
||||
require.Equal(t, ctx.Config.ProjectName, ctx.Config.Scoops[0].Name)
|
||||
require.NotEmpty(t, ctx.Config.Scoops[0].CommitAuthor.Name)
|
||||
require.NotEmpty(t, ctx.Config.Scoops[0].CommitAuthor.Email)
|
||||
require.NotEmpty(t, ctx.Config.Scoops[0].CommitMessageTemplate)
|
||||
}
|
||||
|
||||
func TestDefaultDeprecated(t *testing.T) {
|
||||
testlib.Mktmp(t)
|
||||
|
||||
ctx := testctx.NewWithCfg(
|
||||
config.Project{
|
||||
ProjectName: "barr",
|
||||
Scoop: config.Scoop{
|
||||
Bucket: config.RepoRef{
|
||||
Name: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
testctx.GitHubTokenType,
|
||||
)
|
||||
require.NoError(t, Pipe{}.Default(ctx))
|
||||
require.Len(t, ctx.Config.Scoops, 1)
|
||||
require.Equal(t, ctx.Config.ProjectName, ctx.Config.Scoops[0].Name)
|
||||
require.NotEmpty(t, ctx.Config.Scoops[0].CommitAuthor.Name)
|
||||
require.NotEmpty(t, ctx.Config.Scoops[0].CommitAuthor.Email)
|
||||
require.NotEmpty(t, ctx.Config.Scoops[0].CommitMessageTemplate)
|
||||
}
|
||||
|
||||
func Test_doRun(t *testing.T) {
|
||||
@ -69,6 +101,88 @@ func Test_doRun(t *testing.T) {
|
||||
assertPublishError errChecker
|
||||
assert asserter
|
||||
}{
|
||||
{
|
||||
"multiple_artifacts",
|
||||
args{
|
||||
testctx.NewWithCfg(
|
||||
config.Project{
|
||||
Dist: t.TempDir(),
|
||||
ProjectName: "multi-arts",
|
||||
Scoops: []config.Scoop{{
|
||||
Bucket: config.RepoRef{
|
||||
Owner: "test",
|
||||
Name: "test",
|
||||
},
|
||||
Folder: "scoops",
|
||||
Description: "A run pipe test formula",
|
||||
Homepage: "https://github.com/goreleaser",
|
||||
}},
|
||||
},
|
||||
testctx.GitHubTokenType,
|
||||
testctx.WithCurrentTag("v1.0.1"),
|
||||
testctx.WithVersion("1.0.1"),
|
||||
),
|
||||
client.NewMock(),
|
||||
},
|
||||
[]artifact.Artifact{
|
||||
{Name: "foo_1.0.1_windows_amd64.tar.gz", Goos: "windows", Goarch: "amd64", Goamd64: "v1", Path: file},
|
||||
{Name: "foos_1.0.1_windows_amd64.tar.gz", Goos: "windows", Goarch: "amd64", Goamd64: "v1", Path: file},
|
||||
},
|
||||
func(tb testing.TB, err error) {
|
||||
tb.Helper()
|
||||
require.EqualError(tb, err, ErrIncorrectArchiveCount{
|
||||
goamd64: "v1",
|
||||
archives: []*artifact.Artifact{
|
||||
{Name: "foo_1.0.1_windows_amd64.tar.gz"},
|
||||
{Name: "foos_1.0.1_windows_amd64.tar.gz"},
|
||||
},
|
||||
}.Error())
|
||||
},
|
||||
nil,
|
||||
noAssertions,
|
||||
},
|
||||
{
|
||||
"multiple_binaries",
|
||||
args{
|
||||
testctx.NewWithCfg(
|
||||
config.Project{
|
||||
Dist: t.TempDir(),
|
||||
ProjectName: "multi-bins",
|
||||
Scoops: []config.Scoop{{
|
||||
Bucket: config.RepoRef{
|
||||
Owner: "test",
|
||||
Name: "test",
|
||||
},
|
||||
IDs: []string{"id2"},
|
||||
Folder: "scoops",
|
||||
Description: "A run pipe test formula",
|
||||
Homepage: "https://github.com/goreleaser",
|
||||
}},
|
||||
},
|
||||
testctx.GitHubTokenType,
|
||||
testctx.WithCurrentTag("v1.0.1"),
|
||||
testctx.WithVersion("1.0.1"),
|
||||
),
|
||||
client.NewMock(),
|
||||
},
|
||||
[]artifact.Artifact{
|
||||
{Name: "foo_1.0.1_windows_amd64.tar.gz", Goos: "windows", Goarch: "amd64", Goamd64: "v1", Path: file, Extra: map[string]any{
|
||||
artifact.ExtraID: "id1",
|
||||
artifact.ExtraBinaries: []string{"bin1", "bin2"},
|
||||
}},
|
||||
{Name: "foos_1.0.1_windows_amd64.tar.gz", Goos: "windows", Goarch: "amd64", Goamd64: "v1", Path: file, Extra: map[string]any{
|
||||
artifact.ExtraID: "id2",
|
||||
artifact.ExtraBinaries: []string{"bin4", "bin3"},
|
||||
}},
|
||||
},
|
||||
shouldNotErr,
|
||||
shouldNotErr,
|
||||
func(tb testing.TB, a args) {
|
||||
tb.Helper()
|
||||
require.Equal(tb, "scoops/multi-bins.json", a.client.Path)
|
||||
golden.RequireEqualJSON(tb, []byte(a.client.Content))
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid public github",
|
||||
args{
|
||||
@ -101,6 +215,7 @@ func Test_doRun(t *testing.T) {
|
||||
func(tb testing.TB, a args) {
|
||||
tb.Helper()
|
||||
require.Equal(tb, "scoops/run-pipe.json", a.client.Path)
|
||||
golden.RequireEqualJSON(tb, []byte(a.client.Content))
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -328,7 +443,7 @@ func Test_doRun(t *testing.T) {
|
||||
client.NewMock(),
|
||||
},
|
||||
[]artifact.Artifact{},
|
||||
shouldErr(ErrNoWindows{"v1"}.Error()),
|
||||
shouldErr(ErrIncorrectArchiveCount{"v1", nil, nil}.Error()),
|
||||
shouldNotErr,
|
||||
noAssertions,
|
||||
},
|
||||
@ -447,7 +562,7 @@ func Test_doRun(t *testing.T) {
|
||||
client.NewMock(),
|
||||
},
|
||||
[]artifact.Artifact{},
|
||||
shouldErr(ErrNoWindows{"v1"}.Error()),
|
||||
shouldErr(ErrIncorrectArchiveCount{"v1", nil, nil}.Error()),
|
||||
shouldNotErr,
|
||||
noAssertions,
|
||||
},
|
||||
@ -487,7 +602,7 @@ func Test_doRun(t *testing.T) {
|
||||
config.Project{
|
||||
Env: []string{"FOO=test", "BRANCH=main"},
|
||||
ProjectName: "run-pipe",
|
||||
Scoop: config.Scoop{
|
||||
Scoops: []config.Scoop{{
|
||||
Bucket: config.RepoRef{
|
||||
Owner: "{{ .Env.FOO }}",
|
||||
Name: "{{ .Env.FOO }}",
|
||||
@ -496,7 +611,7 @@ func Test_doRun(t *testing.T) {
|
||||
Folder: "scoops",
|
||||
Description: "A run pipe test formula",
|
||||
Homepage: "https://github.com/goreleaser",
|
||||
},
|
||||
}},
|
||||
},
|
||||
testctx.GitHubTokenType,
|
||||
testctx.WithCurrentTag("v1.0.1"),
|
||||
@ -519,13 +634,15 @@ func Test_doRun(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx := tt.args.ctx
|
||||
for _, a := range tt.artifacts {
|
||||
a := a
|
||||
a.Type = artifact.UploadableArchive
|
||||
ctx.Artifacts.Add(&a)
|
||||
}
|
||||
require.NoError(t, Pipe{}.Default(ctx))
|
||||
|
||||
tt.assertRunError(t, doRun(ctx, tt.args.client))
|
||||
tt.assertPublishError(t, doPublish(ctx, tt.args.client))
|
||||
tt.assertRunError(t, runAll(ctx, tt.args.client))
|
||||
if tt.assertPublishError != nil {
|
||||
tt.assertPublishError(t, publishAll(ctx, tt.args.client))
|
||||
}
|
||||
tt.assert(t, tt.args)
|
||||
})
|
||||
}
|
||||
@ -537,7 +654,7 @@ func TestRunPipePullRequest(t *testing.T) {
|
||||
config.Project{
|
||||
Dist: folder,
|
||||
ProjectName: "foo",
|
||||
Scoop: config.Scoop{
|
||||
Scoops: []config.Scoop{{
|
||||
Name: "foo",
|
||||
Homepage: "https://goreleaser.com",
|
||||
Description: "Fake desc",
|
||||
@ -549,7 +666,7 @@ func TestRunPipePullRequest(t *testing.T) {
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
testctx.WithVersion("1.2.1"),
|
||||
testctx.WithCurrentTag("v1.2.1"),
|
||||
@ -574,8 +691,8 @@ func TestRunPipePullRequest(t *testing.T) {
|
||||
require.NoError(t, f.Close())
|
||||
|
||||
client := client.NewMock()
|
||||
require.NoError(t, doRun(ctx, client))
|
||||
require.NoError(t, doPublish(ctx, client))
|
||||
require.NoError(t, runAll(ctx, client))
|
||||
require.NoError(t, publishAll(ctx, client))
|
||||
require.True(t, client.CreatedFile)
|
||||
require.True(t, client.OpenedPullRequest)
|
||||
golden.RequireEqualJSON(t, []byte(client.Content))
|
||||
@ -712,7 +829,7 @@ func Test_buildManifest(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, Pipe{}.Default(ctx))
|
||||
|
||||
mf, err := dataFor(ctx, cl, []*artifact.Artifact{
|
||||
mf, err := dataFor(ctx, ctx.Config.Scoops[0], cl, []*artifact.Artifact{
|
||||
{
|
||||
Name: "foo_1.0.1_windows_amd64.tar.gz",
|
||||
Goos: "windows",
|
||||
@ -720,13 +837,9 @@ func Test_buildManifest(t *testing.T) {
|
||||
Goamd64: "v1",
|
||||
Path: file,
|
||||
Extra: map[string]interface{}{
|
||||
artifact.ExtraBuilds: []*artifact.Artifact{
|
||||
{
|
||||
Name: "foo.exe",
|
||||
},
|
||||
{
|
||||
Name: "bar.exe",
|
||||
},
|
||||
artifact.ExtraBinaries: []string{
|
||||
"foo.exe",
|
||||
"bar.exe",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -736,13 +849,9 @@ func Test_buildManifest(t *testing.T) {
|
||||
Goarch: "arm",
|
||||
Path: file,
|
||||
Extra: map[string]interface{}{
|
||||
artifact.ExtraBuilds: []*artifact.Artifact{
|
||||
{
|
||||
Name: "foo.exe",
|
||||
},
|
||||
{
|
||||
Name: "bar.exe",
|
||||
},
|
||||
artifact.ExtraBinaries: []string{
|
||||
"foo.exe",
|
||||
"bar.exe",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -752,13 +861,9 @@ func Test_buildManifest(t *testing.T) {
|
||||
Goarch: "386",
|
||||
Path: file,
|
||||
Extra: map[string]interface{}{
|
||||
artifact.ExtraBuilds: []*artifact.Artifact{
|
||||
{
|
||||
Name: "foo.exe",
|
||||
},
|
||||
{
|
||||
Name: "bar.exe",
|
||||
},
|
||||
artifact.ExtraBinaries: []string{
|
||||
"foo.exe",
|
||||
"bar.exe",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -833,8 +938,8 @@ func TestRunPipeScoopWithSkipUpload(t *testing.T) {
|
||||
|
||||
cli := client.NewMock()
|
||||
require.NoError(t, Pipe{}.Default(ctx))
|
||||
require.NoError(t, doRun(ctx, cli))
|
||||
require.EqualError(t, doPublish(ctx, cli), `scoop.skip_upload is true`)
|
||||
require.NoError(t, runAll(ctx, cli))
|
||||
require.EqualError(t, publishAll(ctx, cli), `scoop.skip_upload is true`)
|
||||
|
||||
distFile := filepath.Join(folder, ctx.Config.Scoop.Name+".json")
|
||||
_, err = os.Stat(distFile)
|
||||
@ -852,7 +957,7 @@ func TestWrapInDirectory(t *testing.T) {
|
||||
Download: "https://gitlab.com",
|
||||
},
|
||||
ProjectName: "run-pipe",
|
||||
Scoop: config.Scoop{
|
||||
Scoops: []config.Scoop{{
|
||||
Bucket: config.RepoRef{
|
||||
Owner: "test",
|
||||
Name: "test",
|
||||
@ -862,7 +967,7 @@ func TestWrapInDirectory(t *testing.T) {
|
||||
URLTemplate: "http://gitlab.mycompany.com/foo/bar/-/releases/{{ .Tag }}/downloads/{{ .ArtifactName }}",
|
||||
CommitMessageTemplate: "chore(scoop): update {{ .ProjectName }} version {{ .Tag }}",
|
||||
Persist: []string{"data.cfg", "etc"},
|
||||
},
|
||||
}},
|
||||
},
|
||||
testctx.GitHubTokenType,
|
||||
testctx.WithCurrentTag("v1.0.1"),
|
||||
@ -872,7 +977,7 @@ func TestWrapInDirectory(t *testing.T) {
|
||||
require.NoError(t, Pipe{}.Default(ctx))
|
||||
cl, err := client.New(ctx)
|
||||
require.NoError(t, err)
|
||||
mf, err := dataFor(ctx, cl, []*artifact.Artifact{
|
||||
mf, err := dataFor(ctx, ctx.Config.Scoops[0], cl, []*artifact.Artifact{
|
||||
{
|
||||
Name: "foo_1.0.1_windows_amd64.tar.gz",
|
||||
Goos: "windows",
|
||||
@ -881,13 +986,9 @@ func TestWrapInDirectory(t *testing.T) {
|
||||
Path: file,
|
||||
Extra: map[string]interface{}{
|
||||
artifact.ExtraWrappedIn: "foo_1.0.1_windows_amd64",
|
||||
artifact.ExtraBuilds: []*artifact.Artifact{
|
||||
{
|
||||
Name: "foo.exe",
|
||||
},
|
||||
{
|
||||
Name: "bar.exe",
|
||||
},
|
||||
artifact.ExtraBinaries: []string{
|
||||
"foo.exe",
|
||||
"bar.exe",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -5,6 +5,11 @@
|
||||
"url": "https://dummyhost/download/v1.0.1/foo_1.0.1_windows_386.tar.gz",
|
||||
"bin": null,
|
||||
"hash": "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269"
|
||||
},
|
||||
"64bit": {
|
||||
"url": "https://dummyhost/download/v1.0.1/foo_1.0.1_windows_amd64.tar.gz",
|
||||
"bin": null,
|
||||
"hash": "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269"
|
||||
}
|
||||
},
|
||||
"homepage": "https://github.com/goreleaser",
|
||||
|
15
internal/pipe/scoop/testdata/Test_doRun/multiple_binaries.json.golden
vendored
Normal file
15
internal/pipe/scoop/testdata/Test_doRun/multiple_binaries.json.golden
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": "1.0.1",
|
||||
"architecture": {
|
||||
"64bit": {
|
||||
"url": "https://dummyhost/download/v1.0.1/foos_1.0.1_windows_amd64.tar.gz",
|
||||
"bin": [
|
||||
"bin4",
|
||||
"bin3"
|
||||
],
|
||||
"hash": "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269"
|
||||
}
|
||||
},
|
||||
"homepage": "https://github.com/goreleaser",
|
||||
"description": "A run pipe test formula"
|
||||
}
|
17
internal/pipe/scoop/testdata/Test_doRun/valid_public_github.json.golden
vendored
Normal file
17
internal/pipe/scoop/testdata/Test_doRun/valid_public_github.json.golden
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"version": "1.0.1",
|
||||
"architecture": {
|
||||
"32bit": {
|
||||
"url": "https://dummyhost/download/v1.0.1/foo_1.0.1_windows_386.tar.gz",
|
||||
"bin": null,
|
||||
"hash": "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269"
|
||||
},
|
||||
"64bit": {
|
||||
"url": "https://dummyhost/download/v1.0.1/foo_1.0.1_windows_amd64.tar.gz",
|
||||
"bin": null,
|
||||
"hash": "5e2bf57d3f40c4b6df69daf1936cb766f832374b4fc0259a7cbff06e2f70f269"
|
||||
}
|
||||
},
|
||||
"homepage": "https://github.com/goreleaser",
|
||||
"description": "A run pipe test formula"
|
||||
}
|
@ -239,6 +239,7 @@ type Ko struct {
|
||||
// Scoop contains the scoop.sh section.
|
||||
type Scoop struct {
|
||||
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
||||
IDs []string `yaml:"ids,omitempty" json:"ids,omitempty"`
|
||||
Bucket RepoRef `yaml:"bucket,omitempty" json:"bucket,omitempty"`
|
||||
Folder string `yaml:"folder,omitempty" json:"folder,omitempty"`
|
||||
CommitAuthor CommitAuthor `yaml:"commit_author,omitempty" json:"commit_author,omitempty"`
|
||||
@ -957,7 +958,8 @@ type Project struct {
|
||||
AURs []AUR `yaml:"aurs,omitempty" json:"aurs,omitempty"`
|
||||
Krews []Krew `yaml:"krews,omitempty" json:"krews,omitempty"`
|
||||
Kos []Ko `yaml:"kos,omitempty" json:"kos,omitempty"`
|
||||
Scoop Scoop `yaml:"scoop,omitempty" json:"scoop,omitempty"`
|
||||
Scoop Scoop `yaml:"scoop,omitempty" json:"scoop,omitempty"` // deprecated
|
||||
Scoops []Scoop `yaml:"scoops,omitempty" json:"scoops,omitempty"`
|
||||
Builds []Build `yaml:"builds,omitempty" json:"builds,omitempty"`
|
||||
Archives []Archive `yaml:"archives,omitempty" json:"archives,omitempty"`
|
||||
NFPMs []NFPM `yaml:"nfpms,omitempty" json:"nfpms,omitempty"`
|
||||
|
@ -8,7 +8,9 @@ commented example below:
|
||||
|
||||
```yaml
|
||||
# .goreleaser.yaml
|
||||
scoop:
|
||||
# Since: v1.18
|
||||
scoops:
|
||||
-
|
||||
# URL which is determined by the given Token (github or gitlab)
|
||||
#
|
||||
# Default:
|
||||
|
@ -37,6 +37,27 @@ Description.
|
||||
-->
|
||||
|
||||
|
||||
### scoop
|
||||
|
||||
> since 2023-04-30 (v1.18.0)
|
||||
|
||||
GoReleaser now allows many `scoop` configurations, so it should be pluralized
|
||||
[accordingly](/customization/scoop).
|
||||
|
||||
=== "Before"
|
||||
|
||||
``` yaml
|
||||
scoop:
|
||||
# ...
|
||||
```
|
||||
|
||||
=== "After"
|
||||
``` yaml
|
||||
scoops:
|
||||
- # ...
|
||||
```
|
||||
|
||||
|
||||
### build
|
||||
|
||||
> since 2023-02-09 (v1.16.0)
|
||||
|
@ -1,7 +1,11 @@
|
||||
# Scoop requires a windows archive
|
||||
# Scoop requires single a windows archive
|
||||
|
||||
The Scoop pipe requires a Windows build and archive.
|
||||
|
||||
Usually, if you see this error, one of these 2 things probably happened:
|
||||
|
||||
## 1. Using binary archive format
|
||||
|
||||
The archive should not be in `binary` format.
|
||||
|
||||
For instance, this won't work:
|
||||
@ -19,5 +23,28 @@ archives:
|
||||
- format: zip
|
||||
```
|
||||
|
||||
## 2. Multiple archives for the same GOOS/GOARCH
|
||||
|
||||
If you build multiple binaries and ship them in multiple archives, for example,
|
||||
one for the _client_ and another one for the _server_ of a given project, you
|
||||
will need to have multiple `scoops` in your configuration as well.
|
||||
|
||||
Scoops only allow to install a single archive per manifest, so we need to do
|
||||
something like this:
|
||||
|
||||
```yaml
|
||||
scoops:
|
||||
- ids: [ client ]
|
||||
name: foo
|
||||
# ...
|
||||
- ids: [ server ]
|
||||
name: food
|
||||
# ...
|
||||
```
|
||||
|
||||
## Footnotes
|
||||
|
||||
Also notice the `goamd64` options, it must match the one from your build.
|
||||
By default, only `GOAMD64` `v1` is built.
|
||||
|
||||
Please refer to the [documentation](/customization/scoop) for more details.
|
||||
|
Loading…
x
Reference in New Issue
Block a user