Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Goreleaser to manage release #55

Merged
merged 1 commit into from
May 18, 2020
Merged

Goreleaser to manage release #55

merged 1 commit into from
May 18, 2020

Conversation

gianarb
Copy link
Contributor

@gianarb gianarb commented May 15, 2020

GoReleaser is a cool and powerful tool to manage releases for Go code.
It highly configurable and flexible via YAML file.

The goal for this are:

  • Cross compile Go binary for manager in Linux, Darwin and arm and amd
  • Build docker image for linux arm and and
  • proper multi arch support
  • Have a generate changelog that looks at PR and it gets pushed as
    GitHub release page.
  • upload custerctl.yaml cluster-template.yaml along with the other
    required maniafest and binaries to the GitHub page
  • The process has to be reproducible locally to have a look at how a
    release will look like
  • It has to run in CI detecting a new tag pushed to the repository

Makefile Outdated
@@ -74,7 +74,7 @@ CORE_URL ?= https://github.com/kubernetes-sigs/cluster-api/releases/download/$(C
# useful function
word-dot = $(word $2,$(subst ., ,$1))

VERSION ?= 0.3.0
VERSION ?= v0.0.0
Copy link
Contributor Author

@gianarb gianarb May 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temporary, change it git command to get the last tag. If nothing is in there v0.0.0 can be used as default value

@deitch
Copy link
Contributor

deitch commented May 15, 2020

Do you mind including a doc in docs/ describing:

  • what the release process is
  • how it works
  • dependencies, and how they are installed
  • how to trigger it
  • what gets created where; e.g. I see you added dist/ to .gitignore, but we already create artifacts in bin/ for binaries and out/ for everything else, especially out/release/. I don't mind changing in the least, but we need to describe what purpose each dir serves and what uses it
  • how this interacts with CI, in this case drone via .drone.yml?

Historically (e.g. ccm, csi), I have used drone to just run the right make commands that launch everything. That includes build matrices. Again, more than happy to change it, but we need to understand what we are getting and how it works.

@gianarb
Copy link
Contributor Author

gianarb commented May 15, 2020

It will end up in drone, as you can see there is a box that is waiting to be marked as done. Btw will add doc for sure

Copy link
Contributor

@deitch deitch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some typos, but mainly things to add to explain. It is helpful that I haven't used goreleaser before but have done lots of docker and go releases, so I can review from the perspective of someone who just wants to understand how it all works together and what to do.


We use drone as continuous integration and continuous delivery pipeline.
Integration means: running tests, checking code quality.
Delivery means: make a release when a new tag get pushed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to add something here about delivery vs release. Whenever something gets merged into master, we push a new image tagged with that hash, e.g. docker.io/packethost/cluster-api-provider-packet:abcde566. When we cut a release, i.e. a git tag, we also push an image tagged with that tag, e.g. docker.io/packethost/cluster-api-provider-packet:v0.3.1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do! Thanks, I didn't notice that


GoReleaser is a popular tool to release Go applications and library.

I use it a lot because it is very flexible and it supports a lot of features, we
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can be more assertive here:

We use goreleaser for the following features:


The release life cycle touches two directories:

1. `./dist` it is a temporary directory used by gorleaser to bundle all the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type: "gorleaser"

The release life cycle touches two directories:

1. `./dist` it is a temporary directory used by gorleaser to bundle all the
required files and binaries as long as the generated changelog and so on. It
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is confusing: "as long as the generated changelog"?


1. `./dist` it is a temporary directory used by gorleaser to bundle all the
required files and binaries as long as the generated changelog and so on. It
does not need to be checked in git and that's why it is in the gitignore.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to add the last sentence, it can simply be, "dist is in gitignore."


*Removing --skip-publish goreleaser will attempt a push to GitHub and to your
docker image repository (docker.io). In this way you can cut a release from your
laptop if needed. But it is not a good idea and we use drone for that*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, good point. Another reason for wrapping it in a make target, so that by default it doesn't publish, and you have to do something like make release-publish CONFIRM=true to get it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to say that write access to the docker registry normally is blocked, but don't try it unless you really know what you are doing.

Integration means: running tests, checking code quality.
Delivery means: make a release when a new tag get pushed.

## goreleaser
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use goreleaser only when cutting an actual tagged release, e.g. v0.3.2? What do we use when cutting builds on master directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, we use what we already have in place

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So there are two different flows, then? One for cutting tagged releases (goreleaser) and one for non-tagged merges (existing)? And I assume the difference is handled in drone.yml where "if release then run goreleaser"?

We should document that.

id: capp
env:
- CGO_ENABLED=0
binary: manager
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this create the artifacts in the repo root directory? Or in dist/? I don't see anything in the config that pushes it into dist, but maybe that is the default?

Also, how do we distinguish between one build and another, so we don't accidentally put the darwin-amd64 binary in the linux-arm64 image? The current make build target creates bin/manager-<GOOS>-<GOARCH>. Can we reuse that structure? Or is goreleaser limited from doing that? I imagine not, with those go text templates I see below, but I don't know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything that gets created by goreleaser is in dist

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And when it builds, how does it differentiate between the multiple binaries? It looks like it names them all manager, but there are multiple? Does it use the manager tag just as a tag, and automatically append the right arch/etc.? If so, how does Dockerfile.goreleaser get the right file? Or does it actually manipulate the dockerfile before running it?

- linux
goarch:
- amd64
- arm64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this try to build also for darwin/arm64? Will that even work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it is smart enough to build only what Go can build apparently 👍 in my test locally it built:

capp_darwin_amd64
capp_linux_amd64
capp_linux_arm64

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

.goreleaser.yml Outdated
- arm64
release:
extra_files:
- glob: ./out/release/infrastructure-packet/v0.0.0/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand, the version is 0.0.0?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah this has to be fixed 👍 it will be { .Tag }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use v2. There are known bugs with v1

password: ${{ secrets.DOCKER_PASSWORD }}
email: ${{ secrets.DOCKER_USERNAME }}
- name: Set up Go
uses: actions/setup-go@v1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Should use v2. Known bugs with v1

Copy link
Contributor

@deitch deitch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

GoReleaser is a cool and powerful tool to manage releases for Go code.
It highly configurable and flexible via YAML file.

The goal for this are:

- [x] Cross compile Go binary for manager in Linux, Darwin and arm and amd
- [ ] Build docker image for linux arm and amd with proper multi arch
   support
- [x] Have a generate changelog that looks at PR and it gets pushed as
   GitHub release page.
- [x] upload custerctl.yaml cluster-template.yaml along with the other
   required maniafest and binaries to the GitHub page
- [x] The process has to be reproducible locally to have a look at how a
   release will look like
- [ ] It has to run in CI detecting a new tag pushed to the repository
@gianarb gianarb merged commit 7fa050c into kubernetes-sigs:master May 18, 2020
@gianarb gianarb deleted the feature/goreleaser branch May 18, 2020 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants