mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-14 03:51:24 +02:00
feat: winget support (#4081)
this will add support to winget into goreleaser. Basically, the plan is: - we generate the 3 needed yaml files - we commit them to a repo and that's it. Initially, will probably have limited options support, and will only have the default locale. ###### TODO - [x] docs - [x] review by someone who knows how this works? - [x] test install somewhere - [x] more tests maybe? - [x] PR templates via API? https://github.com/goreleaser/goreleaser/pull/4105 - [x] real project test - [x] setup goreleaser to pr to winget as well - [x] document sync fork stuff https://github.com/goreleaser/goreleaser/pull/4106 --------- Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
parent
81bd82b13b
commit
6afdb49c12
@ -204,6 +204,23 @@ nix:
|
||||
installManPage ./manpages/goreleaser.1.gz
|
||||
installShellCompletion ./completions/*
|
||||
|
||||
winget:
|
||||
- name: goreleaser
|
||||
publisher: goreleaser
|
||||
license: MIT
|
||||
homepage: https://goreleaser.com
|
||||
short_description: Deliver Go binaries as fast and easily as possible
|
||||
repository:
|
||||
owner: goreleaser
|
||||
name: winget-pkgs
|
||||
pull_request:
|
||||
enabled: true
|
||||
base:
|
||||
owner: microsoft
|
||||
name: winget-pkgs
|
||||
branch: master
|
||||
draft: true
|
||||
|
||||
aurs:
|
||||
- homepage: https://goreleaser.com
|
||||
description: Deliver Go binaries as fast and easily as possible
|
||||
|
@ -60,6 +60,12 @@ const (
|
||||
BrewTap
|
||||
// Nixpkg is an uploadable nix package.
|
||||
Nixpkg
|
||||
// WingetInstaller winget installer file.
|
||||
WingetInstaller
|
||||
// WingetDefaultLocale winget default locale file.
|
||||
WingetDefaultLocale
|
||||
// WingetVersion winget version file.
|
||||
WingetVersion
|
||||
// PkgBuild is an Arch Linux AUR PKGBUILD file.
|
||||
PkgBuild
|
||||
// SrcInfo is an Arch Linux AUR .SRCINFO file.
|
||||
@ -126,6 +132,8 @@ func (t Type) String() string {
|
||||
return "C Archive Library"
|
||||
case CShared:
|
||||
return "C Shared Library"
|
||||
case WingetInstaller, WingetDefaultLocale, WingetVersion:
|
||||
return "Winget Manifest"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
|
@ -21,27 +21,32 @@ func RequireEqual(tb testing.TB, out []byte) {
|
||||
|
||||
func RequireEqualExt(tb testing.TB, out []byte, ext string) {
|
||||
tb.Helper()
|
||||
doRequireEqual(tb, out, ext, golden)
|
||||
doRequireEqual(tb, out, ext, golden, false)
|
||||
}
|
||||
|
||||
func RequireEqualExtSubfolder(tb testing.TB, out []byte, ext string) {
|
||||
tb.Helper()
|
||||
doRequireEqual(tb, out, ext, golden, true)
|
||||
}
|
||||
|
||||
func RequireEqualTxt(tb testing.TB, out []byte) {
|
||||
tb.Helper()
|
||||
doRequireEqual(tb, out, ".txt", golden)
|
||||
doRequireEqual(tb, out, ".txt", golden, false)
|
||||
}
|
||||
|
||||
func RequireEqualJSON(tb testing.TB, out []byte) {
|
||||
tb.Helper()
|
||||
doRequireEqual(tb, out, ".json", golden)
|
||||
doRequireEqual(tb, out, ".json", golden, false)
|
||||
}
|
||||
|
||||
func RequireEqualRb(tb testing.TB, out []byte) {
|
||||
tb.Helper()
|
||||
doRequireEqual(tb, out, ".rb", golden)
|
||||
doRequireEqual(tb, out, ".rb", golden, false)
|
||||
}
|
||||
|
||||
func RequireEqualYaml(tb testing.TB, out []byte) {
|
||||
tb.Helper()
|
||||
doRequireEqual(tb, out, ".yaml", "")
|
||||
doRequireEqual(tb, out, ".yaml", "", false)
|
||||
}
|
||||
|
||||
func RequireReadFile(tb testing.TB, path string) []byte {
|
||||
@ -51,10 +56,13 @@ func RequireReadFile(tb testing.TB, path string) []byte {
|
||||
return bts
|
||||
}
|
||||
|
||||
func doRequireEqual(tb testing.TB, out []byte, ext, suffix string) {
|
||||
func doRequireEqual(tb testing.TB, out []byte, ext, suffix string, folder bool) {
|
||||
tb.Helper()
|
||||
|
||||
golden := "testdata/" + tb.Name() + ext + suffix
|
||||
golden := filepath.Join("testdata", tb.Name()+ext+suffix)
|
||||
if folder {
|
||||
golden = filepath.Join("testdata", tb.Name(), filepath.Base(tb.Name())+ext+suffix)
|
||||
}
|
||||
if *update {
|
||||
require.NoError(tb, os.MkdirAll(filepath.Dir(golden), 0o755))
|
||||
require.NoError(tb, os.WriteFile(golden, out, 0o655))
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/sign"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/snapcraft"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/upload"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/winget"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
)
|
||||
|
||||
@ -49,6 +50,7 @@ var publishers = []Publisher{
|
||||
release.Pipe{},
|
||||
// brew et al use the release URL, so, they should be last
|
||||
nix.NewPublish(),
|
||||
winget.Pipe{},
|
||||
brew.Pipe{},
|
||||
aur.Pipe{},
|
||||
krew.Pipe{},
|
||||
|
122
internal/pipe/winget/template.go
Normal file
122
internal/pipe/winget/template.go
Normal file
@ -0,0 +1,122 @@
|
||||
package winget
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/caarlos0/log"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/yaml"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
)
|
||||
|
||||
func createYAML(ctx *context.Context, winget config.Winget, in any, tp artifact.Type) error {
|
||||
versionContent, err := yaml.Marshal(in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filename := winget.Name + extFor(tp)
|
||||
path := filepath.Join(ctx.Config.Dist, winget.Path, filename)
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.WithField("path", path).Info("writing")
|
||||
if err := os.WriteFile(path, []byte(strings.Join([]string{
|
||||
generatedHeader,
|
||||
langserverLineFor(tp),
|
||||
string(versionContent),
|
||||
}, "\n")), 0o644); err != nil { //nolint: gosec
|
||||
return fmt.Errorf("failed to write winget version: %w", err)
|
||||
}
|
||||
|
||||
ctx.Artifacts.Add(&artifact.Artifact{
|
||||
Name: filename,
|
||||
Path: path,
|
||||
Type: tp,
|
||||
Extra: map[string]interface{}{
|
||||
wingetConfigExtra: winget,
|
||||
artifact.ExtraID: winget.Name,
|
||||
},
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
manifestVersion = "1.4.0"
|
||||
versionLangServer = "# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json"
|
||||
installerLangServer = "# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json"
|
||||
defaultLocaleLangServer = "# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json"
|
||||
defaultLocale = "en-US"
|
||||
generatedHeader = `# This file was generated by GoReleaser. DO NOT EDIT.`
|
||||
)
|
||||
|
||||
// nolint: tagliatelle
|
||||
type Version struct {
|
||||
PackageIdentifier string `yaml:"PackageIdentifier,omitempty"`
|
||||
PackageVersion string `yaml:"PackageVersion,omitempty"`
|
||||
DefaultLocale string `yaml:"DefaultLocale,omitempty"`
|
||||
ManifestType string `yaml:"ManifestType,omitempty"`
|
||||
ManifestVersion string `yaml:"ManifestVersion,omitempty"`
|
||||
}
|
||||
|
||||
// nolint: tagliatelle
|
||||
type InstallerItemFile struct {
|
||||
RelativeFilePath string `yaml:"RelativeFilePath,omitempty"`
|
||||
}
|
||||
|
||||
// nolint: tagliatelle
|
||||
type InstallerItem struct {
|
||||
Architecture string `yaml:"Architecture,omitempty"`
|
||||
NestedInstallerType string `yaml:"NestedInstallerType,omitempty"`
|
||||
NestedInstallerFiles []InstallerItemFile `yaml:"NestedInstallerFiles,omitempty"`
|
||||
InstallerURL string `yaml:"InstallerUrl,omitempty"`
|
||||
InstallerSha256 string `yaml:"InstallerSha256,omitempty"`
|
||||
UpgradeBehavior string `yaml:"UpgradeBehavior,omitempty"`
|
||||
}
|
||||
|
||||
// nolint: tagliatelle
|
||||
type Installer struct {
|
||||
PackageIdentifier string `yaml:"PackageIdentifier,omitempty"`
|
||||
PackageVersion string `yaml:"PackageVersion,omitempty"`
|
||||
InstallerLocale string `yaml:"InstallerLocale,omitempty"`
|
||||
InstallerType string `yaml:"InstallerType,omitempty"`
|
||||
Commands []string `yaml:"Commands,omitempty"`
|
||||
ReleaseDate string `yaml:"ReleaseDate,omitempty"`
|
||||
Installers []InstallerItem `yaml:"Installers,omitempty"`
|
||||
ManifestType string `yaml:"ManifestType,omitempty"`
|
||||
ManifestVersion string `yaml:"ManifestVersion,omitempty"`
|
||||
}
|
||||
|
||||
// nolint: tagliatelle
|
||||
type Locale struct {
|
||||
PackageIdentifier string `yaml:"PackageIdentifier,omitempty"`
|
||||
PackageVersion string `yaml:"PackageVersion,omitempty"`
|
||||
PackageLocale string `yaml:"PackageLocale,omitempty"`
|
||||
Publisher string `yaml:"Publisher,omitempty"`
|
||||
PublisherURL string `yaml:"PublisherUrl,omitempty"`
|
||||
Author string `yaml:"Author,omitempty"`
|
||||
PackageName string `yaml:"PackageName,omitempty"`
|
||||
PackageURL string `yaml:"PackageUrl,omitempty"`
|
||||
License string `yaml:"License,omitempty"`
|
||||
LicenseURL string `yaml:"LicenseUrl,omitempty"`
|
||||
Copyright string `yaml:"Copyright,omitempty"`
|
||||
ShortDescription string `yaml:"ShortDescription,omitempty"`
|
||||
Description string `yaml:"Description,omitempty"`
|
||||
Moniker string `yaml:"Moniker,omitempty"`
|
||||
Tags []string `yaml:"Tags,omitempty"`
|
||||
ReleaseNotes string `yaml:"ReleaseNotes,omitempty"`
|
||||
ReleaseNotesURL string `yaml:"ReleaseNotesUrl,omitempty"`
|
||||
ManifestType string `yaml:"ManifestType,omitempty"`
|
||||
ManifestVersion string `yaml:"ManifestVersion,omitempty"`
|
||||
}
|
||||
|
||||
var fromGoArch = map[string]string{
|
||||
"amd64": "x64",
|
||||
"386": "x86",
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.foo
|
||||
PackageVersion: 1.2.1
|
||||
PackageLocale: en-US
|
||||
Publisher: Beckersoft
|
||||
PackageName: foo
|
||||
License: MIT
|
||||
ShortDescription: foo bar zaz
|
||||
Moniker: foo
|
||||
ManifestType: defaultLocale
|
||||
ManifestVersion: 1.4.0
|
@ -0,0 +1,17 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.foo
|
||||
PackageVersion: 1.2.1
|
||||
InstallerLocale: en-US
|
||||
InstallerType: zip
|
||||
ReleaseDate: "2023-06-12"
|
||||
Installers:
|
||||
- Architecture: x64
|
||||
NestedInstallerType: portable
|
||||
NestedInstallerFiles:
|
||||
- RelativeFilePath: foo.exe
|
||||
InstallerUrl: https://dummyhost/download/v1.2.1/foo_windows_amd64v1.zip
|
||||
InstallerSha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
UpgradeBehavior: uninstallPrevious
|
||||
ManifestType: installer
|
||||
ManifestVersion: 1.4.0
|
@ -0,0 +1,7 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.foo
|
||||
PackageVersion: 1.2.1
|
||||
DefaultLocale: en-US
|
||||
ManifestType: version
|
||||
ManifestVersion: 1.4.0
|
24
internal/pipe/winget/testdata/TestRunPipe/full/full.en-US.yaml.golden
vendored
Normal file
24
internal/pipe/winget/testdata/TestRunPipe/full/full.en-US.yaml.golden
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.foo
|
||||
PackageVersion: 1.2.1
|
||||
PackageLocale: en-US
|
||||
Publisher: Beckersoft
|
||||
PublisherUrl: https://carlosbecker.com
|
||||
Author: Carlos Becker
|
||||
PackageName: foo
|
||||
PackageUrl: https://goreleaser.com
|
||||
License: MIT
|
||||
LicenseUrl: https://goreleaser.com/eula/
|
||||
Copyright: bla bla bla
|
||||
ShortDescription: foo
|
||||
Description: |-
|
||||
long foo bar
|
||||
|
||||
yadaa yada yada loooaaasssss
|
||||
|
||||
sss
|
||||
Moniker: foo
|
||||
ReleaseNotesUrl: https://github.com/goreleaser/goreleaser/tags/v1.2.1
|
||||
ManifestType: defaultLocale
|
||||
ManifestVersion: 1.4.0
|
17
internal/pipe/winget/testdata/TestRunPipe/full/full.installer.yaml.golden
vendored
Normal file
17
internal/pipe/winget/testdata/TestRunPipe/full/full.installer.yaml.golden
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.foo
|
||||
PackageVersion: 1.2.1
|
||||
InstallerLocale: en-US
|
||||
InstallerType: zip
|
||||
ReleaseDate: "2023-06-12"
|
||||
Installers:
|
||||
- Architecture: x64
|
||||
NestedInstallerType: portable
|
||||
NestedInstallerFiles:
|
||||
- RelativeFilePath: foo.exe
|
||||
InstallerUrl: https://dummyhost/download/v1.2.1/foo_windows_amd64v1.zip
|
||||
InstallerSha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
UpgradeBehavior: uninstallPrevious
|
||||
ManifestType: installer
|
||||
ManifestVersion: 1.4.0
|
7
internal/pipe/winget/testdata/TestRunPipe/full/full.yaml.golden
vendored
Normal file
7
internal/pipe/winget/testdata/TestRunPipe/full/full.yaml.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.foo
|
||||
PackageVersion: 1.2.1
|
||||
DefaultLocale: en-US
|
||||
ManifestType: version
|
||||
ManifestVersion: 1.4.0
|
12
internal/pipe/winget/testdata/TestRunPipe/minimal/minimal.en-US.yaml.golden
vendored
Normal file
12
internal/pipe/winget/testdata/TestRunPipe/minimal/minimal.en-US.yaml.golden
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json
|
||||
PackageIdentifier: Foo.min
|
||||
PackageVersion: 1.2.1
|
||||
PackageLocale: en-US
|
||||
Publisher: Foo
|
||||
PackageName: min
|
||||
License: MIT
|
||||
ShortDescription: foo bar zaz
|
||||
Moniker: min
|
||||
ManifestType: defaultLocale
|
||||
ManifestVersion: 1.4.0
|
17
internal/pipe/winget/testdata/TestRunPipe/minimal/minimal.installer.yaml.golden
vendored
Normal file
17
internal/pipe/winget/testdata/TestRunPipe/minimal/minimal.installer.yaml.golden
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json
|
||||
PackageIdentifier: Foo.min
|
||||
PackageVersion: 1.2.1
|
||||
InstallerLocale: en-US
|
||||
InstallerType: zip
|
||||
ReleaseDate: "2023-06-12"
|
||||
Installers:
|
||||
- Architecture: x64
|
||||
NestedInstallerType: portable
|
||||
NestedInstallerFiles:
|
||||
- RelativeFilePath: foo.exe
|
||||
InstallerUrl: https://dummyhost/download/v1.2.1/foo_windows_amd64v1.zip
|
||||
InstallerSha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
UpgradeBehavior: uninstallPrevious
|
||||
ManifestType: installer
|
||||
ManifestVersion: 1.4.0
|
7
internal/pipe/winget/testdata/TestRunPipe/minimal/minimal.yaml.golden
vendored
Normal file
7
internal/pipe/winget/testdata/TestRunPipe/minimal/minimal.yaml.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json
|
||||
PackageIdentifier: Foo.min
|
||||
PackageVersion: 1.2.1
|
||||
DefaultLocale: en-US
|
||||
ManifestType: version
|
||||
ManifestVersion: 1.4.0
|
14
internal/pipe/winget/testdata/TestRunPipe/open-pr/open-pr.en-US.yaml.golden
vendored
Normal file
14
internal/pipe/winget/testdata/TestRunPipe/open-pr/open-pr.en-US.yaml.golden
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.foo
|
||||
PackageVersion: 1.2.1
|
||||
PackageLocale: en-US
|
||||
Publisher: Beckersoft
|
||||
PackageName: foo
|
||||
PackageUrl: https://goreleaser.com
|
||||
License: mit
|
||||
ShortDescription: foo bar zaz
|
||||
Description: my test
|
||||
Moniker: foo
|
||||
ManifestType: defaultLocale
|
||||
ManifestVersion: 1.4.0
|
17
internal/pipe/winget/testdata/TestRunPipe/open-pr/open-pr.installer.yaml.golden
vendored
Normal file
17
internal/pipe/winget/testdata/TestRunPipe/open-pr/open-pr.installer.yaml.golden
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.foo
|
||||
PackageVersion: 1.2.1
|
||||
InstallerLocale: en-US
|
||||
InstallerType: zip
|
||||
ReleaseDate: "2023-06-12"
|
||||
Installers:
|
||||
- Architecture: x64
|
||||
NestedInstallerType: portable
|
||||
NestedInstallerFiles:
|
||||
- RelativeFilePath: foo.exe
|
||||
InstallerUrl: https://dummyhost/download/v1.2.1/foo_windows_amd64v1.zip
|
||||
InstallerSha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
UpgradeBehavior: uninstallPrevious
|
||||
ManifestType: installer
|
||||
ManifestVersion: 1.4.0
|
7
internal/pipe/winget/testdata/TestRunPipe/open-pr/open-pr.yaml.golden
vendored
Normal file
7
internal/pipe/winget/testdata/TestRunPipe/open-pr/open-pr.yaml.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.foo
|
||||
PackageVersion: 1.2.1
|
||||
DefaultLocale: en-US
|
||||
ManifestType: version
|
||||
ManifestVersion: 1.4.0
|
12
internal/pipe/winget/testdata/TestRunPipe/partial/partial.en-US.yaml.golden
vendored
Normal file
12
internal/pipe/winget/testdata/TestRunPipe/partial/partial.en-US.yaml.golden
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.partial
|
||||
PackageVersion: 1.2.1
|
||||
PackageLocale: en-US
|
||||
Publisher: Beckersoft
|
||||
PackageName: partial
|
||||
License: MIT
|
||||
ShortDescription: foo bar zaz
|
||||
Moniker: partial
|
||||
ManifestType: defaultLocale
|
||||
ManifestVersion: 1.4.0
|
17
internal/pipe/winget/testdata/TestRunPipe/partial/partial.installer.yaml.golden
vendored
Normal file
17
internal/pipe/winget/testdata/TestRunPipe/partial/partial.installer.yaml.golden
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.partial
|
||||
PackageVersion: 1.2.1
|
||||
InstallerLocale: en-US
|
||||
InstallerType: zip
|
||||
ReleaseDate: "2023-06-12"
|
||||
Installers:
|
||||
- Architecture: x64
|
||||
NestedInstallerType: portable
|
||||
NestedInstallerFiles:
|
||||
- RelativeFilePath: foo.exe
|
||||
InstallerUrl: https://dummyhost/download/v1.2.1/foo_windows_amd64v1.zip
|
||||
InstallerSha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
UpgradeBehavior: uninstallPrevious
|
||||
ManifestType: installer
|
||||
ManifestVersion: 1.4.0
|
7
internal/pipe/winget/testdata/TestRunPipe/partial/partial.yaml.golden
vendored
Normal file
7
internal/pipe/winget/testdata/TestRunPipe/partial/partial.yaml.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.partial
|
||||
PackageVersion: 1.2.1
|
||||
DefaultLocale: en-US
|
||||
ManifestType: version
|
||||
ManifestVersion: 1.4.0
|
12
internal/pipe/winget/testdata/TestRunPipe/skip-upload-auto/skip-upload-auto.en-US.yaml.golden
vendored
Normal file
12
internal/pipe/winget/testdata/TestRunPipe/skip-upload-auto/skip-upload-auto.en-US.yaml.golden
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.doesnotmatter
|
||||
PackageVersion: 1.2.1
|
||||
PackageLocale: en-US
|
||||
Publisher: Beckersoft
|
||||
PackageName: doesnotmatter
|
||||
License: MIT
|
||||
ShortDescription: foo bar zaz
|
||||
Moniker: doesnotmatter
|
||||
ManifestType: defaultLocale
|
||||
ManifestVersion: 1.4.0
|
@ -0,0 +1,17 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.doesnotmatter
|
||||
PackageVersion: 1.2.1
|
||||
InstallerLocale: en-US
|
||||
InstallerType: zip
|
||||
ReleaseDate: "2023-06-12"
|
||||
Installers:
|
||||
- Architecture: x64
|
||||
NestedInstallerType: portable
|
||||
NestedInstallerFiles:
|
||||
- RelativeFilePath: foo.exe
|
||||
InstallerUrl: https://dummyhost/download/v1.2.1/foo_windows_amd64v1.zip
|
||||
InstallerSha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
UpgradeBehavior: uninstallPrevious
|
||||
ManifestType: installer
|
||||
ManifestVersion: 1.4.0
|
7
internal/pipe/winget/testdata/TestRunPipe/skip-upload-auto/skip-upload-auto.yaml.golden
vendored
Normal file
7
internal/pipe/winget/testdata/TestRunPipe/skip-upload-auto/skip-upload-auto.yaml.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.doesnotmatter
|
||||
PackageVersion: 1.2.1
|
||||
DefaultLocale: en-US
|
||||
ManifestType: version
|
||||
ManifestVersion: 1.4.0
|
12
internal/pipe/winget/testdata/TestRunPipe/skip-upload/skip-upload.en-US.yaml.golden
vendored
Normal file
12
internal/pipe/winget/testdata/TestRunPipe/skip-upload/skip-upload.en-US.yaml.golden
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.doesnotmatter
|
||||
PackageVersion: 1.2.1
|
||||
PackageLocale: en-US
|
||||
Publisher: Beckersoft
|
||||
PackageName: doesnotmatter
|
||||
License: MIT
|
||||
ShortDescription: foo bar zaz
|
||||
Moniker: doesnotmatter
|
||||
ManifestType: defaultLocale
|
||||
ManifestVersion: 1.4.0
|
17
internal/pipe/winget/testdata/TestRunPipe/skip-upload/skip-upload.installer.yaml.golden
vendored
Normal file
17
internal/pipe/winget/testdata/TestRunPipe/skip-upload/skip-upload.installer.yaml.golden
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.doesnotmatter
|
||||
PackageVersion: 1.2.1
|
||||
InstallerLocale: en-US
|
||||
InstallerType: zip
|
||||
ReleaseDate: "2023-06-12"
|
||||
Installers:
|
||||
- Architecture: x64
|
||||
NestedInstallerType: portable
|
||||
NestedInstallerFiles:
|
||||
- RelativeFilePath: foo.exe
|
||||
InstallerUrl: https://dummyhost/download/v1.2.1/foo_windows_amd64v1.zip
|
||||
InstallerSha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
UpgradeBehavior: uninstallPrevious
|
||||
ManifestType: installer
|
||||
ManifestVersion: 1.4.0
|
7
internal/pipe/winget/testdata/TestRunPipe/skip-upload/skip-upload.yaml.golden
vendored
Normal file
7
internal/pipe/winget/testdata/TestRunPipe/skip-upload/skip-upload.yaml.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.doesnotmatter
|
||||
PackageVersion: 1.2.1
|
||||
DefaultLocale: en-US
|
||||
ManifestType: version
|
||||
ManifestVersion: 1.4.0
|
16
internal/pipe/winget/testdata/TestRunPipe/wrapped-in-dir/wrapped-in-dir.en-US.yaml.golden
vendored
Normal file
16
internal/pipe/winget/testdata/TestRunPipe/wrapped-in-dir/wrapped-in-dir.en-US.yaml.golden
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.wrapped-in-dir
|
||||
PackageVersion: 1.2.1
|
||||
PackageLocale: en-US
|
||||
Publisher: Beckersoft
|
||||
PackageName: wrapped-in-dir
|
||||
PackageUrl: https://goreleaser.com
|
||||
License: mit
|
||||
LicenseUrl: https://goreleaser.com/license
|
||||
ShortDescription: foo bar zaz
|
||||
Description: my test
|
||||
Moniker: wrapped-in-dir
|
||||
ReleaseNotesUrl: https://github.com/goreleaser/goreleaser/tags/v1.2.1
|
||||
ManifestType: defaultLocale
|
||||
ManifestVersion: 1.4.0
|
17
internal/pipe/winget/testdata/TestRunPipe/wrapped-in-dir/wrapped-in-dir.installer.yaml.golden
vendored
Normal file
17
internal/pipe/winget/testdata/TestRunPipe/wrapped-in-dir/wrapped-in-dir.installer.yaml.golden
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.wrapped-in-dir
|
||||
PackageVersion: 1.2.1
|
||||
InstallerLocale: en-US
|
||||
InstallerType: zip
|
||||
ReleaseDate: "2023-06-12"
|
||||
Installers:
|
||||
- Architecture: x64
|
||||
NestedInstallerType: portable
|
||||
NestedInstallerFiles:
|
||||
- RelativeFilePath: foo\foo.exe
|
||||
InstallerUrl: https://dummyhost/download/v1.2.1/foo_windows_amd64v1.zip
|
||||
InstallerSha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
UpgradeBehavior: uninstallPrevious
|
||||
ManifestType: installer
|
||||
ManifestVersion: 1.4.0
|
7
internal/pipe/winget/testdata/TestRunPipe/wrapped-in-dir/wrapped-in-dir.yaml.golden
vendored
Normal file
7
internal/pipe/winget/testdata/TestRunPipe/wrapped-in-dir/wrapped-in-dir.yaml.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This file was generated by GoReleaser. DO NOT EDIT.
|
||||
# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.4.0.schema.json
|
||||
PackageIdentifier: Beckersoft.wrapped-in-dir
|
||||
PackageVersion: 1.2.1
|
||||
DefaultLocale: en-US
|
||||
ManifestType: version
|
||||
ManifestVersion: 1.4.0
|
432
internal/pipe/winget/winget.go
Normal file
432
internal/pipe/winget/winget.go
Normal file
@ -0,0 +1,432 @@
|
||||
package winget
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/caarlos0/log"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/client"
|
||||
"github.com/goreleaser/goreleaser/internal/commitauthor"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe"
|
||||
"github.com/goreleaser/goreleaser/internal/tmpl"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
)
|
||||
|
||||
var (
|
||||
errNoRepoName = pipe.Skip("winget.repository.name name is required")
|
||||
errNoPublisher = pipe.Skip("winget.publisher is required")
|
||||
errNoLicense = pipe.Skip("winget.license is required")
|
||||
errNoShortDescription = pipe.Skip("winget.short_description is required")
|
||||
errInvalidPackageIdentifier = pipe.Skip("winget.package_identifier is invalid")
|
||||
errSkipUpload = pipe.Skip("winget.skip_upload is set")
|
||||
errSkipUploadAuto = pipe.Skip("winget.skip_upload is set to 'auto', and current version is a pre-release")
|
||||
errMultipleArchives = pipe.Skip("found multiple archives for the same platform, please consider filtering by id")
|
||||
packageIdentifierValid = regexp.MustCompile("^[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}(\\.[^\\.\\s\\\\/:\\*\\?\"<>\\|\\x01-\\x1f]{1,32}){1,7}$")
|
||||
)
|
||||
|
||||
type errNoArchivesFound struct {
|
||||
goamd64 string
|
||||
ids []string
|
||||
}
|
||||
|
||||
func (e errNoArchivesFound) Error() string {
|
||||
return fmt.Sprintf("no zip archives found matching goos=[windows] goarch=[amd64 386] goamd64=%s ids=%v", e.goamd64, e.ids)
|
||||
}
|
||||
|
||||
const wingetConfigExtra = "WingetConfig"
|
||||
|
||||
type Pipe struct{}
|
||||
|
||||
func (Pipe) String() string { return "winget" }
|
||||
func (p Pipe) Skip(ctx *context.Context) bool {
|
||||
return len(ctx.Config.Winget) == 0
|
||||
}
|
||||
|
||||
func (Pipe) Default(ctx *context.Context) error {
|
||||
for i := range ctx.Config.Winget {
|
||||
winget := &ctx.Config.Winget[i]
|
||||
|
||||
winget.CommitAuthor = commitauthor.Default(winget.CommitAuthor)
|
||||
|
||||
if winget.CommitMessageTemplate == "" {
|
||||
winget.CommitMessageTemplate = "{{ .ProjectName }}: {{ .PreviousTag }} -> {{ .Tag }}"
|
||||
}
|
||||
if winget.Name == "" {
|
||||
winget.Name = ctx.Config.ProjectName
|
||||
}
|
||||
if winget.Goamd64 == "" {
|
||||
winget.Goamd64 = "v1"
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p Pipe) Run(ctx *context.Context) error {
|
||||
cli, err := client.New(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.runAll(ctx, cli)
|
||||
}
|
||||
|
||||
// Publish .
|
||||
func (p Pipe) Publish(ctx *context.Context) error {
|
||||
cli, err := client.New(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return p.publishAll(ctx, cli)
|
||||
}
|
||||
|
||||
func (p Pipe) runAll(ctx *context.Context, cli client.Client) error {
|
||||
for _, winget := range ctx.Config.Winget {
|
||||
err := p.doRun(ctx, winget, cli)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p Pipe) doRun(ctx *context.Context, winget config.Winget, cl client.ReleaserURLTemplater) error {
|
||||
if winget.Repository.Name == "" {
|
||||
return errNoRepoName
|
||||
}
|
||||
|
||||
publisher, err := tmpl.New(ctx).Apply(winget.Publisher)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if publisher == "" {
|
||||
return errNoPublisher
|
||||
}
|
||||
winget.Publisher = publisher
|
||||
|
||||
if winget.License == "" {
|
||||
return errNoLicense
|
||||
}
|
||||
|
||||
name, err := tmpl.New(ctx).Apply(winget.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.Name = name
|
||||
|
||||
author, err := tmpl.New(ctx).Apply(winget.Author)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.Author = author
|
||||
|
||||
publisherURL, err := tmpl.New(ctx).Apply(winget.PublisherURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.PublisherURL = publisherURL
|
||||
|
||||
homepage, err := tmpl.New(ctx).Apply(winget.Homepage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.Homepage = homepage
|
||||
|
||||
ref, err := client.TemplateRef(tmpl.New(ctx).Apply, winget.Repository)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.Repository = ref
|
||||
|
||||
skipUpload, err := tmpl.New(ctx).Apply(winget.SkipUpload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.SkipUpload = skipUpload
|
||||
|
||||
description, err := tmpl.New(ctx).Apply(winget.Description)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.Description = description
|
||||
|
||||
shortDescription, err := tmpl.New(ctx).Apply(winget.ShortDescription)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.ShortDescription = shortDescription
|
||||
|
||||
if winget.ShortDescription == "" {
|
||||
return errNoShortDescription
|
||||
}
|
||||
|
||||
releaseNotesURL, err := tmpl.New(ctx).Apply(winget.ReleaseNotesURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.ReleaseNotesURL = releaseNotesURL
|
||||
|
||||
if winget.URLTemplate == "" {
|
||||
url, err := cl.ReleaseURLTemplate(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
winget.URLTemplate = url
|
||||
}
|
||||
|
||||
path, err := tmpl.New(ctx).Apply(winget.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if path == "" {
|
||||
path = filepath.Join("manifests", strings.ToLower(string(winget.Publisher[0])), winget.Publisher, winget.Name, ctx.Version)
|
||||
}
|
||||
winget.Path = path
|
||||
|
||||
filters := []artifact.Filter{
|
||||
artifact.ByGoos("windows"),
|
||||
artifact.ByFormats("zip"),
|
||||
artifact.ByType(artifact.UploadableArchive),
|
||||
artifact.Or(
|
||||
artifact.ByGoarch("386"),
|
||||
artifact.And(
|
||||
artifact.ByGoamd64(winget.Goamd64),
|
||||
artifact.ByGoarch("amd64"),
|
||||
),
|
||||
),
|
||||
}
|
||||
if len(winget.IDs) > 0 {
|
||||
filters = append(filters, artifact.ByIDs(winget.IDs...))
|
||||
}
|
||||
archives := ctx.Artifacts.Filter(artifact.And(filters...)).List()
|
||||
if len(archives) == 0 {
|
||||
return errNoArchivesFound{
|
||||
goamd64: winget.Goamd64,
|
||||
ids: winget.IDs,
|
||||
}
|
||||
}
|
||||
|
||||
if winget.PackageIdentifier == "" {
|
||||
winget.PackageIdentifier = publisher + "." + name
|
||||
}
|
||||
|
||||
if !packageIdentifierValid.MatchString(winget.PackageIdentifier) {
|
||||
return fmt.Errorf("%w: %s", errInvalidPackageIdentifier, winget.PackageIdentifier)
|
||||
}
|
||||
|
||||
if err := createYAML(ctx, winget, Version{
|
||||
PackageIdentifier: winget.PackageIdentifier,
|
||||
PackageVersion: ctx.Version,
|
||||
DefaultLocale: defaultLocale,
|
||||
ManifestType: "version",
|
||||
ManifestVersion: manifestVersion,
|
||||
}, artifact.WingetVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
installer := Installer{
|
||||
PackageIdentifier: winget.PackageIdentifier,
|
||||
PackageVersion: ctx.Version,
|
||||
InstallerLocale: defaultLocale,
|
||||
InstallerType: "zip",
|
||||
Commands: []string{},
|
||||
ReleaseDate: ctx.Date.Format(time.DateOnly),
|
||||
Installers: []InstallerItem{},
|
||||
ManifestType: "installer",
|
||||
ManifestVersion: manifestVersion,
|
||||
}
|
||||
|
||||
var amd64Count, i386count int
|
||||
for _, archive := range archives {
|
||||
sha256, err := archive.Checksum("sha256")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var files []InstallerItemFile
|
||||
folder := artifact.ExtraOr(*archive, artifact.ExtraWrappedIn, ".")
|
||||
for _, bin := range artifact.ExtraOr(*archive, artifact.ExtraBinaries, []string{}) {
|
||||
files = append(files, InstallerItemFile{
|
||||
RelativeFilePath: windowsJoin([2]string{folder, bin}),
|
||||
})
|
||||
}
|
||||
url, err := tmpl.New(ctx).WithArtifact(archive).Apply(winget.URLTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
installer.Installers = append(installer.Installers, InstallerItem{
|
||||
Architecture: fromGoArch[archive.Goarch],
|
||||
NestedInstallerType: "portable",
|
||||
NestedInstallerFiles: files,
|
||||
InstallerURL: url,
|
||||
InstallerSha256: sha256,
|
||||
UpgradeBehavior: "uninstallPrevious",
|
||||
})
|
||||
switch archive.Goarch {
|
||||
case "386":
|
||||
i386count++
|
||||
case "amd64":
|
||||
amd64Count++
|
||||
}
|
||||
}
|
||||
|
||||
if i386count > 1 || amd64Count > 1 {
|
||||
return errMultipleArchives
|
||||
}
|
||||
|
||||
if err := createYAML(ctx, winget, installer, artifact.WingetInstaller); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return createYAML(ctx, winget, Locale{
|
||||
PackageIdentifier: winget.PackageIdentifier,
|
||||
PackageVersion: ctx.Version,
|
||||
PackageLocale: defaultLocale,
|
||||
Publisher: publisher,
|
||||
PublisherURL: winget.PublisherURL,
|
||||
Author: author,
|
||||
PackageName: name,
|
||||
PackageURL: winget.Homepage,
|
||||
License: winget.License,
|
||||
LicenseURL: winget.LicenseURL,
|
||||
Copyright: winget.Copyright,
|
||||
ShortDescription: shortDescription,
|
||||
Description: description,
|
||||
Moniker: name,
|
||||
Tags: []string{},
|
||||
ReleaseNotes: ctx.ReleaseNotes,
|
||||
ReleaseNotesURL: winget.ReleaseNotesURL,
|
||||
ManifestType: "defaultLocale",
|
||||
ManifestVersion: manifestVersion,
|
||||
}, artifact.WingetDefaultLocale)
|
||||
}
|
||||
|
||||
func (p Pipe) publishAll(ctx *context.Context, cli client.Client) error {
|
||||
skips := pipe.SkipMemento{}
|
||||
for _, files := range ctx.Artifacts.Filter(artifact.Or(
|
||||
artifact.ByType(artifact.WingetInstaller),
|
||||
artifact.ByType(artifact.WingetVersion),
|
||||
artifact.ByType(artifact.WingetDefaultLocale),
|
||||
)).GroupByID() {
|
||||
err := doPublish(ctx, cli, files)
|
||||
if err != nil && pipe.IsSkip(err) {
|
||||
skips.Remember(err)
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return skips.Evaluate()
|
||||
}
|
||||
|
||||
func doPublish(ctx *context.Context, cl client.Client, wingets []*artifact.Artifact) error {
|
||||
winget, err := artifact.Extra[config.Winget](*wingets[0], wingetConfigExtra)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if strings.TrimSpace(winget.SkipUpload) == "true" {
|
||||
return errSkipUpload
|
||||
}
|
||||
|
||||
if strings.TrimSpace(winget.SkipUpload) == "auto" && ctx.Semver.Prerelease != "" {
|
||||
return errSkipUploadAuto
|
||||
}
|
||||
|
||||
msg, err := tmpl.New(ctx).Apply(winget.CommitMessageTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
author, err := commitauthor.Get(ctx, winget.CommitAuthor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo := client.RepoFromRef(winget.Repository)
|
||||
|
||||
var files []client.RepoFile
|
||||
for _, pkg := range wingets {
|
||||
content, err := os.ReadFile(pkg.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
files = append(files, client.RepoFile{
|
||||
Content: content,
|
||||
Path: filepath.Join(winget.Path, pkg.Name),
|
||||
})
|
||||
}
|
||||
|
||||
if winget.Repository.Git.URL != "" {
|
||||
return client.NewGitUploadClient(repo.Branch).
|
||||
CreateFiles(ctx, author, repo, msg, files)
|
||||
}
|
||||
|
||||
cl, err = client.NewIfToken(ctx, cl, winget.Repository.Token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
if err := cl.CreateFile(ctx, author, repo, file.Content, file.Path, msg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !winget.Repository.PullRequest.Enabled {
|
||||
log.Debug("winget.pull_request disabled")
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("winget.pull_request enabled, creating a PR")
|
||||
pcl, ok := cl.(client.PullRequestOpener)
|
||||
if !ok {
|
||||
return fmt.Errorf("client does not support pull requests")
|
||||
}
|
||||
|
||||
title := fmt.Sprintf("Updated %s to %s", ctx.Config.ProjectName, ctx.Version)
|
||||
return pcl.OpenPullRequest(ctx, client.Repo{
|
||||
Name: winget.Repository.PullRequest.Base.Name,
|
||||
Owner: winget.Repository.PullRequest.Base.Owner,
|
||||
Branch: winget.Repository.PullRequest.Base.Branch,
|
||||
}, repo, title, winget.Repository.PullRequest.Draft)
|
||||
}
|
||||
|
||||
func langserverLineFor(tp artifact.Type) string {
|
||||
switch tp {
|
||||
case artifact.WingetInstaller:
|
||||
return installerLangServer
|
||||
case artifact.WingetDefaultLocale:
|
||||
return defaultLocaleLangServer
|
||||
default:
|
||||
return versionLangServer
|
||||
}
|
||||
}
|
||||
|
||||
func extFor(tp artifact.Type) string {
|
||||
switch tp {
|
||||
case artifact.WingetVersion:
|
||||
return ".yaml"
|
||||
case artifact.WingetInstaller:
|
||||
return ".installer.yaml"
|
||||
case artifact.WingetDefaultLocale:
|
||||
return "." + defaultLocale + ".yaml"
|
||||
default:
|
||||
// should never happen
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func windowsJoin(elem [2]string) string {
|
||||
if elem[0] == "" {
|
||||
return elem[1]
|
||||
}
|
||||
return elem[0] + "\\" + elem[1]
|
||||
}
|
579
internal/pipe/winget/winget_test.go
Normal file
579
internal/pipe/winget/winget_test.go
Normal file
@ -0,0 +1,579 @@
|
||||
package winget
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/client"
|
||||
"github.com/goreleaser/goreleaser/internal/golden"
|
||||
"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("should", func(t *testing.T) {
|
||||
require.True(t, Pipe{}.Skip(testctx.New()))
|
||||
})
|
||||
t.Run("should not", func(t *testing.T) {
|
||||
require.False(t, Pipe{}.Skip(testctx.NewWithCfg(config.Project{
|
||||
Winget: []config.Winget{{}},
|
||||
})))
|
||||
})
|
||||
}
|
||||
|
||||
func TestRunPipe(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
expectRunErrorIs error
|
||||
expectPublishErrorIs error
|
||||
expectPath string
|
||||
winget config.Winget
|
||||
}{
|
||||
{
|
||||
name: "minimal",
|
||||
expectPath: "manifests/f/Foo/min/1.2.1/min.",
|
||||
winget: config.Winget{
|
||||
Name: "min",
|
||||
Publisher: "Foo",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
IDs: []string{"foo"},
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "full",
|
||||
expectPath: "manifests/b/Beckersoft LTDA/foo/1.2.1",
|
||||
winget: config.Winget{
|
||||
Name: "foo",
|
||||
Publisher: "Beckersoft",
|
||||
PublisherURL: "https://carlosbecker.com",
|
||||
Copyright: "bla bla bla",
|
||||
Author: "Carlos Becker",
|
||||
Path: "manifests/b/Beckersoft LTDA/foo/{{.Version}}",
|
||||
Repository: config.RepoRef{Owner: "foo", Name: "bar"},
|
||||
CommitAuthor: config.CommitAuthor{},
|
||||
CommitMessageTemplate: "update foo to latest and greatest",
|
||||
IDs: []string{"foo"},
|
||||
Goamd64: "v1",
|
||||
SkipUpload: "false",
|
||||
ShortDescription: "foo",
|
||||
Description: `long foo bar
|
||||
|
||||
yadaa yada yada loooaaasssss
|
||||
|
||||
sss`,
|
||||
Homepage: "https://goreleaser.com",
|
||||
License: "MIT",
|
||||
LicenseURL: "https://goreleaser.com/eula/",
|
||||
ReleaseNotesURL: "https://github.com/goreleaser/goreleaser/tags/{{.Tag}}",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "open-pr",
|
||||
winget: config.Winget{
|
||||
Name: "foo",
|
||||
Publisher: "Beckersoft",
|
||||
IDs: []string{"foo"},
|
||||
Description: "my test",
|
||||
Homepage: "https://goreleaser.com",
|
||||
License: "mit",
|
||||
Path: "pkgs/foo.winget",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
Branch: "update-{{.Version}}",
|
||||
PullRequest: config.PullRequest{
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "wrapped-in-dir",
|
||||
winget: config.Winget{
|
||||
Name: "wrapped-in-dir",
|
||||
Publisher: "Beckersoft",
|
||||
IDs: []string{"wrapped-in-dir"},
|
||||
Description: "my test",
|
||||
Homepage: "https://goreleaser.com",
|
||||
License: "mit",
|
||||
LicenseURL: "https://goreleaser.com/license",
|
||||
ReleaseNotesURL: "https://github.com/goreleaser/goreleaser/tags/{{.Tag}}",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no-archives",
|
||||
expectRunErrorIs: errNoArchivesFound{
|
||||
goamd64: "v2",
|
||||
ids: []string{"nopenopenope"},
|
||||
},
|
||||
winget: config.Winget{
|
||||
Name: "no-archives",
|
||||
Publisher: "Beckersoft",
|
||||
IDs: []string{"nopenopenope"},
|
||||
Goamd64: "v2",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "too-many-archives",
|
||||
expectRunErrorIs: errMultipleArchives,
|
||||
winget: config.Winget{
|
||||
Name: "min",
|
||||
Publisher: "Foo",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
IDs: []string{},
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "partial",
|
||||
winget: config.Winget{
|
||||
Name: "partial",
|
||||
Publisher: "Beckersoft",
|
||||
IDs: []string{"partial"},
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no-repo-name",
|
||||
expectRunErrorIs: errNoRepoName,
|
||||
winget: config.Winget{
|
||||
Name: "doesnotmatter",
|
||||
Publisher: "Beckersoft",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no-license",
|
||||
expectRunErrorIs: errNoLicense,
|
||||
winget: config.Winget{
|
||||
Name: "doesnotmatter",
|
||||
Publisher: "Beckersoft",
|
||||
ShortDescription: "aa",
|
||||
Repository: config.RepoRef{
|
||||
Name: "foo",
|
||||
Owner: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no-short-description",
|
||||
expectRunErrorIs: errNoShortDescription,
|
||||
winget: config.Winget{
|
||||
Name: "doesnotmatter",
|
||||
Publisher: "Beckersoft",
|
||||
License: "MIT",
|
||||
Repository: config.RepoRef{
|
||||
Name: "foo",
|
||||
Owner: "foo",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid-package-identifier",
|
||||
expectRunErrorIs: errInvalidPackageIdentifier,
|
||||
winget: config.Winget{
|
||||
Name: "min",
|
||||
PackageIdentifier: "foobar",
|
||||
Publisher: "Foo",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no-publisher",
|
||||
expectRunErrorIs: errNoPublisher,
|
||||
winget: config.Winget{
|
||||
Name: "min",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-name-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "{{ .Nope }}",
|
||||
Publisher: "Beckersoft",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-publisher-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foo",
|
||||
Publisher: "{{ .Nope }}",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-publisher-url-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foo",
|
||||
Publisher: "Beckersoft",
|
||||
PublisherURL: "{{ .Nope }}",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-author-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foobar",
|
||||
Publisher: "Beckersoft",
|
||||
Author: "{{ .Nope }}",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-homepage-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foobar",
|
||||
Publisher: "Beckersoft",
|
||||
Homepage: "{{ .Nope }}",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-description-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foobar",
|
||||
Publisher: "Beckersoft",
|
||||
Description: "{{ .Nope }}",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-short-description-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foobar",
|
||||
Publisher: "Beckersoft",
|
||||
ShortDescription: "{{ .Nope }}",
|
||||
License: "MIT",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-repo-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "doesnotmatter",
|
||||
Publisher: "Beckersoft",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "{{ .Nope }}",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-skip-upload-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "doesnotmatter",
|
||||
Publisher: "Beckersoft",
|
||||
SkipUpload: "{{ .Nope }}",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-release-notes-url-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foo",
|
||||
Publisher: "Beckersoft",
|
||||
ReleaseNotesURL: `https://goo/bar/asdfsd/{{.nope}}`,
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-release-url-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foo",
|
||||
Publisher: "Beckersoft",
|
||||
URLTemplate: "{{.BadURL}}",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-path-tmpl",
|
||||
expectRunErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foo",
|
||||
Publisher: "Beckersoft",
|
||||
License: "MIT",
|
||||
Path: "{{ .Nope }}",
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bad-commit-msg-tmpl",
|
||||
expectPublishErrorIs: &template.Error{},
|
||||
winget: config.Winget{
|
||||
Name: "foo",
|
||||
Publisher: "Beckersoft",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
CommitMessageTemplate: "{{.Foo}}",
|
||||
IDs: []string{"foo"},
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "skip-upload",
|
||||
expectPublishErrorIs: errSkipUpload,
|
||||
winget: config.Winget{
|
||||
Name: "doesnotmatter",
|
||||
Publisher: "Beckersoft",
|
||||
SkipUpload: "true",
|
||||
License: "MIT",
|
||||
IDs: []string{"foo"},
|
||||
ShortDescription: "foo bar zaz",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "skip-upload-auto",
|
||||
expectPublishErrorIs: errSkipUploadAuto,
|
||||
winget: config.Winget{
|
||||
Name: "doesnotmatter",
|
||||
Publisher: "Beckersoft",
|
||||
License: "MIT",
|
||||
ShortDescription: "foo bar zaz",
|
||||
IDs: []string{"foo"},
|
||||
SkipUpload: "auto",
|
||||
Repository: config.RepoRef{
|
||||
Owner: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
folder := t.TempDir()
|
||||
ctx := testctx.NewWithCfg(
|
||||
config.Project{
|
||||
Dist: folder,
|
||||
ProjectName: "foo",
|
||||
Winget: []config.Winget{tt.winget},
|
||||
},
|
||||
testctx.WithVersion("1.2.1"),
|
||||
testctx.WithCurrentTag("v1.2.1"),
|
||||
testctx.WithSemver(1, 2, 1, "rc1"),
|
||||
testctx.WithDate(time.Date(2023, 6, 12, 20, 32, 10, 12, time.Local)),
|
||||
)
|
||||
createFakeArtifact := func(id, goos, goarch, goamd64, goarm string, extra map[string]any) {
|
||||
path := filepath.Join(folder, "dist/foo_"+goos+goarch+goamd64+goarm+".zip")
|
||||
art := artifact.Artifact{
|
||||
Name: "foo_" + goos + "_" + goarch + goamd64 + goarm + ".zip",
|
||||
Path: path,
|
||||
Goos: goos,
|
||||
Goarch: goarch,
|
||||
Goarm: goarm,
|
||||
Goamd64: goamd64,
|
||||
Type: artifact.UploadableArchive,
|
||||
Extra: map[string]interface{}{
|
||||
artifact.ExtraID: id,
|
||||
artifact.ExtraFormat: "zip",
|
||||
artifact.ExtraBinaries: []string{"foo.exe"},
|
||||
artifact.ExtraWrappedIn: "",
|
||||
},
|
||||
}
|
||||
for k, v := range extra {
|
||||
art.Extra[k] = v
|
||||
}
|
||||
ctx.Artifacts.Add(&art)
|
||||
|
||||
require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o755))
|
||||
f, err := os.Create(path)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, f.Close())
|
||||
}
|
||||
|
||||
goos := "windows"
|
||||
goarch := "amd64"
|
||||
createFakeArtifact("partial", goos, goarch, "v1", "", nil)
|
||||
createFakeArtifact("foo", goos, goarch, "v1", "", nil)
|
||||
createFakeArtifact("wrapped-in-dir", goos, goarch, "v1", "", map[string]any{artifact.ExtraWrappedIn: "foo"})
|
||||
|
||||
goarch = "3864"
|
||||
createFakeArtifact("foo", goos, goarch, "", "", nil)
|
||||
createFakeArtifact("wrapped-in-dir", goos, goarch, "", "", map[string]any{artifact.ExtraWrappedIn: "foo"})
|
||||
|
||||
client := client.NewMock()
|
||||
pipe := Pipe{}
|
||||
|
||||
// default
|
||||
require.NoError(t, pipe.Default(ctx))
|
||||
|
||||
// run
|
||||
if tt.expectRunErrorIs != nil {
|
||||
err := pipe.runAll(ctx, client)
|
||||
require.Error(t, err)
|
||||
require.ErrorAs(t, err, &tt.expectPublishErrorIs)
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, pipe.runAll(ctx, client))
|
||||
for _, winget := range ctx.Artifacts.Filter(artifact.Or(
|
||||
artifact.ByType(artifact.WingetInstaller),
|
||||
artifact.ByType(artifact.WingetVersion),
|
||||
artifact.ByType(artifact.WingetDefaultLocale),
|
||||
)).List() {
|
||||
bts, err := os.ReadFile(winget.Path)
|
||||
require.NoError(t, err)
|
||||
golden.RequireEqualExtSubfolder(t, bts, extFor(winget.Type))
|
||||
}
|
||||
|
||||
// publish
|
||||
if tt.expectPublishErrorIs != nil {
|
||||
err := pipe.publishAll(ctx, client)
|
||||
require.Error(t, err)
|
||||
require.ErrorAs(t, err, &tt.expectPublishErrorIs)
|
||||
return
|
||||
}
|
||||
require.NoError(t, pipe.publishAll(ctx, client))
|
||||
require.True(t, client.CreatedFile)
|
||||
|
||||
require.NotEmpty(t, client.Path)
|
||||
if tt.expectPath != "" {
|
||||
require.Truef(t, strings.HasPrefix(client.Path, tt.expectPath), "expected %q to begin with %q", client.Path, tt.expectPath)
|
||||
}
|
||||
|
||||
if tt.winget.Repository.PullRequest.Enabled {
|
||||
require.True(t, client.OpenedPullRequest)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrNoArchivesFound(t *testing.T) {
|
||||
require.EqualError(t, errNoArchivesFound{
|
||||
goamd64: "v1",
|
||||
ids: []string{"foo", "bar"},
|
||||
}, "no zip archives found matching goos=[windows] goarch=[amd64 386] goamd64=v1 ids=[foo bar]")
|
||||
}
|
||||
|
||||
func TestDefault(t *testing.T) {
|
||||
ctx := testctx.NewWithCfg(config.Project{
|
||||
ProjectName: "foo",
|
||||
Winget: []config.Winget{{}},
|
||||
})
|
||||
require.NoError(t, Pipe{}.Default(ctx))
|
||||
winget := ctx.Config.Winget[0]
|
||||
require.Equal(t, "v1", winget.Goamd64)
|
||||
require.NotEmpty(t, winget.CommitMessageTemplate)
|
||||
require.Equal(t, "foo", winget.Name)
|
||||
}
|
@ -36,6 +36,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/sourcearchive"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/universalbinary"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/upx"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/winget"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
)
|
||||
|
||||
@ -112,6 +113,8 @@ var Pipeline = append(
|
||||
aur.Pipe{},
|
||||
// create nixpkgs
|
||||
nix.NewBuild(),
|
||||
// winget installers
|
||||
winget.Pipe{},
|
||||
// create brew tap
|
||||
brew.Pipe{},
|
||||
// krew plugins
|
||||
|
@ -260,6 +260,29 @@ type Nix struct {
|
||||
License string `yaml:"license,omitempty" json:"license,omitempty"`
|
||||
}
|
||||
|
||||
type Winget struct {
|
||||
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
||||
PackageIdentifier string `yaml:"package_identifier,omitempty" json:"package_identifier,omitempty"`
|
||||
Publisher string `yaml:"publisher,omitempty" json:"publisher,omitempty"`
|
||||
PublisherURL string `yaml:"publisher_url,omitempty" json:"publisher_url,omitempty"`
|
||||
Copyright string `yaml:"copyright,omitempty" json:"copyright,omitempty"`
|
||||
Author string `yaml:"author,omitempty" json:"author,omitempty"`
|
||||
Path string `yaml:"path,omitempty" json:"path,omitempty"`
|
||||
Repository RepoRef `yaml:"repository,omitempty" json:"repository,omitempty"`
|
||||
CommitAuthor CommitAuthor `yaml:"commit_author,omitempty" json:"commit_author,omitempty"`
|
||||
CommitMessageTemplate string `yaml:"commit_msg_template,omitempty" json:"commit_msg_template,omitempty"`
|
||||
IDs []string `yaml:"ids,omitempty" json:"ids,omitempty"`
|
||||
Goamd64 string `yaml:"goamd64,omitempty" json:"goamd64,omitempty"`
|
||||
SkipUpload string `yaml:"skip_upload,omitempty" json:"skip_upload,omitempty" jsonschema:"oneof_type=string;boolean"`
|
||||
URLTemplate string `yaml:"url_template,omitempty" json:"url_template,omitempty"`
|
||||
ShortDescription string `yaml:"short_description,omitempty" json:"short_description,omitempty"`
|
||||
Description string `yaml:"description,omitempty" json:"description,omitempty"`
|
||||
Homepage string `yaml:"homepage,omitempty" json:"homepage,omitempty"`
|
||||
License string `yaml:"license,omitempty" json:"license,omitempty"`
|
||||
LicenseURL string `yaml:"license_url,omitempty" json:"license_url,omitempty"`
|
||||
ReleaseNotesURL string `yaml:"release_notes_url,omitempty" json:"release_notes_url,omitempty"`
|
||||
}
|
||||
|
||||
// Krew contains the krew section.
|
||||
type Krew struct {
|
||||
IDs []string `yaml:"ids,omitempty" json:"ids,omitempty"`
|
||||
@ -1036,6 +1059,7 @@ type Project struct {
|
||||
Milestones []Milestone `yaml:"milestones,omitempty" json:"milestones,omitempty"`
|
||||
Brews []Homebrew `yaml:"brews,omitempty" json:"brews,omitempty"`
|
||||
Nix []Nix `yaml:"nix,omitempty" json:"nix,omitempty"`
|
||||
Winget []Winget `yaml:"winget,omitempty" json:"winget,omitempty"`
|
||||
AURs []AUR `yaml:"aurs,omitempty" json:"aurs,omitempty"`
|
||||
Krews []Krew `yaml:"krews,omitempty" json:"krews,omitempty"`
|
||||
Kos []Ko `yaml:"kos,omitempty" json:"kos,omitempty"`
|
||||
|
@ -43,6 +43,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/upload"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/upx"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/webhook"
|
||||
"github.com/goreleaser/goreleaser/internal/pipe/winget"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
)
|
||||
|
||||
@ -80,6 +81,7 @@ var Defaulters = []Defaulter{
|
||||
upload.Pipe{},
|
||||
aur.Pipe{},
|
||||
nix.Pipe{},
|
||||
winget.Pipe{},
|
||||
brew.Pipe{},
|
||||
krew.Pipe{},
|
||||
ko.Pipe{},
|
||||
|
111
www/docs/customization/winget.md
Normal file
111
www/docs/customization/winget.md
Normal file
@ -0,0 +1,111 @@
|
||||
# Winget
|
||||
|
||||
> Since: v1.19
|
||||
|
||||
After releasing to GitHub, GitLab, or Gitea, GoReleaser can generate and publish
|
||||
a _winget manifest_ and commit to a git repository, and PR it to `winget-pkgs`
|
||||
if instructed to.
|
||||
|
||||
The `winget` section specifies how the **manifests** should be created:
|
||||
|
||||
```yaml
|
||||
# .goreleaser.yaml
|
||||
winget:
|
||||
- # Name of the recipe
|
||||
#
|
||||
# Default: ProjectName
|
||||
# Templates: allowed
|
||||
name: myproject
|
||||
|
||||
# Publisher name.
|
||||
#
|
||||
# Templates: allowed
|
||||
# Required.
|
||||
publisher: Foo Inc
|
||||
|
||||
# Your app's description.
|
||||
#
|
||||
# Templates: allowed
|
||||
# Required.
|
||||
short_description: "Software to create fast and easy drum rolls."
|
||||
|
||||
# License name.
|
||||
# Required.
|
||||
license: "mit"
|
||||
|
||||
# Publisher URL.
|
||||
#
|
||||
# Templates: allowed
|
||||
publisher_url: https://goreleaser.com
|
||||
|
||||
# Package identifier.
|
||||
#
|
||||
# Default: Publisher.ProjectName
|
||||
# Templates: allowed
|
||||
package_identifier: myproject.myproject
|
||||
|
||||
# IDs of the archives to use.
|
||||
# Empty means all IDs.
|
||||
ids:
|
||||
- foo
|
||||
- bar
|
||||
|
||||
# GOAMD64 to specify which amd64 version to use if there are multiple
|
||||
# versions from the build section.
|
||||
#
|
||||
# Default: v1
|
||||
goamd64: v1
|
||||
|
||||
# URL which is determined by the given Token (github, gitlab or gitea).
|
||||
#
|
||||
# Default depends on the client.
|
||||
# Templates: allowed
|
||||
url_template: "https://github.mycompany.com/foo/bar/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
|
||||
|
||||
# Git author used to commit to the repository.
|
||||
commit_author:
|
||||
name: goreleaserbot
|
||||
email: bot@goreleaser.com
|
||||
|
||||
# The project name and current git tag are used in the format string.
|
||||
#
|
||||
# Templates: allowed
|
||||
commit_msg_template: "{{ .ProjectName }}: {{ .Tag }}"
|
||||
|
||||
# Path for the file inside the repository.
|
||||
#
|
||||
# Default: manifests/<lowercased first char of publisher>/<publisher>/<version>
|
||||
path: manifests/g/goreleaser/1.19
|
||||
|
||||
# Your app's homepage.
|
||||
homepage: "https://example.com/"
|
||||
|
||||
# Your app's long description.
|
||||
#
|
||||
# Templates: allowed
|
||||
description: "Software to create fast and easy drum rolls."
|
||||
|
||||
# License URL.
|
||||
license_url: "https://goreleaser.com/license"
|
||||
|
||||
# Copyright.
|
||||
copyright: "Becker Software LTDA"
|
||||
|
||||
# Setting this will prevent goreleaser to actually try to commit the updated
|
||||
# package - instead, it will be stored on the dist folder only,
|
||||
# leaving the responsibility of publishing it to the user.
|
||||
#
|
||||
# If set to auto, the release will not be uploaded to the repository
|
||||
# in case there is an indicator for prerelease in the tag e.g. v1.0.0-rc1
|
||||
#
|
||||
# Templates: allowed
|
||||
skip_upload: true
|
||||
|
||||
{% include-markdown "../includes/repository.md" comments=false %}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
|
||||
Learn more about the [name template engine](/customization/templates/).
|
||||
|
||||
{% include-markdown "../includes/prs.md" comments=false %}
|
@ -131,6 +131,7 @@ nav:
|
||||
- customization/fury.md
|
||||
- customization/homebrew.md
|
||||
- customization/nix.md
|
||||
- customization/winget.md
|
||||
- customization/aur.md
|
||||
- customization/krew.md
|
||||
- customization/scoop.md
|
||||
|
Loading…
Reference in New Issue
Block a user