diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 1b6e05a78..ffc52b6e0 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -4,3 +4,6 @@ Please don't file issues directly, use one of our available templates: * [Feature Requests](https://github.com/goreleaser/goreleaser/issues/new?template=feature.md) Thank you. + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6307de983..088198466 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,3 +81,36 @@ See #284 Push your branch to your `goreleaser` fork and open a pull request against the master branch. + +## Financial contributions + +We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/goreleaser). +Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed. + +## Credits + +### Contributors + +Thank you to all the people who have already contributed to goreleaser! + + +### Backers + +Thank you to all our backers! [[Become a backer](https://opencollective.com/goreleaser#backer)] + + + +### Sponsors + +Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/goreleaser#sponsor)) + + + + + + + + + + + diff --git a/Gopkg.lock b/Gopkg.lock index 1a10f6f79..0443ac8d9 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -20,7 +20,7 @@ branch = "master" name = "github.com/campoy/unique" packages = ["."] - revision = "8da0a74979c676510b9de445041ce14b6e450e24" + revision = "88950e537e7e644cd746a3102037b5d2b723e9f5" [[projects]] name = "github.com/davecgh/go-spew" @@ -38,13 +38,13 @@ branch = "master" name = "github.com/golang/protobuf" packages = ["proto"] - revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845" + revision = "925541529c1fa6821df4e44ce2723319eb2be768" [[projects]] branch = "master" name = "github.com/google/go-github" packages = ["github"] - revision = "922ceac0585d40f97d283d921f872fc50480e06e" + revision = "e48060a28fac52d0f1cb758bc8b87c07bac4a87d" [[projects]] branch = "master" @@ -120,7 +120,7 @@ "context", "context/ctxhttp" ] - revision = "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec" + revision = "0ed95abb35c445290478a5348a7b38bb154135fd" [[projects]] branch = "master" @@ -141,7 +141,7 @@ branch = "master" name = "golang.org/x/sys" packages = ["unix"] - revision = "2c42eef0765b9837fbdab12011af7830f55f88f0" + revision = "03467258950d845cd1877eab69461b98e8c09219" [[projects]] name = "google.golang.org/appengine" diff --git a/README.md b/README.md index d6243d645..a25f15768 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Go Doc SayThanks.io Powered By: GoReleaser + Backers on Open Collective + Sponsors on Open Collective

@@ -81,3 +83,8 @@ Love our work and community? [Become a backer](https://opencollective.com/gorele --- Would you like to fix something in the documentation? Feel free to open an [issue](https://github.com/goreleaser/goreleaser/issues). + +## Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. + diff --git a/config/config.go b/config/config.go index 355ad2723..697d96a27 100644 --- a/config/config.go +++ b/config/config.go @@ -3,11 +3,9 @@ package config import ( - "fmt" "io" "io/ioutil" "os" - "strings" "github.com/apex/log" yaml "gopkg.in/yaml.v2" @@ -24,9 +22,6 @@ type GitHubURLs struct { type Repo struct { Owner string `yaml:",omitempty"` Name string `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // String of the repo, e.g. owner/name @@ -52,9 +47,6 @@ type Homebrew struct { Homepage string `yaml:",omitempty"` SkipUpload bool `yaml:"skip_upload,omitempty"` DownloadStrategy string `yaml:"download_strategy,omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // CommitAuthor is the author of a Git commit @@ -67,17 +59,11 @@ type CommitAuthor struct { type Hooks struct { Pre string `yaml:",omitempty"` Post string `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // IgnoredBuild represents a build ignored by the user type IgnoredBuild struct { Goos, Goarch, Goarm string - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Build contains the build configuration section @@ -94,18 +80,12 @@ type Build struct { Hooks Hooks `yaml:",omitempty"` Env []string `yaml:",omitempty"` Lang string `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // FormatOverride is used to specify a custom format for a specific GOOS. type FormatOverride struct { Goos string `yaml:",omitempty"` Format string `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Archive config used for the archive @@ -117,9 +97,6 @@ type Archive struct { FormatOverrides []FormatOverride `yaml:"format_overrides,omitempty"` WrapInDirectory bool `yaml:"wrap_in_directory,omitempty"` Files []string `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Release config used for the GitHub release @@ -128,8 +105,6 @@ type Release struct { Draft bool `yaml:",omitempty"` Prerelease bool `yaml:",omitempty"` NameTemplate string `yaml:"name_template,omitempty"` - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // FPM config @@ -147,9 +122,6 @@ type FPM struct { License string `yaml:",omitempty"` Bindir string `yaml:",omitempty"` Files map[string]string `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Sign config @@ -177,25 +149,16 @@ type Snapcraft struct { Grade string `yaml:",omitempty"` Confinement string `yaml:",omitempty"` Apps map[string]SnapcraftAppMetadata `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Snapshot config type Snapshot struct { NameTemplate string `yaml:"name_template,omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Checksum config type Checksum struct { NameTemplate string `yaml:"name_template,omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Docker image config @@ -210,9 +173,6 @@ type Docker struct { OldTagTemplate string `yaml:"tag_template,omitempty"` TagTemplates []string `yaml:"tag_templates,omitempty"` Files []string `yaml:"extra_files,omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Artifactory server configuration @@ -221,26 +181,17 @@ type Artifactory struct { Name string `yaml:",omitempty"` Username string `yaml:",omitempty"` Mode string `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Filters config type Filters struct { Exclude []string `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Changelog Config type Changelog struct { Filters Filters `yaml:",omitempty"` Sort string `yaml:",omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Project includes all project configuration @@ -265,9 +216,6 @@ type Project struct { // should be set if using github enterprise GitHubURLs GitHubURLs `yaml:"github_urls,omitempty"` - - // Capture all undefined fields and should be empty after loading - XXX map[string]interface{} `yaml:",inline"` } // Load config file @@ -286,72 +234,7 @@ func LoadReader(fd io.Reader) (config Project, err error) { if err != nil { return config, err } - if err := yaml.Unmarshal(data, &config); err != nil { - return config, err - } + err = yaml.UnmarshalStrict(data, &config) log.WithField("config", config).Debug("loaded config file") - return config, checkOverflows(config) -} - -// TODO: check if we can use UnmarshalStrict instead of the manual checkOverflow -func checkOverflows(config Project) error { - var overflow = &overflowChecker{} - overflow.check(config.XXX, "") - overflow.check(config.Archive.XXX, "archive") - for i, ov := range config.Archive.FormatOverrides { - overflow.check(ov.XXX, fmt.Sprintf("archive.format_overrides[%d]", i)) - } - overflow.check(config.Brew.XXX, "brew") - overflow.check(config.Brew.GitHub.XXX, "brew.github") - for i, build := range config.Builds { - overflow.check(build.XXX, fmt.Sprintf("builds[%d]", i)) - overflow.check(build.Hooks.XXX, fmt.Sprintf("builds[%d].hooks", i)) - for j, ignored := range build.Ignore { - overflow.check(ignored.XXX, fmt.Sprintf("builds[%d].ignored_builds[%d]", i, j)) - } - } - overflow.check(config.FPM.XXX, "fpm") - overflow.check(config.Snapcraft.XXX, "snapcraft") - overflow.check(config.Release.XXX, "release") - overflow.check(config.Release.GitHub.XXX, "release.github") - overflow.check(config.SingleBuild.XXX, "build") - overflow.check(config.SingleBuild.Hooks.XXX, "builds.hooks") - for i, ignored := range config.SingleBuild.Ignore { - overflow.check(ignored.XXX, fmt.Sprintf("builds.ignored_builds[%d]", i)) - } - overflow.check(config.Snapshot.XXX, "snapshot") - overflow.check(config.Checksum.XXX, "checksum") - for i, docker := range config.Dockers { - overflow.check(docker.XXX, fmt.Sprintf("docker[%d]", i)) - } - for i, artifactory := range config.Artifactories { - overflow.check(artifactory.XXX, fmt.Sprintf("artifactory[%d]", i)) - } - overflow.check(config.Changelog.XXX, "changelog") - overflow.check(config.Changelog.Filters.XXX, "changelog.filters") - return overflow.err() -} - -type overflowChecker struct { - fields []string -} - -func (o *overflowChecker) check(m map[string]interface{}, ctx string) { - for k := range m { - var key = fmt.Sprintf("%s.%s", ctx, k) - if ctx == "" { - key = k - } - o.fields = append(o.fields, key) - } -} - -func (o *overflowChecker) err() error { - if len(o.fields) == 0 { - return nil - } - return fmt.Errorf( - "unknown fields in the config file: %s", - strings.Join(o.fields, ", "), - ) + return config, err } diff --git a/config/config_test.go b/config/config_test.go index 427a7225e..6c2041a59 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -59,10 +59,15 @@ func TestFileNotFound(t *testing.T) { func TestInvalidFields(t *testing.T) { _, err := Load("testdata/invalid_config.yml") - assert.EqualError(t, err, "unknown fields in the config file: invalid_root, archive.invalid_archive, archive.format_overrides[0].invalid_archive_fmtoverrides, brew.invalid_brew, brew.github.invalid_brew_github, builds[0].invalid_builds, builds[0].hooks.invalid_builds_hooks, builds[0].ignored_builds[0].invalid_builds_ignore, fpm.invalid_fpm, release.invalid_release, release.github.invalid_release_github, build.invalid_build, builds.hooks.invalid_build_hook, builds.ignored_builds[0].invalid_build_ignore, snapshot.invalid_snapshot, docker[0].invalid_docker, artifactory[0].invalid_artifactory, changelog.invalid_changelog, changelog.filters.invalid_filters") + assert.EqualError(t, err, "yaml: unmarshal errors:\n line 2: field invalid_yaml not found in struct config.Build") } func TestInvalidYaml(t *testing.T) { _, err := Load("testdata/invalid.yml") assert.EqualError(t, err, "yaml: line 1: did not find expected node content") } + +func TestConfigWithAnchors(t *testing.T) { + _, err := Load("testdata/anchor.yaml") + assert.NoError(t, err) +} diff --git a/config/testdata/anchor.yaml b/config/testdata/anchor.yaml new file mode 100644 index 000000000..440a7346a --- /dev/null +++ b/config/testdata/anchor.yaml @@ -0,0 +1,3 @@ +project_name: &anchor_name This string will appear as the value of two keys. +build: + binary: *anchor_name diff --git a/config/testdata/invalid_config.yml b/config/testdata/invalid_config.yml index 6c2956f10..126c5f137 100644 --- a/config/testdata/invalid_config.yml +++ b/config/testdata/invalid_config.yml @@ -1,37 +1,3 @@ -invalid_root: 1 build: - invalid_build: 1 - hooks: - invalid_build_hook: 1 - ignore: - - invalid_build_ignore: 1 -builds: -- invalid_builds: 1 - hooks: - invalid_builds_hooks: 1 - ignore: - - invalid_builds_ignore: 1 -archive: - invalid_archive: 1 - format_overrides: - - invalid_archive_fmtoverrides: 1 -release: - invalid_release: 1 - github: - invalid_release_github: 1 -brew: - invalid_brew: 1 - github: - invalid_brew_github: 1 -fpm: - invalid_fpm: 1 -snapshot: - invalid_snapshot: 1 -dockers: - - invalid_docker: 1 -artifactories: - - invalid_artifactory: 1 -changelog: - invalid_changelog: 1 - filters: - invalid_filters: 1 + invalid_yaml: 1 + diff --git a/internal/client/client.go b/internal/client/client.go index 421d37546..a726cd424 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -17,7 +17,7 @@ type Info struct { // Client interface type Client interface { - CreateRelease(ctx *context.Context, body string) (releaseID int, err error) + CreateRelease(ctx *context.Context, body string) (releaseID int64, err error) CreateFile(ctx *context.Context, content bytes.Buffer, path string) (err error) - Upload(ctx *context.Context, releaseID int, name string, file *os.File) (err error) + Upload(ctx *context.Context, releaseID int64, name string, file *os.File) (err error) } diff --git a/internal/client/github.go b/internal/client/github.go index 95a6a42a7..d9e98a331 100644 --- a/internal/client/github.go +++ b/internal/client/github.go @@ -81,7 +81,7 @@ func (c *githubClient) CreateFile( return } -func (c *githubClient) CreateRelease(ctx *context.Context, body string) (releaseID int, err error) { +func (c *githubClient) CreateRelease(ctx *context.Context, body string) (releaseID int64, err error) { var release *github.RepositoryRelease title, err := releaseTitle(ctx) if err != nil { @@ -122,7 +122,7 @@ func (c *githubClient) CreateRelease(ctx *context.Context, body string) (release func (c *githubClient) Upload( ctx *context.Context, - releaseID int, + releaseID int64, name string, file *os.File, ) (err error) { diff --git a/pipeline/brew/brew_test.go b/pipeline/brew/brew_test.go index 0bde35ce4..25876ed99 100644 --- a/pipeline/brew/brew_test.go +++ b/pipeline/brew/brew_test.go @@ -387,7 +387,7 @@ type DummyClient struct { Content string } -func (client *DummyClient) CreateRelease(ctx *context.Context, body string) (releaseID int, err error) { +func (client *DummyClient) CreateRelease(ctx *context.Context, body string) (releaseID int64, err error) { return } @@ -398,6 +398,6 @@ func (client *DummyClient) CreateFile(ctx *context.Context, content bytes.Buffer return } -func (client *DummyClient) Upload(ctx *context.Context, releaseID int, name string, file *os.File) (err error) { +func (client *DummyClient) Upload(ctx *context.Context, releaseID int64, name string, file *os.File) (err error) { return } diff --git a/pipeline/release/release.go b/pipeline/release/release.go index 3c0c73b31..f7e9176c4 100644 --- a/pipeline/release/release.go +++ b/pipeline/release/release.go @@ -82,7 +82,7 @@ func doRun(ctx *context.Context, c client.Client) error { return g.Wait() } -func upload(ctx *context.Context, c client.Client, releaseID int, artifact artifact.Artifact) error { +func upload(ctx *context.Context, c client.Client, releaseID int64, artifact artifact.Artifact) error { file, err := os.Open(artifact.Path) if err != nil { return err diff --git a/pipeline/release/release_test.go b/pipeline/release/release_test.go index 5d99a4bbd..7e08a83cb 100644 --- a/pipeline/release/release_test.go +++ b/pipeline/release/release_test.go @@ -203,7 +203,7 @@ type DummyClient struct { UploadedFileNames []string } -func (client *DummyClient) CreateRelease(ctx *context.Context, body string) (releaseID int, err error) { +func (client *DummyClient) CreateRelease(ctx *context.Context, body string) (releaseID int64, err error) { if client.FailToCreateRelease { return 0, errors.New("release failed") } @@ -215,7 +215,7 @@ func (client *DummyClient) CreateFile(ctx *context.Context, content bytes.Buffer return } -func (client *DummyClient) Upload(ctx *context.Context, releaseID int, name string, file *os.File) (err error) { +func (client *DummyClient) Upload(ctx *context.Context, releaseID int64, name string, file *os.File) (err error) { if client.FailToUpload { return errors.New("upload failed") }