-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Speed CI and local builds up #944
Conversation
1d71870
to
d805939
Compare
4f14ae9
to
25b4c8f
Compare
Awesome, thanks! I might not find the time tomorrow to look into the details, but happy to go ahead with this. I mostly want to look at it out of curiosity, please don't block on my review. |
I've sprinkled the makefile with |
6052b05
to
2d05b51
Compare
Makefile
Outdated
@# Docker uses the file permissions as part of the COPY hash, which can lead to cache misses | ||
@# in hosts with different default file permissions (umask). | ||
chmod 0600 go.mod go.sum | ||
chmod 0700 install-build-deps.sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, we could tar up the context and pass to docker via stdin, I've seen it done in LinuxKit. Just FYI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a link?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, LinuxKit has build system written in Go no.
But see the docs, there are multiple options of how you can pass the context.
The main bottlenecks in the build currently are:
|
Update: I have updated the PR to:
We are now at a 4.5-minute build mark! I have updated the PR description and measurements accordingly. I know @errordeveloper is not going to like the use of CircleCI, but persisting Go's build cache and modules for changing source code can't really be done with Docker image caching (i.e.
This has been fixed |
5da8e16
to
ab4a508
Compare
4573bad
to
affba2f
Compare
Also, do not copy full sourcecode to buildcache container, since it will cause caching to fail whenever the sourcecode changes (we want to cache build dependencies).
It hasn't been needed for a long time https://golang.org/doc/go1.5#net Also it was implicit when CGO_ENABLED=0 anyways
As a side-effect, I added a new build stage
Use ubuntu-1604:201903-01 because: 1. The default executor (ubuntu-1604:201903-01) uses Ubuntu 14.04, which reached EOL and Circle recommends ubuntu-1604:201903-01 (see https://circleci.com/docs/2.0/configuration-reference/#available-machine-images ) 2. The default executor bundles Docker 17.09-ce which suffers from this bug, breaking caching: moby/moby#32816
It wasn't used and it prevents tests from being cached. See golang/go#23565 for more details.
1. Use file targets instead of .PHONY ones when possible. 2. Avoid generating files if they are up to date 3. Use proper prerequisites
1. Remove PWD prefix for local dependencies (otherwise we need to specify the full path in the make targets) 2. Remove zz_generated.deepcopy.go from its prerequisites
affba2f
to
fad0810
Compare
This change speeds CI builds up by using a docker image (
weaveworks/eksctl-build:deps-VERSION
) as dependency-cache and CircleCI's caching system for caching go modules ($GOPATH/pkg/mod
) and the go build artifacts (go env GOCACHE
). Fixes #920Dependencies don't change all that often, so caching them should save us a lot of time.
The change also speeds local builds and tests up since:
cmd/go: coverage profile should be cached with tests golang/go#23565 )
Finally, the change makes building the eksctl-image faster since the local go caches are mounted when building.
CI build times are:
vendor
directories): ~12 minutesvendor
directories and dependency caching): ~7 minutesSo, this change brings a ~66% speed improvement compared to master and a ~42% improvement compared to before go modules were introduced. Things will get even faster once #935 (comment) is addressed.
This change follows @errordeveloper's vision of keeping caching independent of the CI-system. It is inspired by this blog post and this Stackoverflow question.For now the dependency-cache image needs to be manually pushed (which I did), just like it was done before with
weaveworks/eksctl-build:latest
, which isn't ideal doesn't worsen the current situation. I will automate it once https://github.com/weaveworks/corp/issues/350 is resolved.PS: @errordeveloper FYI, using Docker images as a caching layer is a neat idea. However, Docker is not really made for this: the downsides (it took a couple of days to get it right, namely due to the file hashing invalidation and image pulling is slow in comparison with a caching-optimized storage) don't make it up for the upsides (having a CI-system-independent caching system). I think it would had taken me way less effort to use the CircleCI cache (see fluxcd/flux#2078 ). Well, at least I learned about layer caching in Docker ...