Our Product Hydra uses Gox and GitHub Releases to ship binaries for all platforms with every new git tag. To do so, we had to experiment with various settings. Our goal:

  • Automatically build binaries for all platforms on Travis
  • Only build binaries when Go 1.7 is used
  • Skip the build if the commit is not a new git tag
  • Push the binaries to the GitHub Releases tab
  • Tell Go what the build tag is, so it can be retrieved when using hydra version

To achieve that, our .travis.yml file now looks like this:

language: go

go:
  - 1.7

install:
  - github.com/mitchellh/gox

script:
  # Testing scripts etc

after_success:
  - |-
    [ "${TRAVIS_TAG}" != "" ] && [ "${TRAVIS_GO_VERSION}" == "1.7" ] && gox -ldflags "-X github.com/ory-am/hydra/cmd.Version=`git describe --tags` -X github.com/ory-am/hydra/cmd.BuildTime=`TZ=UTC date -u '+%Y-%m-%dT%H:%M:%SZ'` -X github.com/ory-am/hydra/cmd.GitHash=`git rev-parse HEAD`" -output "dist/{{.Dir}}-{{.OS}}-{{.Arch}}"

deploy:
  provider: releases
  file_glob: true
  api_key: "$GITHUB_TOKEN"
  file: "dist/*"
  skip_cleanup: true
  on:
    tags: true
    go: 1.7

There are a couple of things happening here:

  • We use the ldflags flag to set variables such as github.com/ory-am/hydra/cmd.Version and similar:
    -ldflags "-X github.com/ory-am/hydra/cmd.Version=`git describe --tags` -X github.com/ory-am/hydra/cmd.BuildTime=`TZ=UTC date -u '+%Y-%m-%dT%H:%M:%SZ'` -X github.com/ory-am/hydra/cmd.GitHash=`git rev-parse HEAD`"
  • Because cross platform compiles take a long time, we skip those when the Go version is not 1.7 or no git tag was set:
    [ "${TRAVIS_TAG}" != "" ] && [ "${TRAVIS_GO_VERSION}" == "1.7" ]
  • Create a personal access token on GitHub and use the Travis-ci user interface to set the environment variable $GITHUB_TOKEN to its value. Make sure you don't copy any accidental whitespaces, as this can cause Travis-ci to display your token and thus give everyone access to your GitHub data.
  • Getting the deployment right was a headache because we create multiple binaries. The file_glob option allows us to use wildcards such as file: "dist/*":
    provider: releases
    file_glob: true
    api_key: "$GITHUB_TOKEN"
    file: "dist/*"
    skip_cleanup: true
  • Because we want to skip this feature when neither Go 1.7 is used nor git tags are set, we additionally used these options:
    tags: true
    go: 1.7

That's it. If you have any questions, feel free to comment below.