2017-09-10 22:07:28 +02:00
---
2017-12-20 12:32:21 +02:00
title: Continuous Integration
2018-04-25 07:20:12 +02:00
menu: true
weight: 140
2017-09-10 22:07:28 +02:00
---
2018-02-17 22:15:40 +02:00
GoReleaser was built from the very first commit with the idea of
running it as part of the CI pipeline in mind.
2018-09-17 16:28:10 +02:00
Let's see how we can get it working on popular CI software.
2018-02-17 22:15:40 +02:00
2018-09-17 16:28:10 +02:00
## Travis CI
2018-02-17 22:15:40 +02:00
2017-10-01 18:57:52 +02:00
You may want to setup your project to auto-deploy your new tags on
2017-09-11 15:13:14 +02:00
[Travis ](https://travis-ci.org ), for example:
2017-09-10 22:07:28 +02:00
```yaml
# .travis.yml
2018-02-17 22:15:40 +02:00
language: go
addons:
apt:
packages:
2018-02-19 01:37:59 +02:00
# needed for the nfpm pipe:
2018-02-17 22:15:40 +02:00
- rpm
2018-02-19 01:37:59 +02:00
# needed for the snap pipe:
2018-12-02 20:57:38 +02:00
- snapd
2018-02-19 01:37:59 +02:00
env:
# needed for the snap pipe:
- PATH=/snap/bin:$PATH
install:
# needed for the snap pipe:
- sudo snap install snapcraft --classic
2018-02-17 22:15:40 +02:00
# needed for the docker pipe
services:
- docker
2018-06-06 15:44:52 +02:00
after_success:
# docker login is required if you want to push docker images.
# DOCKER_PASSWORD should be a secret in your .travis.yml configuration.
- test -n "$TRAVIS_TAG" && docker login -u=myuser -p="$DOCKER_PASSWORD"
2018-10-20 21:36:12 +02:00
# snapcraft login is required if you want to push snapcraft packages to the
# store.
# You'll need to run `snapcraft export-login snap.login` and
# `travis encrypt-file snap.login --add` to add the key to the travis
# environment.
- test -n "$TRAVIS_TAG" && snapcraft login --with snap.login
2018-06-06 15:44:52 +02:00
2018-02-17 22:15:40 +02:00
# calls goreleaser
deploy:
- provider: script
skip_cleanup: true
2018-04-07 17:59:39 +02:00
script: curl -sL https://git.io/goreleaser | bash
2018-02-17 22:15:40 +02:00
on:
tags: true
condition: $TRAVIS_OS_NAME = linux
2017-09-10 22:07:28 +02:00
```
2018-02-17 22:15:40 +02:00
Note the last line (`condition: $TRAVIS_OS_NAME = linux`): it is important
if you run a build matrix with multiple Go versions and/or multiple OSes. If
that's the case you will want to make sure GoReleaser is run just once.
2018-08-01 14:44:05 +02:00
## CircleCI
2018-02-17 22:15:40 +02:00
2018-08-01 14:44:05 +02:00
Here is how to do it with [CircleCI 2.0 ](https://circleci.com ):
```yml
# .circleci/config.yml
2018-08-09 14:08:28 +02:00
version: 2
2018-08-01 14:44:05 +02:00
jobs:
release:
docker:
- image: circleci/golang:1.10
steps:
- checkout
- run: curl -sL https://git.io/goreleaser | bash
workflows:
version: 2
release:
jobs:
- release:
2018-08-09 14:08:28 +02:00
filters:
branches:
ignore: /.*/
tags:
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
2018-08-01 14:44:05 +02:00
```
2018-07-11 18:49:24 +02:00
## Drone
2018-07-11 19:03:20 +02:00
By default, drone does not fetch tags. `plugins/git` is used with default values,
in most cases we'll need overwrite the `clone` step enabling tags in order to make
2018-07-11 18:49:24 +02:00
`goreleaser` work correctly.
2018-07-11 11:43:09 +02:00
In this example we're creating a new release every time a new tag is pushed.
2018-07-11 19:03:20 +02:00
Note that you'll need to enable `tags` in repo settings and add `github_token`
2018-07-11 18:49:24 +02:00
secret.
2018-07-11 11:43:09 +02:00
2019-07-05 16:21:46 +02:00
#### 1.x
2019-07-06 22:09:22 +02:00
```yml
# .drone.yml
2019-07-05 16:21:46 +02:00
kind: pipeline
name: default
steps:
- name: fetch
image: docker:git
commands:
- git fetch --tags
- name: test
image: golang
volumes:
- name: deps
path: /go
commands:
- go test -race -v ./... -cover
- name: release
image: golang
environment:
GITHUB_TOKEN:
from_secret: github_token
volumes:
- name: deps
path: /go
commands:
- curl -sL https://git.io/goreleaser | bash
when:
event: tag
volumes:
- name: deps
temp: {}
```
2019-09-13 14:53:56 +02:00
#### 0.8
2018-07-11 11:43:09 +02:00
```yml
pipeline:
clone:
image: plugins/git
tags: true
test:
image: golang:1.10
commands:
- go test ./... -race
release:
image: golang:1.10
secrets: [github_token]
commands:
curl -sL https://git.io/goreleaser | bash
when:
event: tag
```
2018-10-02 16:14:40 +02:00
## Google CloudBuild
CloudBuild works off a different clone than your github repo: it seems that
2018-10-20 21:36:12 +02:00
your changes are pulled to a repo like
2018-10-02 16:14:40 +02:00
source.developers.google.com/p/YourProjectId/r/github-YourGithubUser-YourGithubRepo, and that's what
2018-10-20 21:36:12 +02:00
you're building off.
2018-10-02 16:14:40 +02:00
This repo has the wrong name, so to prevent Goreleaser from publishing to
2019-08-09 16:27:55 +02:00
the wrong github repo, add to your `.goreleaser.yml` file's release section:
2018-10-02 16:14:40 +02:00
```yml
release:
github:
owner: YourGithubUser
name: YourGithubRepo
```
Create two build triggers:
2019-05-26 16:27:28 +02:00
2018-10-02 16:14:40 +02:00
- a "push to any branch" trigger for your regular CI (doesn't invoke goreleaser)
- a "push to tag" trigger which invokes goreleaser
The push to any branch trigger could use a Dockerfile or a cloudbuild.yaml,
whichever you prefer.
You should have a dedicated cloudbuild.release.yaml that is only used by the "push to
tag" trigger.
In this example we're creating a new release every time a new tag is pushed.
See [Using Encrypted Resources ](https://cloud.google.com/cloud-build/docs/securing-builds/use-encrypted-secrets-credentials ) for how to encrypt and base64-encode your github token.
The clone that the build uses [has no
tags](https://issuetracker.google.com/u/1/issues/113668706), which is why we
must explicitly run git tag $TAG_NAME (note that $TAG_NAME is only set when
your build is triggered by a "push to tag".) This will allow goreleaser to
create a release with that version, but it won't be able to build a proper
changelog containing just the messages from the commits since the prior tag.
2019-08-09 16:27:55 +02:00
Note that the build performs a shallow clone of git repositories and will
only contain tags that reference the latest commit.
2018-10-02 16:14:40 +02:00
```yml
steps:
2019-03-25 01:10:30 +02:00
# Setup the workspace so we have a viable place to point GOPATH at.
- name: gcr.io/cloud-builders/go
env: ['PROJECT_ROOT=github.com/YourGithubUser/YourGithubRepo']
args: ['env']
# Create github release.
- name: goreleaser/goreleaser
entrypoint: /bin/sh
dir: gopath/src/github.com
env: ['GOPATH=/workspace/gopath']
args: ['-c', 'cd YourGithubUser/YourGithubRepo & & git tag $TAG_NAME & & /goreleaser' ]
secretEnv: ['GITHUB_TOKEN']
2018-10-20 21:36:12 +02:00
2018-10-02 16:14:40 +02:00
secrets:
2019-03-25 01:10:30 +02:00
- kmsKeyName: projects/YourProjectId/locations/global/keyRings/YourKeyRing/cryptoKeys/YourKey
secretEnv:
GITHUB_TOKEN: |
ICAgICAgICBDaVFBZUhVdUVoRUtBdmZJSGxVWnJDZ0hOU2NtMG1ES0k4WjF3L04zT3pEazhRbDZr
QVVTVVFEM3dVYXU3cVJjK0g3T25UVW82YjJaCiAgICAgICAgREtBMWVNS0hOZzcyOUtmSGoyWk1x
ICAgICAgIEgwYndIaGUxR1E9PQo=
2018-10-02 16:14:40 +02:00
```
2018-10-31 18:06:30 +02:00
## Semaphore
In [Sempahore 2.0 ](https://semaphoreci.com ) each project starts with the
default pipeline specified in .semaphore/semaphore.yml.
```yml
# .semaphore/semaphore.yml.
version: v1.0
name: Build
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804
blocks:
- name: "Test"
task:
prologue:
commands:
# set go version
- sem-version go 1.11
- "export GOPATH=~/go"
- "export PATH=/home/semaphore/go/bin:$PATH"
- checkout
jobs:
- name: "Lint"
commands:
- go get ./...
- go test ./...
# On Semaphore 2.0 deployment and delivery is managed with promotions,
# which may be automatic or manual and optionally depend on conditions.
promotions:
- name: Release
pipeline_file: goreleaser.yml
auto_promote_on:
- result: passed
branch:
- "^refs/tags/v*"
```
Pipeline file in .semaphore/goreleaser.yml:
```yml
version: "v1.0"
name: GoReleaser
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804
blocks:
- name: "Release"
task:
secrets:
- name: goreleaser
prologue:
commands:
- sem-version go 1.11
- "export GOPATH=~/go"
- "export PATH=/home/semaphore/go/bin:$PATH"
- checkout
jobs:
- name: goreleaser
commands:
- curl -sL https://git.io/goreleaser | bash
```
The following YAML file, `createSecret.yml` creates a new secret item that is called goreleaser
with one environment variable, named GITHUB_TOKEN:
```yml
apiVersion: v1alpha
kind: Secret
metadata:
name: goreleaser
data:
env_vars:
- name: GITHUB_TOKEN
value: "4afk4388304hfhei34950dg43245"
```
2019-02-25 15:46:01 +02:00
Check [Managing Secrets ](https://docs.semaphoreci.com/article/51-secrets-yaml-reference ) for
2018-10-31 18:06:30 +02:00
more detailed documentation.
2019-05-26 16:27:28 +02:00
## GitLab CI
To push releases to both GitHub and the **official** Docker registry, add a file `.gitlab-ci.yml` in the Go project directory:
```yaml
image: docker:stable
services:
- docker:dind
stages:
- build
variables:
GORELEASER_IMAGE: goreleaser/goreleaser:latest
DOCKER_REGISTRY: https://index.docker.io/v1/
build:
stage: build
script:
- docker pull $GORELEASER_IMAGE
- docker run --rm --privileged -v $PWD:/go/src/github.com/YourGithubUser/YourGithubRepo -v /var/run/docker.sock:/var/run/docker.sock -w /go/src/github.com/YourGithubUser/YourGithubRepo -e GITHUB_TOKEN -e DOCKER_USERNAME -e DOCKER_PASSWORD -e DOCKER_REGISTRY $GORELEASER_IMAGE release --rm-dist
```
Next, in the GitLab sidebar add the variables `DOCKER_USERNAME` , `DOCKER_PASSWORD` and `GITHUB_TOKEN` through Project --> Settings --> CI / CD --> Variables.\
Make sure they are set to *Masked* (*Protection* is not needed).
To push to some other Docker registry (e.g. to a GitLab registry), set different variables in the file above:
```txt
CI_REGISTRY: gitlab.example.com:4567
DOCKER_REGISTRY: $CI_REGISTRY
DOCKER_USERNAME: gitlab-ci-token
DOCKER_PASSWORD: $CI_JOB_TOKEN
```
Make sure the `image_templates` in the file `.goreleaser.yml` reflect that custom registry!
Example:
```yaml
dockers:
-
goos: linux
goarch: amd64
binaries:
- program
image_templates:
- 'gitlab.example.com:4567/Group/Project:{{ .Tag }}'
- 'gitlab.example.com:4567/Group/Project:latest'
```
2019-06-03 14:18:27 +02:00
## Codefresh
Codefresh uses Docker based pipelines where all steps must be Docker containers. Using Goreleaser is very easy via the [existing Docker image ](https://hub.docker.com/r/goreleaser/goreleaser/ ).
Here is an example pipeline that builds a Go application and then uses Goreleaser.
```yaml
version: '1.0'
stages:
- prepare
- build
- release
steps:
main_clone:
title: 'Cloning main repository...'
type: git-clone
repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}'
revision: '${{CF_REVISION}}'
stage: prepare
BuildMyApp:
title: Compiling go code
stage: build
2019-09-13 14:53:56 +02:00
image: 'golang:1.13'
2019-06-03 14:18:27 +02:00
commands:
2019-09-13 14:53:56 +02:00
- go build
2019-06-03 14:18:27 +02:00
ReleaseMyApp:
title: Creating packages
stage: release
image: 'goreleaser/goreleaser'
commands:
2019-09-13 14:53:56 +02:00
- goreleaser --rm-dist
2019-06-03 14:18:27 +02:00
```
You need to pass the variable `GITHUB_TOKEN` in the Codefresh UI that contains credentials to your Github account or load it from [shared configuration ](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/shared-configuration/ ).
You should also restrict this pipeline to run only on tags when you add [git triggers ](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/triggers/git-triggers/ ) on it.
2019-07-05 16:21:46 +02:00
More details can be found in the [goreleaser example page ](https://codefresh.io/docs/docs/learn-by-example/golang/goreleaser/ ).