Deliver Go binaries as fast and easily as possible.
--- GoReleaser builds Go binaries for several platforms, creates a GitHub release and then pushes a Homebrew formula to a repository. All that wrapped in your favorite CI. This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. We appreciate your contribution. Please refer to our [contributing guidelines](CONTRIBUTING.md) for further information. For questions join the [#goreleaser](https://gophers.slack.com/messages/goreleaser/) channel in the [Gophers Slack](https://invite.slack.golangbridge.org/). # Table of contents - [Introduction](#introduction) - [Quick start](#quick-start) - [Environment setup](#environment-setup) - [Release customization](#release-customization) - [Integration with CI](#integration-with-ci) ## Introduction GoReleaser is a release automation tool for Golang projects, the goal is to simplify the build, release and publish steps while providing variant customization options for all steps. GoReleaser is built for CI tools; you only need to [download and execute it](#integration-with-ci) in your build script. You can [customize](#release-customization) your release process by createing a `.goreleaser.yml` file. We are also working on integrating with package managers, we currently support Homebrew. The idea started with a [simple shell script](https://github.com/goreleaser/old-go-releaser), but it quickly became more complex and I also wanted to publish binaries via Homebrew. ## Quick start In this example we will build, archive and release a Golang project. Create a GitHub repository and add a single main package: ```go // main.go package main func main() { println("Ba dum, tss!") } ``` By default GoReleaser will build the current directory, but you can change the build package path in the GoReleaser configuration file. ```yml # .goreleaser.yml # Build customization builds: - binary: drum-roll goos: - windows - darwin - linux goarch: - amd64 ``` PS: Invalid GOOS/GOARCH combinations will automatically be skipped. This configuration specifies the build operating systems to Windows, Linux and MacOS using 64bit architecture, the name of the binaries is `drum-roll`. GoReleaser will then archive the result binaries of each Os/Arch into a separate file. The default format is `{{.ProjectName}}_{{.Os}}_{{.Arch}}`. You can change the archives name and format. You can also replace the OS and the Architecture with your own. Another useful feature is to add files to archives, this is very useful for integrating assets like resource files. ```yml # .goreleaser.yml # Build customization builds: - main: main.go binary: drum-roll goos: - windows - darwin - linux goarch: - amd64 # Archive customization archive: format: tar.gz replacements: amd64: 64-bit darwin: macOS linux: Tux files: - drum-roll.licence.txt ``` This configuration will generate tar archives, contains an additional file `drum-roll.licence.txt`, the archives will be located in: - `./dist/drum-roll_windows_64-bit.tar.gz` - `./dist/drum-roll_macOS_64-bit.tar.gz` - `./dist/drum-roll_Tux_64-bit.tar.gz` Next export a `GITHUB_TOKEN` environment variable with the `repo` scope selected. This will be used to deploy releases to your GitHub repository. Create yours [here](https://github.com/settings/tokens/new). ```console $ export GITHUB_TOKEN=`YOUR_TOKEN` ``` GoReleaser uses the latest [Git tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging) of your repository. Create a tag and push it to GitHub: ```console $ git tag -a v0.1.0 -m "First release" && git push origin v0.1.0 ``` **Note**: we recommend the use of [semantic versioning](http://semver.org/). We are not enforcing it though. We do remove the `v` prefix and then enforce that the next character is a number. So, `v0.1.0` and `0.1.0` are virtually the same and are both accepted, while `version0.1.0` is not. If you don't want to create a tag yet but instead simply create a package based on the latest commit, then you can also use the `--snapshot` flag. Now you can run GoReleaser at the root of your repository: ```console $ goreleaser ``` That's it! Check your GitHub project's release page. The release should look like this: [![image](https://cloud.githubusercontent.com/assets/245435/23342061/fbcbd506-fc31-11e6-9d2b-4c1b776dee9c.png) ](https://github.com/goreleaser/goreleaser/releases) ## Environment setup ### GitHub Token GoReleaser requires a GitHub API token with the `repo` scope checked to deploy the artefacts to GitHub. You can create one [here](https://github.com/settings/tokens/new). This token should be added to the environment variables as `GITHUB_TOKEN`. Here is how to do it with Travis CI: [Defining Variables in Repository Settings](https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings). ### A note about `main.version` GoReleaser always sets a `main.version` ldflag. You can use it in your `main.go` file: ```go package main var version = "master" func main() { println(version) } ``` `version` will be the current Git tag (with `v` prefix stripped) or the name of the snapshot if you're using the `--snapshot` flag. ## GoReleaser customization GoReleaser provides multiple customizations via the `.goreleaser.yml` file. You can generate it by running `goreleaser init` or start from scratch. The defaults are sensible and fit for most projects. We'll cover all customizations available bellow: ### Project name ```yml # .goreleaser.yml # The name of the project. It is used in the name of the brew formula, archives, # etc. Defaults to the name of the git project. project_name: myproject ``` ### Build customization ```yml # .goreleaser.yml builds: # You can have multiple builds, its a common yaml list - # Path to main.go file or main package. # Default is `.` main: ./cmd/main.go # Name of the binary. # Default is the name of the project directory. binary: program # Custom build tags. # Default is empty flags: -tags dev # Custom ldflags template. # This is parsed with Golang template engine and the following variables # are available: # - Date # - Commit # - Tag # - Version (Tag with the `v` prefix stripped) # The default is `-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}` # Date format is `2006-01-02_15:04:05` ldflags: -s -w -X main.build={{.Version}} # Custom environment variables to be set durign the builds. # Default is empty env: - CGO_ENABLED=0 # GOOS list to build in. # For more info refer to https://golang.org/doc/install/source#environment # Defaults are darwin and linux goos: - freebsd - windows # GOARCH to build in. # For more info refer to https://golang.org/doc/install/source#environment # Defaults are 386 and amd64 goarch: - amd64 - arm - arm64 # GOARM to build in when GOARCH is arm. # For more info refer to https://golang.org/doc/install/source#environment # Defaults are 6 goarm: - 6 - 7 # List of combinations of GOOS + GOARCH + GOARM to ignore. # Default is empty. ignore: - goos: darwin goarch: 386 - goos: linux goarch: arm goarm: 7 # Hooks can be used to customize the final binary, for example, to run # generator or whatever you want. # Default is both hooks empty. hooks: pre: rice embed-go post: ./script.sh ``` ### Archive customization ```yml # .goreleaser.yml archive: # You can change the name of the archive. # This is parsed with Golang template engine and the following variables # are available: # - ProjectName # - Tag # - Version (Tag with the `v` prefix stripped) # - Os # - Arch # - Arm (ARM version) # The default is `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}` name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" # Archive format. Valid options are `tar.gz`, `zip` and `binary`. # If format is `binary` no archives are created and the binaries are instead uploaded directly. # In that case name_template the below specified files are ignored. # Default is `tar.gz` format: zip # Can be used to archive on different formats for specific GOOSs. # Most common use case is to archive as zip on Windows. # Default is empty format_overrides: - goos: windows format: zip # Replacements for GOOS and GOARCH on the archive name. # The keys should be valid GOOS or GOARCH values followed by your custom # replacements. replacements: amd64: 64-bit 386: 32-bit darwin: macOS linux: Tux # Additional files/globs you want to add to the archive. # Defaults are any files matching `LICENCE*`, `LICENSE*`, # `README*` and `CHANGELOG*` (case-insensitive) files: - LICENSE.txt - README.md - CHANGELOG.md - docs/* - design/*.png ``` ### Release customization ```yml # .goreleaser.yml release: # Repo in which the release will be created. # Default is extracted from the origin remote URL. github: owner: user name: repo # If set to true, will not auto-publish the release. # Default is false draft: true ``` You can also specify a release notes file in markdown format using the `--release-notes` flag. ### Snapshot customization ```yml # .goreleaser.yml snapshot: # Allows you to change the name of the generated snapshot # releases. The following variables are available: # - Commit # - Tag # - Timestamp # Default: SNAPSHOT-{{.Commit}} name_template: SNAPSHOT-{{.Commit}} ``` ### Homebrew tap customization The brew section specifies how the formula should be created. Check [the Homebrew documentation](https://github.com/Homebrew/brew/blob/master/docs/How-to-Create-and-Maintain-a-Tap.md) and the [formula cookbook](https://github.com/Homebrew/brew/blob/master/docs/Formula-Cookbook.md) for details. ```yml # .goreleaser.yml brew: # Reporitory to push the tap to. github: owner: user name: homebrew-tap # Folder inside the repository to put the formula. # Default is the root folder. folder: Formula # Caveats for the user of your binary. # Default is empty. caveats: "How to use this binary" # Your app's homepage # Default is empty homepage: "https://example.com/" # Your app's description # Default is empty description: "Software to create fast and easy drum rolls." # Dependencies of your package dependencies: - git - zsh # Packages that conflict with your package conflicts: - svn - bash # So you can brew test your formula. Default is empty. plist: | ... # Packages that run as a service. Default is empty. test: | system "#{bin}/program --version" ... # Custom install script for brew. Default is 'bin.install "program"' install: | bin.install "program" ... ``` By defining the `brew` section, GoReleaser will take care of publishing the Homebrew tap. Assuming that the current tag is `v1.2.3`, the above config will generate a `program.rb` formula in the `Formula` folder of `user/homebrew-tap` repository: ```rb class Program < Formula desc "How to use this binary" homepage "https://github.com/user/repo" url "https://github.com/user/repo/releases/download/v1.2.3/program_v1.2.3_macOs_64bit.zip" version "v1.2.3" sha256 "9ee30fc358fae8d248a2d7538957089885da321dca3f09e3296fe2058e7fff74" depends_on "git" depends_on "zsh" def install bin.install "program" end end ``` ### FPM build customization GoReleaser can be wired to [fpm]() to generate `.deb`, `.rpm` and other archives. Check its [wiki](https://github.com/jordansissel/fpm/wiki) for more info. [fpm]: https://github.com/jordansissel/fpm ```yml # .goreleaser.yml fpm: # Your app's vendor # Default is empty vendor: Drum Roll Inc. # Your app's homepage # Default is empty homepage: https://example.com/ # Your app's maintainer (probably you) # Default is empty maintainer: Drummer