- Name: Contractual Build Plan
- Start Date: 2019-04-12
- Status: Implemented
- CNB Pull Requests: rfcs#12, spec#52, lifecycle#149
- CNB Issues: (lifecycle issues to follow)
This proposal suggests a new contract for generating the build plan and bill-of-materials that is easier to understand and more straightforward compared to the current method. In addition, it fixes a critical design flaw in the current build plan mechanism: two buildpacks that require the same dependency at different stages (build vs. launch) will often result in unclear build failures due to the second request overriding the first request.
While the current build plan contract is superficially simple, buildpacks currently use it in ways that are occasionally difficult to understand or explain. For example, some buildpacks "push" dependencies they plan to provide into the build plan, while other buildpacks "pull" dependencies they need from other buildpacks by placing them in the build plan.
Additionally, reading an incremental build plan during the detection phase is not necessary to accomplish the current use cases for the build plan.
- Accounts for all current use cases while applying a tighter, "pull-only" contract
- Speeds up detection
- Simplifies writing modular buildpacks
- Easier to understand
This RFC proposes a breaking change to the build plan contract. Changes would consist of modifications to the buildpack specification and lifecycle.
It affects buildpack developers who implement modular, interdependent buildpacks.
/bin/detect
no longer receives a build plan on stdin.- In
/bin/detect
, buildpacks contribute two sections to the build plan:requires
andprovides
- Every required dependency must be provided by the current buildpack or a previous buildpack one or more times for detection to pass.
- Every provided dependency must be required one or more times for detection to pass.
- If an optional buildpack provides a dependency that is not required, it is excluded from consideration.
- If an optional buildpack requires a dependency that is not provided, it is excluded from consideration.
- Multiple buildpacks may require or provide the same dependency.
/bin/build
no longer receives a build plan on stdin./bin/build
's build plan argument contains required dependencies that it provides./bin/build
may refine its build plan to contain additional dependency metadata./bin/build
may remove all entries for a dependency in its build plan to allow a subsequent buildpack to provide that dependency.
Node Engine Buildpack:
[[provides]]
name = "nodejs"
NPM Buildpack:
[[requires]]
name = "nodejs"
version = "1.x"
[requires.metadata]
something = "12"
[[requires]]
name = "node_modules"
[[provides]]
name = "node_modules"
Node Engine Buildpack:
[[nodejs]]
version = "1.x"
[nodejs.metadata]
something = "12"
NPM Buildpack:
[[node_modules]]
When combined:
[[nodejs]]
version = "1.2.3"
[nodejs.metadata]
something = "12"
arch = "x86_64"
[[node_modules]]
packages = ["..."]
-
Should we provide an alternative version of
[[require]]
that also provides? Alternatively, should[[require]]
have aprovide = true
option? -
How can a buildpack require either of two different dependencies, but not both?
With the distribution spec, complex logic can be expressed by multiple buildpacks that live in the same repository. These buildpacks may have the same source.
N/A
-
It's no longer possible to push structured data to subsequent buildpacks during detection.
-
Breaking change for all current buildpacks that use the build plan.
Keeping the current build plan mechanism.