1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-10 03:47:03 +02:00
goreleaser/pkg/config/config.go
fredbi 8d6ef40020
feat(yaml): upgraded from yaml.v2 to yaml.v3 (#3004)
* chore(yaml): upgraded from yaml.v2 to yaml.v3

* provided internal package to take care of backward
  compatible settings:
    * UnmarshalStrict method
    * mute io.EOF unmarshaling errors
    * marshal indenting with 2 chars
* adapted unit tests to new yaml v3

Signed-off-by: Frederic BIDON <fredbi@yahoo.com>

* fixed failing tests

Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
2022-03-29 14:00:53 -03:00

1061 lines
40 KiB
Go

// Package config contains the model and loader of the goreleaser configuration
// file.
package config
import (
"io"
"os"
"strings"
"time"
"github.com/alecthomas/jsonschema"
"github.com/apex/log"
"github.com/goreleaser/goreleaser/internal/yaml"
"github.com/goreleaser/nfpm/v2/files"
)
// GitHubURLs holds the URLs to be used when using github enterprise.
type GitHubURLs struct {
API string `yaml:"api,omitempty"`
Upload string `yaml:"upload,omitempty"`
Download string `yaml:"download,omitempty"`
SkipTLSVerify bool `yaml:"skip_tls_verify,omitempty"`
}
// GitLabURLs holds the URLs to be used when using gitlab ce/enterprise.
type GitLabURLs struct {
API string `yaml:"api,omitempty"`
Download string `yaml:"download,omitempty"`
SkipTLSVerify bool `yaml:"skip_tls_verify,omitempty"`
UsePackageRegistry bool `yaml:"use_package_registry,omitempty"`
}
// GiteaURLs holds the URLs to be used when using gitea.
type GiteaURLs struct {
API string `yaml:"api,omitempty"`
Download string `yaml:"download,omitempty"`
SkipTLSVerify bool `yaml:"skip_tls_verify,omitempty"`
}
// Repo represents any kind of repo (github, gitlab, etc).
// to upload releases into.
type Repo struct {
Owner string `yaml:"owner,omitempty"`
Name string `yaml:"name,omitempty"`
}
// String of the repo, e.g. owner/name.
func (r Repo) String() string {
if r.Owner == "" && r.Name == "" {
return ""
}
return r.Owner + "/" + r.Name
}
// RepoRef represents any kind of repo which may differ
// from the one we are building from and may therefore
// also require separate authentication
// e.g. Homebrew Tap, Scoop bucket.
type RepoRef struct {
Owner string `yaml:"owner,omitempty"`
Name string `yaml:"name,omitempty"`
Token string `yaml:"token,omitempty"`
Branch string `yaml:"branch,omitempty"`
}
// HomebrewDependency represents Homebrew dependency.
type HomebrewDependency struct {
Name string `yaml:"name,omitempty"`
Type string `yaml:"type,omitempty"`
}
// type alias to prevent stack overflowing in the custom unmarshaler.
type homebrewDependency HomebrewDependency
// UnmarshalYAML is a custom unmarshaler that accept brew deps in both the old and new format.
func (a *HomebrewDependency) UnmarshalYAML(unmarshal func(interface{}) error) error {
var str string
if err := unmarshal(&str); err == nil {
a.Name = str
return nil
}
var dep homebrewDependency
if err := unmarshal(&dep); err != nil {
return err
}
a.Name = dep.Name
a.Type = dep.Type
return nil
}
func (a HomebrewDependency) JSONSchemaType() *jsonschema.Type {
reflector := jsonschema.Reflector{
ExpandedStruct: true,
}
schema := reflector.Reflect(&homebrewDependency{})
return &jsonschema.Type{
OneOf: []*jsonschema.Type{
{
Type: "string",
},
schema.Type,
},
}
}
type AUR struct {
Name string `yaml:"name,omitempty"`
IDs []string `yaml:"ids,omitempty"`
CommitAuthor CommitAuthor `yaml:"commit_author,omitempty"`
CommitMessageTemplate string `yaml:"commit_msg_template,omitempty"`
Description string `yaml:"description,omitempty"`
Homepage string `yaml:"homepage,omitempty"`
License string `yaml:"license,omitempty"`
SkipUpload string `yaml:"skip_upload,omitempty"`
URLTemplate string `yaml:"url_template,omitempty"`
Maintainers []string `yaml:"maintainers,omitempty"`
Contributors []string `yaml:"contributors,omitempty"`
Provides []string `yaml:"provides,omitempty"`
Conflicts []string `yaml:"conflicts,omitempty"`
Depends []string `yaml:"depends,omitempty"`
OptDepends []string `yaml:"optdepends,omitempty"`
Rel string `yaml:"rel,omitempty"`
Package string `yaml:"package,omitempty"`
GitURL string `yaml:"git_url,omitempty"`
GitSSHCommand string `yaml:"git_ssh_command,omitempty"`
PrivateKey string `yaml:"private_key,omitempty"`
}
// GoFish contains the gofish section.
type GoFish struct {
Name string `yaml:"name,omitempty"`
Rig RepoRef `yaml:"rig,omitempty"`
CommitAuthor CommitAuthor `yaml:"commit_author,omitempty"`
CommitMessageTemplate string `yaml:"commit_msg_template,omitempty"`
Description string `yaml:"description,omitempty"`
Homepage string `yaml:"homepage,omitempty"`
License string `yaml:"license,omitempty"`
SkipUpload string `yaml:"skip_upload,omitempty"`
URLTemplate string `yaml:"url_template,omitempty"`
IDs []string `yaml:"ids,omitempty"`
Goarm string `yaml:"goarm,omitempty"`
}
// Homebrew contains the brew section.
type Homebrew struct {
Name string `yaml:"name,omitempty"`
Tap RepoRef `yaml:"tap,omitempty"`
CommitAuthor CommitAuthor `yaml:"commit_author,omitempty"`
CommitMessageTemplate string `yaml:"commit_msg_template,omitempty"`
Folder string `yaml:"folder,omitempty"`
Caveats string `yaml:"caveats,omitempty"`
Plist string `yaml:"plist,omitempty"`
Install string `yaml:"install,omitempty"`
PostInstall string `yaml:"post_install,omitempty"`
Dependencies []HomebrewDependency `yaml:"dependencies,omitempty"`
Test string `yaml:"test,omitempty"`
Conflicts []string `yaml:"conflicts,omitempty"`
Description string `yaml:"description,omitempty"`
Homepage string `yaml:"homepage,omitempty"`
License string `yaml:"license,omitempty"`
SkipUpload string `yaml:"skip_upload,omitempty"`
DownloadStrategy string `yaml:"download_strategy,omitempty"`
URLTemplate string `yaml:"url_template,omitempty"`
CustomRequire string `yaml:"custom_require,omitempty"`
CustomBlock string `yaml:"custom_block,omitempty"`
IDs []string `yaml:"ids,omitempty"`
Goarm string `yaml:"goarm,omitempty"`
Service string `yaml:"service,omitempty"`
}
// Krew contains the krew section.
type Krew struct {
IDs []string `yaml:"ids,omitempty"`
Name string `yaml:"name,omitempty"`
Index RepoRef `yaml:"index,omitempty"`
CommitAuthor CommitAuthor `yaml:"commit_author,omitempty"`
CommitMessageTemplate string `yaml:"commit_msg_template,omitempty"`
Caveats string `yaml:"caveats,omitempty"`
ShortDescription string `yaml:"short_description,omitempty"`
Description string `yaml:"description,omitempty"`
Homepage string `yaml:"homepage,omitempty"`
URLTemplate string `yaml:"url_template,omitempty"`
Goarm string `yaml:"goarm,omitempty"`
SkipUpload string `yaml:"skip_upload,omitempty"`
}
// Scoop contains the scoop.sh section.
type Scoop struct {
Name string `yaml:"name,omitempty"`
Bucket RepoRef `yaml:"bucket,omitempty"`
Folder string `yaml:"folder,omitempty"`
CommitAuthor CommitAuthor `yaml:"commit_author,omitempty"`
CommitMessageTemplate string `yaml:"commit_msg_template,omitempty"`
Homepage string `yaml:"homepage,omitempty"`
Description string `yaml:"description,omitempty"`
License string `yaml:"license,omitempty"`
URLTemplate string `yaml:"url_template,omitempty"`
Persist []string `yaml:"persist,omitempty"`
SkipUpload string `yaml:"skip_upload,omitempty"`
PreInstall []string `yaml:"pre_install,omitempty"`
PostInstall []string `yaml:"post_install,omitempty"`
}
// CommitAuthor is the author of a Git commit.
type CommitAuthor struct {
Name string `yaml:"name,omitempty"`
Email string `yaml:"email,omitempty"`
}
// BuildHooks define actions to run before and/or after something.
type BuildHooks struct { // renamed on pro
Pre string `yaml:"pre,omitempty"`
Post string `yaml:"post,omitempty"`
}
// IgnoredBuild represents a build ignored by the user.
type IgnoredBuild struct {
Goos string `yaml:"goos,omitempty"`
Goarch string `yaml:"goarch,omitempty"`
Goarm string `yaml:"goarm,omitempty"`
Gomips string `yaml:"gomips,omitempty"`
}
// StringArray is a wrapper for an array of strings.
type StringArray []string
// UnmarshalYAML is a custom unmarshaler that wraps strings in arrays.
func (a *StringArray) UnmarshalYAML(unmarshal func(interface{}) error) error {
var strings []string
if err := unmarshal(&strings); err != nil {
var str string
if err := unmarshal(&str); err != nil {
return err
}
*a = []string{str}
} else {
*a = strings
}
return nil
}
func (a StringArray) JSONSchemaType() *jsonschema.Type {
return &jsonschema.Type{
OneOf: []*jsonschema.Type{{
Type: "string",
}, {
Type: "array",
Items: &jsonschema.Type{
Type: "string",
},
}},
}
}
// FlagArray is a wrapper for an array of strings.
type FlagArray []string
// UnmarshalYAML is a custom unmarshaler that wraps strings in arrays.
func (a *FlagArray) UnmarshalYAML(unmarshal func(interface{}) error) error {
var flags []string
if err := unmarshal(&flags); err != nil {
var flagstr string
if err := unmarshal(&flagstr); err != nil {
return err
}
*a = strings.Fields(flagstr)
} else {
*a = flags
}
return nil
}
func (a FlagArray) JSONSchemaType() *jsonschema.Type {
return &jsonschema.Type{
OneOf: []*jsonschema.Type{{
Type: "string",
}, {
Type: "array",
Items: &jsonschema.Type{
Type: "string",
},
}},
}
}
// Build contains the build configuration section.
type Build struct {
ID string `yaml:"id,omitempty"`
Goos []string `yaml:"goos,omitempty"`
Goarch []string `yaml:"goarch,omitempty"`
Goarm []string `yaml:"goarm,omitempty"`
Gomips []string `yaml:"gomips,omitempty"`
Targets []string `yaml:"targets,omitempty"`
Ignore []IgnoredBuild `yaml:"ignore,omitempty"`
Dir string `yaml:"dir,omitempty"`
Main string `yaml:"main,omitempty"`
Binary string `yaml:"binary,omitempty"`
Hooks BuildHookConfig `yaml:"hooks,omitempty"`
Env []string `yaml:"env,omitempty"`
Builder string `yaml:"builder,omitempty"`
ModTimestamp string `yaml:"mod_timestamp,omitempty"`
Skip bool `yaml:"skip,omitempty"`
GoBinary string `yaml:"gobinary,omitempty"`
NoUniqueDistDir bool `yaml:"no_unique_dist_dir,omitempty"`
UnproxiedMain string `yaml:"-"` // used by gomod.proxy
UnproxiedDir string `yaml:"-"` // used by gomod.proxy
BuildDetails `yaml:",inline"` // nolint: tagliatelle
BuildDetailsOverrides []BuildDetailsOverride `yaml:"overrides,omitempty"`
}
type BuildDetailsOverride struct {
Goos string `yaml:"goos,omitempty"`
Goarch string `yaml:"goarch,omitempty"`
Goarm string `yaml:"goarm,omitempty"`
Gomips string `yaml:"gomips,omitempty"`
BuildDetails `yaml:",inline"` // nolint: tagliatelle
}
type BuildDetails struct {
Ldflags StringArray `yaml:"ldflags,omitempty"`
Tags FlagArray `yaml:"tags,omitempty"`
Flags FlagArray `yaml:"flags,omitempty"`
Asmflags StringArray `yaml:"asmflags,omitempty"`
Gcflags StringArray `yaml:"gcflags,omitempty"`
}
type BuildHookConfig struct {
Pre Hooks `yaml:"pre,omitempty"`
Post Hooks `yaml:"post,omitempty"`
}
type Hooks []Hook
// UnmarshalYAML is a custom unmarshaler that allows simplified declaration of single command.
func (bhc *Hooks) UnmarshalYAML(unmarshal func(interface{}) error) error {
var singleCmd string
err := unmarshal(&singleCmd)
if err == nil {
*bhc = []Hook{{Cmd: singleCmd}}
return nil
}
type t Hooks
var hooks t
if err := unmarshal(&hooks); err != nil {
return err
}
*bhc = (Hooks)(hooks)
return nil
}
func (bhc Hooks) JSONSchemaType() *jsonschema.Type {
type t Hooks
reflector := jsonschema.Reflector{
ExpandedStruct: true,
}
schema := reflector.Reflect(&t{})
return &jsonschema.Type{
Items: &jsonschema.Type{
OneOf: []*jsonschema.Type{
{
Type: "string",
},
schema.Type,
},
},
}
}
type Hook struct {
Dir string `yaml:"dir,omitempty"`
Cmd string `yaml:"cmd,omitempty"`
Env []string `yaml:"env,omitempty"`
Output bool `yaml:"output,omitempty"`
}
// UnmarshalYAML is a custom unmarshaler that allows simplified declarations of commands as strings.
func (bh *Hook) UnmarshalYAML(unmarshal func(interface{}) error) error {
var cmd string
if err := unmarshal(&cmd); err != nil {
type t Hook
var hook t
if err := unmarshal(&hook); err != nil {
return err
}
*bh = (Hook)(hook)
return nil
}
bh.Cmd = cmd
return nil
}
func (bh Hook) JSONSchemaType() *jsonschema.Type {
type t Hook
reflector := jsonschema.Reflector{
ExpandedStruct: true,
}
schema := reflector.Reflect(&t{})
return &jsonschema.Type{
OneOf: []*jsonschema.Type{
{
Type: "string",
},
schema.Type,
},
}
}
// FormatOverride is used to specify a custom format for a specific GOOS.
type FormatOverride struct {
Goos string `yaml:"goos,omitempty"`
Format string `yaml:"format,omitempty"`
}
// File is a file inside an archive.
type File struct {
Source string `yaml:"src,omitempty"`
Destination string `yaml:"dst,omitempty"`
StripParent bool `yaml:"strip_parent,omitempty"`
Info FileInfo `yaml:"info,omitempty"`
}
// FileInfo is the file info of a file.
type FileInfo struct {
Owner string `yaml:"owner,omitempty"`
Group string `yaml:"group,omitempty"`
Mode os.FileMode `yaml:"mode,omitempty"`
MTime time.Time `yaml:"mtime,omitempty"`
}
// type alias to prevent stack overflow
type fileAlias File
// UnmarshalYAML is a custom unmarshaler that wraps strings in arrays.
func (f *File) UnmarshalYAML(unmarshal func(interface{}) error) error {
var str string
if err := unmarshal(&str); err == nil {
*f = File{Source: str}
return nil
}
var file fileAlias
if err := unmarshal(&file); err != nil {
return err
}
*f = File(file)
return nil
}
func (f File) JSONSchemaType() *jsonschema.Type {
type t File
reflector := jsonschema.Reflector{
ExpandedStruct: true,
}
schema := reflector.Reflect(&t{})
// jsonschema would just refer to FileInfo in the definition. It doesn't get included there, as we override the
// generated schema with JSONSchemaType here. So we need to include it directly in the schema of File.
schema.Properties.Set("info", reflector.Reflect(&FileInfo{}).Type)
return &jsonschema.Type{
OneOf: []*jsonschema.Type{
{
Type: "string",
},
schema.Type,
},
}
}
// UniversalBinary setups macos universal binaries.
type UniversalBinary struct {
ID string `yaml:"id,omitempty"` // deprecated
IDs []string `yaml:"ids,omitempty"`
NameTemplate string `yaml:"name_template,omitempty"`
Replace bool `yaml:"replace,omitempty"`
Hooks BuildHookConfig `yaml:"hooks,omitempty"`
}
// Archive config used for the archive.
type Archive struct {
ID string `yaml:"id,omitempty"`
Builds []string `yaml:"builds,omitempty"`
NameTemplate string `yaml:"name_template,omitempty"`
Replacements map[string]string `yaml:"replacements,omitempty"`
Format string `yaml:"format,omitempty"`
FormatOverrides []FormatOverride `yaml:"format_overrides,omitempty"`
WrapInDirectory string `yaml:"wrap_in_directory,omitempty"`
Files []File `yaml:"files,omitempty"`
AllowDifferentBinaryCount bool `yaml:"allow_different_binary_count,omitempty"`
}
type ReleaseNotesMode string
const (
ReleaseNotesModeKeepExisting ReleaseNotesMode = "keep-existing"
ReleaseNotesModeAppend ReleaseNotesMode = "append"
ReleaseNotesModeReplace ReleaseNotesMode = "replace"
ReleaseNotesModePrepend ReleaseNotesMode = "prepend"
)
// Release config used for the GitHub/GitLab release.
type Release struct {
GitHub Repo `yaml:"github,omitempty"`
GitLab Repo `yaml:"gitlab,omitempty"`
Gitea Repo `yaml:"gitea,omitempty"`
Draft bool `yaml:"draft,omitempty"`
Disable bool `yaml:"disable,omitempty"`
Prerelease string `yaml:"prerelease,omitempty"`
NameTemplate string `yaml:"name_template,omitempty"`
IDs []string `yaml:"ids,omitempty"`
ExtraFiles []ExtraFile `yaml:"extra_files,omitempty"`
DiscussionCategoryName string `yaml:"discussion_category_name,omitempty"`
Header string `yaml:"header,omitempty"`
Footer string `yaml:"footer,omitempty"`
ReleaseNotesMode ReleaseNotesMode `yaml:"mode,omitempty" jsonschema:"enum=keep-existing,enum=append,enum=prepend,enum=replace,default=keep-existing"`
}
// Milestone config used for VCS milestone.
type Milestone struct {
Repo Repo `yaml:"repo,omitempty"`
Close bool `yaml:"close,omitempty"`
FailOnError bool `yaml:"fail_on_error,omitempty"`
NameTemplate string `yaml:"name_template,omitempty"`
}
// ExtraFile on a release.
type ExtraFile struct {
Glob string `yaml:"glob,omitempty"`
NameTemplate string `yaml:"name_template,omitempty"`
}
// NFPM config.
type NFPM struct {
NFPMOverridables `yaml:",inline"` // nolint: tagliatelle
Overrides map[string]NFPMOverridables `yaml:"overrides,omitempty"`
ID string `yaml:"id,omitempty"`
Builds []string `yaml:"builds,omitempty"`
Formats []string `yaml:"formats,omitempty"`
Section string `yaml:"section,omitempty"`
Priority string `yaml:"priority,omitempty"`
Vendor string `yaml:"vendor,omitempty"`
Homepage string `yaml:"homepage,omitempty"`
Maintainer string `yaml:"maintainer,omitempty"`
Description string `yaml:"description,omitempty"`
License string `yaml:"license,omitempty"`
Bindir string `yaml:"bindir,omitempty"`
Meta bool `yaml:"meta,omitempty"` // make package without binaries - only deps
}
// NFPMScripts is used to specify maintainer scripts.
type NFPMScripts struct {
PreInstall string `yaml:"preinstall,omitempty"`
PostInstall string `yaml:"postinstall,omitempty"`
PreRemove string `yaml:"preremove,omitempty"`
PostRemove string `yaml:"postremove,omitempty"`
}
type NFPMRPMSignature struct {
// PGP secret key, can be ASCII-armored
KeyFile string `yaml:"key_file,omitempty"`
KeyPassphrase string `yaml:"-"` // populated from environment variable
}
// NFPMRPMScripts represents scripts only available on RPM packages.
type NFPMRPMScripts struct {
PreTrans string `yaml:"pretrans,omitempty"`
PostTrans string `yaml:"posttrans,omitempty"`
}
// NFPMRPM is custom configs that are only available on RPM packages.
type NFPMRPM struct {
Summary string `yaml:"summary,omitempty"`
Group string `yaml:"group,omitempty"`
Compression string `yaml:"compression,omitempty"`
Signature NFPMRPMSignature `yaml:"signature,omitempty"`
Scripts NFPMRPMScripts `yaml:"scripts,omitempty"`
}
// NFPMDebScripts is scripts only available on deb packages.
type NFPMDebScripts struct {
Rules string `yaml:"rules,omitempty"`
Templates string `yaml:"templates,omitempty"`
}
// NFPMDebTriggers contains triggers only available for deb packages.
// https://wiki.debian.org/DpkgTriggers
// https://man7.org/linux/man-pages/man5/deb-triggers.5.html
type NFPMDebTriggers struct {
Interest []string `yaml:"interest,omitempty"`
InterestAwait []string `yaml:"interest_await,omitempty"`
InterestNoAwait []string `yaml:"interest_noawait,omitempty"`
Activate []string `yaml:"activate,omitempty"`
ActivateAwait []string `yaml:"activate_await,omitempty"`
ActivateNoAwait []string `yaml:"activate_noawait,omitempty"`
}
// NFPMDebSignature contains config for signing deb packages created by nfpm.
type NFPMDebSignature struct {
// PGP secret key, can be ASCII-armored
KeyFile string `yaml:"key_file,omitempty"`
KeyPassphrase string `yaml:"-"` // populated from environment variable
// origin, maint or archive (defaults to origin)
Type string `yaml:"type,omitempty"`
}
// NFPMDeb is custom configs that are only available on deb packages.
type NFPMDeb struct {
Scripts NFPMDebScripts `yaml:"scripts,omitempty"`
Triggers NFPMDebTriggers `yaml:"triggers,omitempty"`
Breaks []string `yaml:"breaks,omitempty"`
Signature NFPMDebSignature `yaml:"signature,omitempty"`
Lintian []string `yaml:"lintian_overrides,omitempty"`
}
type NFPMAPKScripts struct {
PreUpgrade string `yaml:"preupgrade,omitempty"`
PostUpgrade string `yaml:"postupgrade,omitempty"`
}
// NFPMAPKSignature contains config for signing apk packages created by nfpm.
type NFPMAPKSignature struct {
// RSA private key in PEM format
KeyFile string `yaml:"key_file,omitempty"`
KeyPassphrase string `yaml:"-"` // populated from environment variable
// defaults to <maintainer email>.rsa.pub
KeyName string `yaml:"key_name,omitempty"`
}
// NFPMAPK is custom config only available on apk packages.
type NFPMAPK struct {
Scripts NFPMAPKScripts `yaml:"scripts,omitempty"`
Signature NFPMAPKSignature `yaml:"signature,omitempty"`
}
// NFPMOverridables is used to specify per package format settings.
type NFPMOverridables struct {
FileNameTemplate string `yaml:"file_name_template,omitempty"`
PackageName string `yaml:"package_name,omitempty"`
Epoch string `yaml:"epoch,omitempty"`
Release string `yaml:"release,omitempty"`
Prerelease string `yaml:"prerelease,omitempty"`
VersionMetadata string `yaml:"version_metadata,omitempty"`
Replacements map[string]string `yaml:"replacements,omitempty"`
Dependencies []string `yaml:"dependencies,omitempty"`
Recommends []string `yaml:"recommends,omitempty"`
Suggests []string `yaml:"suggests,omitempty"`
Conflicts []string `yaml:"conflicts,omitempty"`
Replaces []string `yaml:"replaces,omitempty"`
EmptyFolders []string `yaml:"empty_folders,omitempty"` // deprecated
Contents files.Contents `yaml:"contents,omitempty"`
Scripts NFPMScripts `yaml:"scripts,omitempty"`
RPM NFPMRPM `yaml:"rpm,omitempty"`
Deb NFPMDeb `yaml:"deb,omitempty"`
APK NFPMAPK `yaml:"apk,omitempty"`
}
// SBOM config.
type SBOM struct {
ID string `yaml:"id,omitempty"`
Cmd string `yaml:"cmd,omitempty"`
Env []string `yaml:"env,omitempty"`
Args []string `yaml:"args,omitempty"`
Documents []string `yaml:"documents,omitempty"`
Artifacts string `yaml:"artifacts,omitempty"`
IDs []string `yaml:"ids,omitempty"`
}
// Sign config.
type Sign struct {
ID string `yaml:"id,omitempty"`
Cmd string `yaml:"cmd,omitempty"`
Args []string `yaml:"args,omitempty"`
Signature string `yaml:"signature,omitempty"`
Artifacts string `yaml:"artifacts,omitempty"`
IDs []string `yaml:"ids,omitempty"`
Stdin *string `yaml:"stdin,omitempty"`
StdinFile string `yaml:"stdin_file,omitempty"`
Env []string `yaml:"env,omitempty"`
Certificate string `yaml:"certificate,omitempty"`
Output bool `yaml:"output,omitempty"`
}
// SnapcraftAppMetadata for the binaries that will be in the snap package.
type SnapcraftAppMetadata struct {
Command string `yaml:"command"`
Args string `yaml:"args,omitempty"`
Adapter string `yaml:"adapter,omitempty"`
After []string `yaml:"after,omitempty"`
Aliases []string `yaml:"aliases,omitempty"`
Autostart string `yaml:"autostart,omitempty"`
Before []string `yaml:"before,omitempty"`
BusName string `yaml:"bus_name,omitempty"`
CommandChain []string `yaml:"command_chain,omitempty"`
CommonID string `yaml:"common_id,omitempty"`
Completer string `yaml:"completer,omitempty"`
Daemon string `yaml:"daemon,omitempty"`
Desktop string `yaml:"desktop,omitempty"`
Environment map[string]interface{} `yaml:"environment,omitempty"`
Extensions []string `yaml:"extensions,omitempty"`
InstallMode string `yaml:"install_mode,omitempty"`
Passthrough map[string]interface{} `yaml:"passthrough,omitempty"`
Plugs []string `yaml:"plugs,omitempty"`
PostStopCommand string `yaml:"post_stop_command,omitempty"`
RefreshMode string `yaml:"refresh_mode,omitempty"`
ReloadCommand string `yaml:"reload_command,omitempty"`
RestartCondition string `yaml:"restart_condition,omitempty"`
RestartDelay string `yaml:"restart_delay,omitempty"`
Slots []string `yaml:"slots,omitempty"`
Sockets map[string]interface{} `yaml:"sockets,omitempty"`
StartTimeout string `yaml:"start_timeout,omitempty"`
StopCommand string `yaml:"stop_command,omitempty"`
StopMode string `yaml:"stop_mode,omitempty"`
StopTimeout string `yaml:"stop_timeout,omitempty"`
Timer string `yaml:"timer,omitempty"`
WatchdogTimeout string `yaml:"watchdog_timeout,omitempty"`
}
type SnapcraftLayoutMetadata struct {
Symlink string `yaml:"symlink,omitempty"`
Bind string `yaml:"bind,omitempty"`
BindFile string `yaml:"bind_file,omitempty"`
Type string `yaml:"type,omitempty"`
}
// Snapcraft config.
type Snapcraft struct {
NameTemplate string `yaml:"name_template,omitempty"`
Replacements map[string]string `yaml:"replacements,omitempty"`
Publish bool `yaml:"publish,omitempty"`
ID string `yaml:"id,omitempty"`
Builds []string `yaml:"builds,omitempty"`
Name string `yaml:"name,omitempty"`
Summary string `yaml:"summary,omitempty"`
Description string `yaml:"description,omitempty"`
Base string `yaml:"base,omitempty"`
License string `yaml:"license,omitempty"`
Grade string `yaml:"grade,omitempty"`
ChannelTemplates []string `yaml:"channel_templates,omitempty"`
Confinement string `yaml:"confinement,omitempty"`
Layout map[string]SnapcraftLayoutMetadata `yaml:"layout,omitempty"`
Apps map[string]SnapcraftAppMetadata `yaml:"apps,omitempty"`
Plugs map[string]interface{} `yaml:"plugs,omitempty"`
Files []SnapcraftExtraFiles `yaml:"extra_files,omitempty"`
}
// SnapcraftExtraFiles config.
type SnapcraftExtraFiles struct {
Source string `yaml:"source"`
Destination string `yaml:"destination,omitempty"`
Mode uint32 `yaml:"mode,omitempty"`
}
// Snapshot config.
type Snapshot struct {
NameTemplate string `yaml:"name_template,omitempty"`
}
// Checksum config.
type Checksum struct {
NameTemplate string `yaml:"name_template,omitempty"`
Algorithm string `yaml:"algorithm,omitempty"`
IDs []string `yaml:"ids,omitempty"`
Disable bool `yaml:"disable,omitempty"`
ExtraFiles []ExtraFile `yaml:"extra_files,omitempty"`
}
// Docker image config.
type Docker struct {
ID string `yaml:"id,omitempty"`
IDs []string `yaml:"ids,omitempty"`
Goos string `yaml:"goos,omitempty"`
Goarch string `yaml:"goarch,omitempty"`
Goarm string `yaml:"goarm,omitempty"`
Dockerfile string `yaml:"dockerfile,omitempty"`
ImageTemplates []string `yaml:"image_templates,omitempty"`
SkipPush string `yaml:"skip_push,omitempty"`
Files []string `yaml:"extra_files,omitempty"`
BuildFlagTemplates []string `yaml:"build_flag_templates,omitempty"`
PushFlags []string `yaml:"push_flags,omitempty"`
Use string `yaml:"use,omitempty"`
}
// DockerManifest config.
type DockerManifest struct {
ID string `yaml:"id,omitempty"`
NameTemplate string `yaml:"name_template,omitempty"`
SkipPush string `yaml:"skip_push,omitempty"`
ImageTemplates []string `yaml:"image_templates,omitempty"`
CreateFlags []string `yaml:"create_flags,omitempty"`
PushFlags []string `yaml:"push_flags,omitempty"`
Use string `yaml:"use,omitempty"`
}
// Filters config.
type Filters struct {
Exclude []string `yaml:"exclude,omitempty"`
}
// Changelog Config.
type Changelog struct {
Filters Filters `yaml:"filters,omitempty"`
Sort string `yaml:"sort,omitempty"`
Skip bool `yaml:"skip,omitempty"` // TODO(caarlos0): rename to Disable to match other pipes
Use string `yaml:"use,omitempty" jsonschema:"enum=git,enum=github,enum=github-native,enum=gitlab,default=git"`
Groups []ChangeLogGroup `yaml:"groups,omitempty"`
}
// ChangeLogGroup holds the grouping criteria for the changelog.
type ChangeLogGroup struct {
Title string `yaml:"title,omitempty"`
Regexp string `yaml:"regexp,omitempty"`
Order int `yaml:"order,omitempty"`
}
// EnvFiles holds paths to files that contains environment variables
// values like the github token for example.
type EnvFiles struct {
GitHubToken string `yaml:"github_token,omitempty"`
GitLabToken string `yaml:"gitlab_token,omitempty"`
GiteaToken string `yaml:"gitea_token,omitempty"`
}
// Before config.
type Before struct {
Hooks []string `yaml:"hooks,omitempty"`
}
// Blob contains config for GO CDK blob.
type Blob struct {
Bucket string `yaml:"bucket,omitempty"`
Provider string `yaml:"provider,omitempty"`
Region string `yaml:"region,omitempty"`
DisableSSL bool `yaml:"disableSSL,omitempty"` // nolint:tagliatelle // TODO(caarlos0): rename to disable_ssl
Folder string `yaml:"folder,omitempty"`
KMSKey string `yaml:"kmskey,omitempty"`
IDs []string `yaml:"ids,omitempty"`
Endpoint string `yaml:"endpoint,omitempty"` // used for minio for example
ExtraFiles []ExtraFile `yaml:"extra_files,omitempty"`
}
// Upload configuration.
type Upload struct {
Name string `yaml:"name,omitempty"`
IDs []string `yaml:"ids,omitempty"`
Exts []string `yaml:"exts,omitempty"`
Target string `yaml:"target,omitempty"`
Username string `yaml:"username,omitempty"`
Mode string `yaml:"mode,omitempty"`
Method string `yaml:"method,omitempty"`
ChecksumHeader string `yaml:"checksum_header,omitempty"`
TrustedCerts string `yaml:"trusted_certificates,omitempty"`
Checksum bool `yaml:"checksum,omitempty"`
Signature bool `yaml:"signature,omitempty"`
CustomArtifactName bool `yaml:"custom_artifact_name,omitempty"`
CustomHeaders map[string]string `yaml:"custom_headers,omitempty"`
}
// Publisher configuration.
type Publisher struct {
Name string `yaml:"name,omitempty"`
IDs []string `yaml:"ids,omitempty"`
Checksum bool `yaml:"checksum,omitempty"`
Signature bool `yaml:"signature,omitempty"`
Dir string `yaml:"dir,omitempty"`
Cmd string `yaml:"cmd,omitempty"`
Env []string `yaml:"env,omitempty"`
ExtraFiles []ExtraFile `yaml:"extra_files,omitempty"`
}
// Source configuration.
type Source struct {
NameTemplate string `yaml:"name_template,omitempty"`
Format string `yaml:"format,omitempty"`
Enabled bool `yaml:"enabled,omitempty"`
PrefixTemplate string `yaml:"prefix_template,omitempty"`
}
// Project includes all project configuration.
type Project struct {
ProjectName string `yaml:"project_name,omitempty"`
Env []string `yaml:"env,omitempty"`
Release Release `yaml:"release,omitempty"`
Milestones []Milestone `yaml:"milestones,omitempty"`
Brews []Homebrew `yaml:"brews,omitempty"`
Rigs []GoFish `yaml:"rigs,omitempty"`
AURs []AUR `yaml:"aurs,omitempty"`
Krews []Krew `yaml:"krews,omitempty"`
Scoop Scoop `yaml:"scoop,omitempty"`
Builds []Build `yaml:"builds,omitempty"`
Archives []Archive `yaml:"archives,omitempty"`
NFPMs []NFPM `yaml:"nfpms,omitempty"`
Snapcrafts []Snapcraft `yaml:"snapcrafts,omitempty"`
Snapshot Snapshot `yaml:"snapshot,omitempty"`
Checksum Checksum `yaml:"checksum,omitempty"`
Dockers []Docker `yaml:"dockers,omitempty"`
DockerManifests []DockerManifest `yaml:"docker_manifests,omitempty"`
Artifactories []Upload `yaml:"artifactories,omitempty"`
Uploads []Upload `yaml:"uploads,omitempty"`
Blobs []Blob `yaml:"blobs,omitempty"`
Publishers []Publisher `yaml:"publishers,omitempty"`
Changelog Changelog `yaml:"changelog,omitempty"`
Dist string `yaml:"dist,omitempty"`
Signs []Sign `yaml:"signs,omitempty"`
DockerSigns []Sign `yaml:"docker_signs,omitempty"`
EnvFiles EnvFiles `yaml:"env_files,omitempty"`
Before Before `yaml:"before,omitempty"`
Source Source `yaml:"source,omitempty"`
GoMod GoMod `yaml:"gomod,omitempty"`
Announce Announce `yaml:"announce,omitempty"`
SBOMs []SBOM `yaml:"sboms,omitempty"`
UniversalBinaries []UniversalBinary `yaml:"universal_binaries,omitempty"`
// this is a hack ¯\_(ツ)_/¯
SingleBuild Build `yaml:"build,omitempty"`
// should be set if using github enterprise
GitHubURLs GitHubURLs `yaml:"github_urls,omitempty"`
// should be set if using a private gitlab
GitLabURLs GitLabURLs `yaml:"gitlab_urls,omitempty"`
// should be set if using Gitea
GiteaURLs GiteaURLs `yaml:"gitea_urls,omitempty"`
}
type GoMod struct {
Proxy bool `yaml:"proxy,omitempty"`
Env []string `yaml:"env,omitempty"`
GoBinary string `yaml:"gobinary,omitempty"`
Mod string `yaml:"mod,omitempty"`
}
type Announce struct {
Skip string `yaml:"skip,omitempty"`
Twitter Twitter `yaml:"twitter,omitempty"`
Reddit Reddit `yaml:"reddit,omitempty"`
Slack Slack `yaml:"slack,omitempty"`
Discord Discord `yaml:"discord,omitempty"`
Teams Teams `yaml:"teams,omitempty"`
SMTP SMTP `yaml:"smtp,omitempty"`
Mattermost Mattermost `yaml:"mattermost,omitempty"`
LinkedIn LinkedIn `yaml:"linkedin,omitempty"`
Telegram Telegram `yaml:"telegram,omitempty"`
Webhook Webhook `yaml:"webhook,omitempty"`
}
type Webhook struct {
Enabled bool `yaml:"enabled,omitempty"`
SkipTLSVerify bool `yaml:"skip_tls_verify,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty"`
EndpointURL string `yaml:"endpoint_url,omitempty"`
Headers map[string]string `yaml:"headers,omitempty"`
ContentType string `yaml:"content_type,omitempty"`
}
type Twitter struct {
Enabled bool `yaml:"enabled,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty"`
}
type Reddit struct {
Enabled bool `yaml:"enabled,omitempty"`
ApplicationID string `yaml:"application_id,omitempty"`
Username string `yaml:"username,omitempty"`
TitleTemplate string `yaml:"title_template,omitempty"`
URLTemplate string `yaml:"url_template,omitempty"`
Sub string `yaml:"sub,omitempty"`
}
type Slack struct {
Enabled bool `yaml:"enabled,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty"`
Channel string `yaml:"channel,omitempty"`
Username string `yaml:"username,omitempty"`
IconEmoji string `yaml:"icon_emoji,omitempty"`
IconURL string `yaml:"icon_url,omitempty"`
}
type Discord struct {
Enabled bool `yaml:"enabled,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty"`
Author string `yaml:"author,omitempty"`
Color string `yaml:"color,omitempty"`
IconURL string `yaml:"icon_url,omitempty"`
}
type Teams struct {
Enabled bool `yaml:"enabled,omitempty"`
TitleTemplate string `yaml:"title_template,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty"`
Color string `yaml:"color,omitempty"`
IconURL string `yaml:"icon_url,omitempty"`
}
type Mattermost struct {
Enabled bool `yaml:"enabled,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty"`
TitleTemplate string `yaml:"title_template,omitempty"`
Color string `yaml:"color,omitempty"`
Channel string `yaml:"channel,omitempty"`
Username string `yaml:"username,omitempty"`
IconEmoji string `yaml:"icon_emoji,omitempty"`
IconURL string `yaml:"icon_url,omitempty"`
}
type SMTP struct {
Enabled bool `yaml:"enabled,omitempty"`
Host string `yaml:"host,omitempty"`
Port int `yaml:"port,omitempty"`
Username string `yaml:"username,omitempty"`
From string `yaml:"from,omitempty"`
To []string `yaml:"to,omitempty"`
SubjectTemplate string `yaml:"subject_template,omitempty"`
BodyTemplate string `yaml:"body_template,omitempty"`
InsecureSkipVerify bool `yaml:"insecure_skip_verify,omitempty"`
}
type LinkedIn struct {
Enabled bool `yaml:"enabled,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty"`
}
type Telegram struct {
Enabled bool `yaml:"enabled,omitempty"`
MessageTemplate string `yaml:"message_template,omitempty"`
ChatID int64 `yaml:"chat_id,omitempty"`
}
// Load config file.
func Load(file string) (config Project, err error) {
f, err := os.Open(file) // #nosec
if err != nil {
return
}
defer f.Close()
log.WithField("file", file).Info("loading config file")
return LoadReader(f)
}
// LoadReader config via io.Reader.
func LoadReader(fd io.Reader) (config Project, err error) {
data, err := io.ReadAll(fd)
if err != nil {
return config, err
}
err = yaml.UnmarshalStrict(data, &config)
log.WithField("config", config).Debug("loaded config file")
return config, err
}