-
Notifications
You must be signed in to change notification settings - Fork 286
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
Add builder to project descriptor #1116
Conversation
Signed-off-by: Sambhav Kothari <skothari44@bloomberg.net>
@@ -72,18 +72,30 @@ func Build(logger logging.Logger, cfg config.Config, packClient PackClient) *cob | |||
logger.Debugf("Using project descriptor located at %s", style.Symbol(actualDescriptorPath)) | |||
} | |||
|
|||
builder := flags.Builder |
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.
This ended up being a bit weird to implement than I imagined.
We needed to do 2 things -
- Figure out if the user explicitly passed a flag or the default one was used.
- Parse the project descriptor and check if builder existed before before we could validate the bulder flag. In order to do so, I moved the builder validation out of validate flags as it was sort of a chicken egg problem where I had to use the project descriptor from the flags and parse it before I could validate the actual flags and that seemed to break the whole contract of validating the flags before using them. So for now I extracted this part out of validate flags and I explicitly check and throw an error if builder is null.
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.
I also had to parse the builder and decide which one to use in the command instead of the client.Build as at that point it was too late to distinguish which flag was passed and the order of preference.
Codecov Report
@@ Coverage Diff @@
## main #1116 +/- ##
==========================================
- Coverage 80.52% 80.00% -0.51%
==========================================
Files 136 136
Lines 8243 6005 -2238
==========================================
- Hits 6637 4804 -1833
+ Misses 1176 767 -409
- Partials 430 434 +4
Flags with carried forward coverage won't be shown. Click here to find out more. |
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.
This is great! One small concern is that we don't have a unit test for the case where a default builder was previously set in the config
, but we test it in our acceptance tests here (
pack/acceptance/acceptance_test.go
Lines 798 to 936 in dc94db0
when("default builder is set", func() { | |
it.Before(func() { | |
pack.RunSuccessfully("config", "default-builder", builderName) | |
pack.JustRunSuccessfully("config", "trusted-builders", "add", builderName) | |
}) | |
it("creates a runnable, rebuildable image on daemon from app dir", func() { | |
appPath := filepath.Join("testdata", "mock_app") | |
output := pack.RunSuccessfully( | |
"build", repoName, | |
"-p", appPath, | |
) | |
assertOutput := assertions.NewOutputAssertionManager(t, output) | |
assertOutput.ReportsSuccessfulImageBuild(repoName) | |
assertOutput.ReportsUsingBuildCacheVolume() | |
assertOutput.ReportsSelectingRunImageMirror(runImageMirror) | |
t.Log("app is runnable") | |
assertImage.RunsWithOutput(repoName, "Launch Dep Contents", "Cached Dep Contents") | |
t.Log("it uses the run image as a base image") | |
assertImage.HasBaseImage(repoName, runImage) | |
t.Log("sets the run image metadata") | |
assertImage.HasLabelWithData(repoName, "io.buildpacks.lifecycle.metadata", fmt.Sprintf(`"stack":{"runImage":{"image":"%s","mirrors":["%s"]}}}`, runImage, runImageMirror)) | |
t.Log("registry is empty") | |
assertImage.NotExistsInRegistry(repo) | |
t.Log("add a local mirror") | |
localRunImageMirror := registryConfig.RepoName("pack-test/run-mirror") | |
imageManager.TagImage(runImage, localRunImageMirror) | |
defer imageManager.CleanupImages(localRunImageMirror) | |
pack.JustRunSuccessfully("config", "run-image-mirrors", "add", runImage, "-m", localRunImageMirror) | |
t.Log("rebuild") | |
output = pack.RunSuccessfully( | |
"build", repoName, | |
"-p", appPath, | |
) | |
assertOutput = assertions.NewOutputAssertionManager(t, output) | |
assertOutput.ReportsSuccessfulImageBuild(repoName) | |
assertOutput.ReportsSelectingRunImageMirrorFromLocalConfig(localRunImageMirror) | |
cachedLaunchLayer := "simple/layers:cached-launch-layer" | |
assertLifecycleOutput := assertions.NewLifecycleOutputAssertionManager(t, output) | |
assertLifecycleOutput.ReportsRestoresCachedLayer(cachedLaunchLayer) | |
assertLifecycleOutput.ReportsExporterReusingUnchangedLayer(cachedLaunchLayer) | |
assertLifecycleOutput.ReportsCacheReuse(cachedLaunchLayer) | |
t.Log("app is runnable") | |
assertImage.RunsWithOutput(repoName, "Launch Dep Contents", "Cached Dep Contents") | |
t.Log("rebuild with --clear-cache") | |
output = pack.RunSuccessfully("build", repoName, "-p", appPath, "--clear-cache") | |
assertOutput = assertions.NewOutputAssertionManager(t, output) | |
assertOutput.ReportsSuccessfulImageBuild(repoName) | |
assertLifecycleOutput = assertions.NewLifecycleOutputAssertionManager(t, output) | |
assertLifecycleOutput.ReportsSkippingBuildpackLayerAnalysis() | |
assertLifecycleOutput.ReportsExporterReusingUnchangedLayer(cachedLaunchLayer) | |
assertLifecycleOutput.ReportsCacheCreation(cachedLaunchLayer) | |
t.Log("cacher adds layers") | |
assert.Matches(output, regexp.MustCompile(`(?i)Adding cache layer 'simple/layers:cached-launch-layer'`)) | |
t.Log("inspecting image") | |
inspectCmd := "inspect" | |
if !pack.Supports("inspect") { | |
inspectCmd = "inspect-image" | |
} | |
var ( | |
webCommand string | |
helloCommand string | |
helloArgs []string | |
helloArgsPrefix string | |
) | |
if imageManager.HostOS() == "windows" { | |
webCommand = ".\\run" | |
helloCommand = "cmd" | |
helloArgs = []string{"/c", "echo hello world"} | |
helloArgsPrefix = " " | |
} else { | |
webCommand = "./run" | |
helloCommand = "echo" | |
helloArgs = []string{"hello", "world"} | |
helloArgsPrefix = "" | |
} | |
formats := []compareFormat{ | |
{ | |
extension: "txt", | |
compareFunc: assert.TrimmedEq, | |
outputArg: "human-readable", | |
}, | |
{ | |
extension: "json", | |
compareFunc: assert.EqualJSON, | |
outputArg: "json", | |
}, | |
{ | |
extension: "yaml", | |
compareFunc: assert.EqualYAML, | |
outputArg: "yaml", | |
}, | |
{ | |
extension: "toml", | |
compareFunc: assert.EqualTOML, | |
outputArg: "toml", | |
}, | |
} | |
for _, format := range formats { | |
t.Logf("inspecting image %s format", format.outputArg) | |
output = pack.RunSuccessfully(inspectCmd, repoName, "--output", format.outputArg) | |
expectedOutput := pack.FixtureManager().TemplateFixture( | |
fmt.Sprintf("inspect_image_local_output.%s", format.extension), | |
map[string]interface{}{ | |
"image_name": repoName, | |
"base_image_id": h.ImageID(t, runImageMirror), | |
"base_image_top_layer": h.TopLayerDiffID(t, runImageMirror), | |
"run_image_local_mirror": localRunImageMirror, | |
"run_image_mirror": runImageMirror, | |
"web_command": webCommand, | |
"hello_command": helloCommand, | |
"hello_args": helloArgs, | |
"hello_args_prefix": helloArgsPrefix, | |
}, | |
) | |
format.compareFunc(output, expectedOutput) | |
} | |
}) |
Signed-off-by: Sambhav Kothari skothari44@bloomberg.net
Summary
Adds support for the builder key in project descriptor
Output
Before
After
Documentation
Related
Resolves #1114
Implements buildpacks/rfcs#138 (We should wait for that to be merged before merging this I guess?)