paketo-buildpacks / dotnet-publish

Apache License 2.0
3 stars 4 forks source link

[Investigation] Support building dotnet-core application from .sln file #307

Open prerak-patel opened 2 years ago

prerak-patel commented 2 years ago

What happened?

Build a dotnet-core 5.0 application using buildpack with multiple submodules each with its own .csproj file and .sln file at the root. Build fails with ERROR: No buildpack groups passed detection as it fails to locate project file in the root directory.

Build Configuration

Checklist

fg-j commented 2 years ago

Perhaps it'd be sufficient here for the buildpack to look recursively at app subdirectories to find *.csproj files during detection phase. During the build phase, the buildpack could run dotnet publish from the app root (which will build all projects in a solution). Would that address your need, @prerak-patel ?

fg-j commented 1 year ago

Before potentially implementing, this needs exploration:

fg-j commented 1 year ago

The other day, @macsux mentioned that it can be ambiguous which project(s) within a solution should be built. He mentioned the example of a frontend and backend checked in together under one solution, where the user may not want to build both into one container. This gives me the impression that it might not actually be wise for the buildpack to build the solution without BP_DOTNET_PROJECT_PATH set. @macsux perhaps you could comment here about this?

jwhitcraft commented 1 month ago

Hello, is there still any movement on being able to build everything listed in the SLN file. Right now we are using the old heroku dotnet build pack which allows you to build multiple projects into one container. We need this functionality so we can move these projects to the paketo buildpacks so.

Right now we can use these build packs if there is only one program to be compiled, but most of our projects need multiple things built into a single container.

macsux commented 1 month ago

@jwhitcraft can you explain what you mean by this? Containers do not generally have multiple processes running - they have a single app that starts up. Consider the following Solution:

│   MyProject.sln
│
├───Common
├───Backend
└───FrontEnd

If you gave buildpack just this solution project to containerize, what should it do? You have 2 distinct entry point apps, and a common library shared between them. There are 2 different containers that you would want to build from it. Buildpack cannot build more than one container.

Usually, when this comes up people want to build either FrontEnd or Backend but if they set the buildpack path to that subfolder it fails because there's a reference to Common project that recurses up to solution level - and it's not present in build container. The solution is to push the entire solution folder, but give it an entrypoint project that will be containerized using the environmental variable BP_DOTNET_PROJECT_PATH.

If your scenario is different, please provide details

jwhitcraft commented 1 month ago

@macsux ,

So our use case is this, our dotnet apps have different entry-points for doing db migrations, data migrations and then the main app.

│   MyProject.sln
│
├───Common
├───Backend
└───DataMigrations

We use the procfile as a way to define which entrypoint is to be used when starting the container. That is why we need to have both Backend and DataMigrations compiled in the same container as building two containers, while it could be done, would just lead to move overhead and complexity in our build system vs having both binaries built into the same container image.

make sense?

macsux commented 1 month ago

@jwhitcraft Containers are generally meant to have a single entry point executable. I would argue that is a quite rare and nonstandard scenario. I will go a step further and say packing multiple apps into a single container is an antipattern in most cases and you yourself mention you only doing it due to some internal complexities with your pipelining. Buildpacks goal is to provide opinionated best practices - this is not that. The scenario I brought up is a LOT more common and you definitely don't want to pack the backend and frontend into the same container as far as best practices go if the buildpack were to compile from sln.

I'll add that in many cases data migrations are often done via a framework that can be made part of the app code. This is true for Entity Framework migrations and FluentMigrator - both quite popular in .NET space. If they are part of your main app's code, then you can still accomplish what you're trying to do by simply introducing a command line subcommand for entry point to apply migrations (or apply migrations on startup automatically as many projects do).