buildpacks / pack

CLI for building apps using Cloud Native Buildpacks
https://buildpacks.io
Apache License 2.0
2.58k stars 288 forks source link

Add a way for apps to exclude certain buildpacks #1612

Open effulgentsia opened 1 year ago

effulgentsia commented 1 year ago

Description

Currently, an app can either use a builder and let all of that builder's buildpacks (whose detection phase passes) contribute to the building, or an app can specify which buildpacks to use via the --buildpack option.

However, suppose an app wants to use a composite buildpack (such as paketo-buildpacks/php), which consists of many component buildpacks, but the app wants to not use one of those component buildpacks, even if that component buildpack's detection phase passes. An example is if my app has a composer.json file in it, which provides information to several of the component buildpacks that I want to run, but I do not want one of the component buildpacks (such as paketo-buildpacks/composer-install) to run.

Currently, the app would need to replace a single --buildpack=COMPOSITE_BUILDPACK option with a much longer --buildpack=COMPONENT_BUILDPACK_1 --buildpack=COMPONENT_BUILDPACK_2 --buildpack=COMPONENT_BUILDPACK_3 ... option in order to include all of the desired component buildpacks without including the undesired one.

It would be great if there was a way to instead specify an exclusion list.

Proposed solution

Describe alternatives you've considered

There's probably many other ways to approach this. I have not yet considered them.

Additional context

effulgentsia commented 1 year ago

I came across another use-case related to this. Suppose you have a component buildpack that is included in multiple composite buildpacks. For example, paketo-buildpacks/procfile is included in paketo-buildpacks/php and paketo-buildpacks/nodejs. In https://github.com/paketo-buildpacks/php-start/issues/124, I found that the order in which the buildpacks are added (e.g., in project.toml) is the order in which they run, so for example if this is my project.toml:

[_]
schema-version = "0.2"

[io.buildpacks]
builder = "paketobuildpacks/builder-jammy-full"

group = [
  {uri = "paketo-buildpacks/nodejs"},
  {uri = "paketo-buildpacks/php"}
]

build.env = [
  {name = "BP_NODE_PROJECT_PATH", value = "node-app"},
  {name = "BP_PHP_SERVER", value = "httpd"},
  {name = "BP_PHP_WEB_DIR", value = "php-app/web"},
  {name = "BPE_DEFAULT_PORT", value = "8080"}
]

Then all of the components of paketo-buildpacks/nodejs (including paketo-buildpacks/procfile) run before paketo-buildpacks/php, so then the latter ends up overriding what was done by paketo-buildpacks/procfile.

It would be nice to be able to cause paketo-buildpacks/procfile to run last, perhaps by doing something like:

group = [
  {uri = "paketo-buildpacks/nodejs", exclude = [{uri = paketo-buildpacks/procfile}]},
  {uri = "paketo-buildpacks/php", exclude = [{uri = paketo-buildpacks/procfile}]},
  {uri = "paketo-buildpacks/procfile"}
]

That's kind of a separate use-case (controlling the order) from the initial one (removing a buildpack entirely), but I wanted to mention it in case it informs the thinking around this.

natalieparellano commented 1 year ago

@buildpacks/toc any thoughts on this one?

jjbustamante commented 1 year ago

Hi @effulgentsia

This looks like a really interesting idea, would like to create an RFC to discuss the details of it?