dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.65k stars 1.06k forks source link

Unable to publish multiple projects at the same time. #7238

Open joelharkes opened 7 years ago

joelharkes commented 7 years ago

When i publish with dotnet cli, the output is:

publish: Published to ../output/project1 Published 1/1 projects successfully

Which indicates i could publish multiple projects at te same time (why else say: 1/1)

so i tried this.

Steps to reproduce

dotnet publish project1 project2 -o ../output

Expected behavior

I expect 2 projects to be published in this output folder (each in there own folder, having the same name as the project folder).

Actual behavior

Unrecognized command or argument project2

Environment data

.NET Command Line Tools (1.0.0-preview2-1-003155)

Product Information:
 Version:            1.0.0-preview2-1-003155
 Commit SHA-1 hash:  d7b0190bd4

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.14393
 OS Platform: Windows
 RID:         win10-x64
richlander commented 2 years ago

@baronfel

flobernd commented 2 years ago

Edit:

I added a reusable workflow that can be used to create release artifacts for a specific set of projects in a solution: https://github.com/flobernd/workflows/blob/master/.github/workflows/dotnet_publish.yml

It uses the solution filter workaround (see below). Besides that, it parses the log output of the dotnet publish command in order to determine the project-names and output-pathes for all published projects. An artifact containing a seperate .zip file for each project is uploaded at the end.

Some examples: https://github.com/flobernd/workflow-test/tree/master/.github/workflows


@aaronr93 When I was searching for a good way to only build specific projects in my repository (defined by glob patterns), I quickly noticed that running multiple restore/build/publish jobs in parallel is tremendously slow compared to even building the complete solution.

After doing some research I found the key information about support for solution filters in the newer .NET CLI versions (starting from .NET Core 3.1 I think).

I created a reusable workflow that makes use of this feature: https://github.com/flobernd/workflows/blob/master/.github/workflows/dotnet_pack.yml

A little python script generates the .slnf file based on the input solution .sln and a list of glob patterns: https://github.com/flobernd/workflows/blob/master/scripts/solution_filter.py

I'll most likely add a dotnet_publish workflow myself to that repository in the next days, but feel free to use this idea (and/or the script) to implement a custom solution for yourself in the meantime.

However this is only the first part of a solution for the discussed issue. The binaries are created in ./{project}/bin/{configuration}/{framework}/publish or similar, if no output path is specified.

To summarize the current workaround:

  1. Generate a solution filter that includes only the desired publish targets
  2. Call dotnet publish {solution_filter.slnf} without specifying an output path
  3. Use publish binaries in ./{project}/bin/{configuration}/{framework}/publish
joelharkes commented 2 years ago

From joelharkes

I made a script that builds the dependency trees for all projects and then executes builds in parallel (Promises nodejs) according to the builds. I got a major decrease in build/publish time (on a multi core environment).

@joelharkes this script you mentioned 5 years ago could be very useful to us. Do you mind sharing the script please, if you still have it?

We are publishing over a hundred projects that all share a web of 10-20 core dependencies. Publishing in parallel could decimate our deployment time.

sorry mate, it was a node js script I think it also only worked with the old project.json format which is no longer used. This was the gist:

  1. find all project files
  2. make a dependency graph
  3. start with the outside/bottom nodes whom have no children/dependendats and trigger build process in separate process. (with forcing not to rebuild dependency projects)
  4. every time a build finishes trigger all dependent nodes which only runes once all the dependencies have been finished (either by removing one by one or counting untill you have had them all finished).

Conclusion

my end result was that in the end it had more or less the same speed as dotnet build/publish does a lot of overhead each time a new project is build. that is why i requested this feature.

jhudsoncedaron commented 2 years ago

@joelharkes The fastest path is and has always been generate a .sln file and run publish tmp.sln -c $CONFIGURATION -r $RID --self-contained true -p:ShouldUnsetParentConfigurationAndPlatform=false

flobernd commented 2 years ago

@joelharkes The fastest path is and has always been generate a .sln file

Generating a .slnf from a .sln is a simple solution as well as they are using a json format for these. I linked a python script that handles this task.