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:
|
2020-01-26 16:35:19 +02:00
|
|
|
# needed only if you use the snap pipe:
|
|
|
|
- snapcraft
|
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
|
|
|
|
2019-11-01 14:25:36 +02:00
|
|
|
Here is how to do it with [CircleCI](https://circleci.com):
|
2018-08-01 14:44:05 +02:00
|
|
|
|
|
|
|
```yml
|
|
|
|
# .circleci/config.yml
|
2019-11-01 14:25:36 +02:00
|
|
|
version: 2.1
|
2018-08-01 14:44:05 +02:00
|
|
|
workflows:
|
2019-11-01 14:25:36 +02:00
|
|
|
main:
|
2018-08-01 14:44:05 +02:00
|
|
|
jobs:
|
|
|
|
- release:
|
2019-11-01 14:25:36 +02:00
|
|
|
# Only run this job on git tag pushes
|
2018-08-09 14:08:28 +02:00
|
|
|
filters:
|
|
|
|
branches:
|
|
|
|
ignore: /.*/
|
|
|
|
tags:
|
|
|
|
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
|
2019-11-01 14:25:36 +02:00
|
|
|
jobs:
|
|
|
|
release:
|
|
|
|
docker:
|
|
|
|
- image: circleci/golang:1.13
|
|
|
|
steps:
|
|
|
|
- checkout
|
|
|
|
- run: curl -sL https://git.io/goreleaser | bash
|
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
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
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
|
2020-01-08 16:11:09 +02:00
|
|
|
`source.developers.google.com/p/YourProjectId/r/github-YourGithubUser-YourGithubRepo`,
|
|
|
|
and that's what you're building off.
|
2018-10-02 16:14:40 +02:00
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
This repo has the wrong name, so to prevent GoReleaser from publishing to
|
|
|
|
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
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
- a "push to any branch" trigger for your regular CI (doesn't invoke GoReleaser)
|
|
|
|
- a "push to tag" trigger which invokes GoReleaser
|
2018-10-02 16:14:40 +02:00
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
The push to any branch trigger could use a `Dockerfile` or a `cloudbuild.yaml`,
|
2018-10-02 16:14:40 +02:00
|
|
|
whichever you prefer.
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
You should have a dedicated `cloudbuild.release.yaml` that is only used by the
|
|
|
|
"push to tag" trigger.
|
2018-10-02 16:14:40 +02:00
|
|
|
|
|
|
|
In this example we're creating a new release every time a new tag is pushed.
|
2020-01-08 16:11:09 +02:00
|
|
|
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
|
2018-10-02 16:14:40 +02:00
|
|
|
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
|
2020-01-08 16:11:09 +02:00
|
|
|
default pipeline specified in `.semaphore/semaphore.yml`.
|
2018-10-31 18:06:30 +02:00
|
|
|
|
|
|
|
```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*"
|
|
|
|
```
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
Pipeline file in `.semaphore/goreleaser.yml`:
|
2018-10-31 18:06:30 +02:00
|
|
|
|
|
|
|
```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
|
|
|
|
```
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
The following YAML file, `createSecret.yml` creates a new secret item that is
|
|
|
|
called GoReleaser with one environment variable, named `GITHUB_TOKEN`:
|
2018-10-31 18:06:30 +02:00
|
|
|
|
|
|
|
```yml
|
|
|
|
apiVersion: v1alpha
|
|
|
|
kind: Secret
|
|
|
|
metadata:
|
|
|
|
name: goreleaser
|
|
|
|
data:
|
|
|
|
env_vars:
|
|
|
|
- name: GITHUB_TOKEN
|
|
|
|
value: "4afk4388304hfhei34950dg43245"
|
|
|
|
```
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
Check [Managing Secrets](https://docs.semaphoreci.com/article/51-secrets-yaml-reference)
|
|
|
|
for more detailed documentation.
|
2019-05-26 16:27:28 +02:00
|
|
|
|
|
|
|
## GitLab CI
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
To push releases to both GitHub and the **official** Docker registry, add a
|
|
|
|
file `.gitlab-ci.yml` in the Go project directory:
|
2019-05-26 16:27:28 +02:00
|
|
|
|
|
|
|
```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
|
|
|
|
```
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
Next, in the GitLab sidebar add the variables `DOCKER_USERNAME`,
|
|
|
|
`DOCKER_PASSWORD` and `GITHUB_TOKEN` through
|
|
|
|
Project --> Settings --> CI / CD --> Variables.
|
2019-05-26 16:27:28 +02:00
|
|
|
Make sure they are set to *Masked* (*Protection* is not needed).
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
To push to some other Docker registry (e.g. to a GitLab registry), set
|
|
|
|
different variables in the file above:
|
2019-05-26 16:27:28 +02:00
|
|
|
|
|
|
|
```txt
|
|
|
|
CI_REGISTRY: gitlab.example.com:4567
|
|
|
|
DOCKER_REGISTRY: $CI_REGISTRY
|
|
|
|
DOCKER_USERNAME: gitlab-ci-token
|
|
|
|
DOCKER_PASSWORD: $CI_JOB_TOKEN
|
|
|
|
```
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
Make sure the `image_templates` in the file `.goreleaser.yml` reflect that
|
|
|
|
custom registry!
|
2019-05-26 16:27:28 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
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/).
|
2019-06-03 14:18:27 +02:00
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
Here is an example pipeline that builds a Go application and then uses
|
|
|
|
GoReleaser.
|
2019-06-03 14:18:27 +02:00
|
|
|
|
|
|
|
```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
|
|
|
```
|
|
|
|
|
2020-01-08 16:11:09 +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-06-03 14:18:27 +02:00
|
|
|
|
2020-01-08 16:11:09 +02:00
|
|
|
More details can be found in the
|
|
|
|
[GoReleaser example page](https://codefresh.io/docs/docs/learn-by-example/golang/goreleaser/).
|