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

use build as common API for build scenarios #10374

Merged
merged 2 commits into from
Mar 21, 2023
Merged

Conversation

ndeloof
Copy link
Contributor

@ndeloof ndeloof commented Mar 15, 2023

What I did
from various places we trigger builds (build, up and watch commands), use composeService#build as the single entry point into the (complex) build logic.

This allows to manage classic vs buildkit at early stage, and to pass the BuildConfig to classic builder, while we only get it converted into buildx.Options for buildkit builder

To get up to only build selected platform, prepareProjectForBuild mutate the project to remove unnecessary build config so that the exact same build function can be used both by up and build.
Added a test case to make it obvious about this mutation and prevent any regression next time we try to change this codebase :)

Related issue
see #10056 for illustration of the issue using buildx.Options to configure classic builder

(not mandatory) A picture of a cute animal, if possible in relation to what you did
image

@ndeloof ndeloof force-pushed the build_refactor branch 4 times, most recently from eefed69 to be48461 Compare March 15, 2023 18:15
@codecov
Copy link

codecov bot commented Mar 15, 2023

Codecov Report

Patch coverage: 85.27% and project coverage change: +0.03 🎉

Comparison is base (03f0ed1) 53.41% compared to head (c48bc95) 53.44%.

❗ Current head c48bc95 differs from pull request most recent head 7a57e2c. Consider uploading reports for the commit 7a57e2c to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##               v2   #10374      +/-   ##
==========================================
+ Coverage   53.41%   53.44%   +0.03%     
==========================================
  Files         104      104              
  Lines        8942     8919      -23     
==========================================
- Hits         4776     4767       -9     
+ Misses       3646     3632      -14     
  Partials      520      520              
Impacted Files Coverage Δ
pkg/compose/watch.go 0.00% <0.00%> (ø)
pkg/compose/build_classic.go 51.94% <80.64%> (-0.97%) ⬇️
pkg/api/api.go 49.05% <86.95%> (+29.05%) ⬆️
pkg/compose/build.go 76.71% <91.54%> (+0.43%) ⬆️

... and 2 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@ndeloof ndeloof force-pushed the build_refactor branch 2 times, most recently from 1d219b1 to 1d7be81 Compare March 16, 2023 11:07
@ndeloof ndeloof marked this pull request as ready for review March 16, 2023 12:32
@ndeloof ndeloof requested review from a team, nicksieger, StefanScherer, ulyssessouza, glours, milas and laurazard and removed request for a team March 16, 2023 12:34
@laurazard
Copy link
Contributor

Yessss this was a refactor that was really needed ❤️ I'll take a better look later + approve

@ndeloof ndeloof force-pushed the build_refactor branch 2 times, most recently from f0d360b to 58d5796 Compare March 17, 2023 08:01
Copy link
Contributor

@milas milas left a comment

Choose a reason for hiding this comment

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

✨ 🧹 👍🏻

if err != nil {
return err

if buildkitEnabled, err := s.dockerCli.BuildKitEnabled(); err != nil || !buildkitEnabled {
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: it might be good to bring this out of the "loop" (InDependencyOrder)

Also, I think it's probably safe to fail and propagate the error:
https://github.com/docker/cli/blob/3c9e0073dd3ab31783a9d27d5fc26b70d59db367/cli/command/cli.go#L171 (tl;dr it can only fail if you do something like DOCKER_BUILDKIT=not_a_bool

Or, at the very least, a warning that we're falling back would be nice.

if service.Image == "" && service.Build == nil {
return nil, fmt.Errorf("invalid service %q. Must specify either image or build", service.Name)
func (s *composeService) prepareProjectForBuild(project *types.Project, images map[string]string) error {
err := api.BuildOptions{}.Apply(project)
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 need to actually pass the api.BuildOptions down?

In Apply we use Pull / NoCache, which I assume are for the global CLI --pull & --no-cache flags respectively

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we only expose those flags for build command. up --build only applies options set by compose file

Comment on lines 299 to 300
NoCache: service.Build.NoCache || options.NoCache,
Pull: service.Build.Pull || options.Pull,
Copy link
Contributor

Choose a reason for hiding this comment

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

This is also done when mutating the project & service in api.BuildOptions::Apply()

Do we need both?

Copy link
Contributor Author

@ndeloof ndeloof Mar 21, 2023

Choose a reason for hiding this comment

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

yes indeed, reminiscence from an earlier attempt, before I moved it all to Apply :)

if len(options.Inputs.NamedContexts) > 0 {
return "", errors.Errorf("this builder doesn't support additional contexts, set DOCKER_BUILDKIT=1 to use BuildKit which does")
if len(service.Build.Secrets) > 0 {
return "", errors.Errorf("the classic builder doesn't support Secrets, set DOCKER_BUILDKIT=1 to use BuildKit")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return "", errors.Errorf("the classic builder doesn't support Secrets, set DOCKER_BUILDKIT=1 to use BuildKit")
return "", errors.Errorf("the classic builder doesn't support secrets, set DOCKER_BUILDKIT=1 to use BuildKit")

@@ -252,25 +211,18 @@ func isLocalDir(c string) bool {
return err == nil
}

func imageBuildOptions(options buildx.Options) dockertypes.ImageBuildOptions {
func imageBuildOptions(config *types.BuildConfig) dockertypes.ImageBuildOptions {
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps rename classicBuildOptions()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this produces the options for the ImageBuild engine API, so ...

"gotest.tools/v3/assert"
)

func TestPrepareProjectForBuild(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

💯 for these tests! We definitely need more unit test coverage for some of these complex scenarios like platforms, so this is awesome

Copy link
Contributor

@glours glours left a comment

Choose a reason for hiding this comment

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

LGTM

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.

4 participants