templating icon indicating copy to clipboard operation
templating copied to clipboard

Adding package references via post action doesn't work

Open das-kaesebrot opened this issue 2 years ago • 11 comments

I'm trying to dynamically add a new package reference to a solution template based on a symbol set previously through parameters in the post actions of my template, like this (package references changed for privacy):

{
   ...
    "symbols": {
        "hosting": {
            "type": "parameter",
            "datatype": "choice",
            "description": "Choose between HttpSys and Kestrel for ASP.NET Core hosting",
            "choices": [
                {
                    "choice": "httpsys",
                    "description": "HttpSys hosting"
                },
                {
                    "choice": "kestrel",
                    "description": "Kestrel hosting"
                }
            ],
            "defaultValue": "httpsys"
        }
        // other params go here...
    },
    "postActions": [
        {
            "condition": "(hosting == 'httpsys')",
            "description": "Adding reference to HttpSys",
            "manualInstructions": [
                { "text": "Manually add the reference to your project file" }
            ],
            "actionId": "B17581D1-C5C9-4489-8F0A-004BE667B814",
            "continueOnError": true,
            "args": {
                "referenceType": "package",
                "reference": "Microsoft.AspNetCore.Server.HttpSys",
                "version": "2.2.6",
                "targetFiles": "MyProject/MyProject.csproj"
            }
        },
        {
            "condition": "(hosting == 'kestrel')",
            "description": "Adding reference to Kestrel",
            "manualInstructions": [
                { "text": "Manually add the reference to your project file" }
            ],
            "actionId": "B17581D1-C5C9-4489-8F0A-004BE667B814",
            "continueOnError": true,
            "args": {
                "referenceType": "package",
                "reference": "Microsoft.AspNetCore.Server.Kestrel",
                "version": "2.2.0",
                "targetFiles": "MyProject/MyProject.csproj"
            }
        }
    ]
}

For adding post actions, I've been following the docs for post action registries at https://github.com/dotnet/templating/wiki/Post-Action-Registry#add-a-reference-to-a-project-file.

Running dotnet new mytemplate -n test123 unfortunately results in a very short error message without an explanation as to why it fails:

PS C:\Users\user\repos> dotnet new mytemplate -n test123
The template "App template" was created successfully.

Processing post-creation actions...
Post action failed.
Manual instructions: Manually add the reference to your project file

I've verified that the package references are compatible by manually running dotnet add package Microsoft.AspNetCore.Server.HttpSys --version 2.2.6, which adds a reference to the newly generated .csproj file just fine. My colleagues have tested the template as well, resulting in the same error message. I've already tried working around this using a powershell script, but it would be way easier to use post actions for this purpose.

dotnet --version: 6.0.301 Platform: Windows

das-kaesebrot avatar Jul 19 '22 19:07 das-kaesebrot

@das-kaesebrot we recently fixed 2 issues related to this post actions https://github.com/dotnet/templating/pull/4922 https://github.com/dotnet/templating/pull/4948 but unfortunately those fixes will be released on in .NET 7.

Using JSON array may fix the issue "targetFiles": [ "MyProject/MyProject.csproj" ]

vlada-shubina avatar Jul 20 '22 10:07 vlada-shubina

@vlada-shubina Thank you! Unforunately, the JSON array workaround doesn't seem to work either. It may be possible to work around this using a custom script, although I can't find any examples of how to pass generated symbols as post action script arguments. Is it even possible to do so?

das-kaesebrot avatar Jul 20 '22 12:07 das-kaesebrot

no, unfortunately this is not possible.
There is a separate ticket for this https://github.com/dotnet/templating/issues/1600 https://github.com/dotnet/templating/issues/1600#issuecomment-403189839 has possible workaround.

I would like to investigate your case a bit more, could you please send me the full template that reproduces the issue? It might be simplified as much to keep the issue reproduced. Thank you.

vlada-shubina avatar Jul 20 '22 13:07 vlada-shubina

Thank you for investigating this, I've attached a simplified templating solution containing the template in question as well as the generated nuget package: myapptemplate-simplified.tar.gz

das-kaesebrot avatar Jul 21 '22 09:07 das-kaesebrot

For the post-action issue adding reference, root cause is the path of targetFiles missed the prefix ./ for relative path. It should look like "targetFiles": [ "./MyTemplateApp/MyTemplateApp.csproj" ].

Since #2810 was fixed, source relative path of file change is prefixed with ./ relative to template source root while getting creation effects. Then the template also needs the prefix matching file changes when processing post action.

However to get the command like dotnet new mytemplate -n test123 work well needs the fixes that will be released in .NET 7 as mentioned above.

GangWang01 avatar Aug 08 '22 08:08 GangWang01

Update more detail on the investigation above.

For dotnet 6.0.301 and above, it needs ./ prefix with relative path of targetFiles to get adding package reference post action work. But the command like dotnet new mytemplate -n test123 doesn't work because of -n test123. It renames project file when instantiating template. While just as the note of https://github.com/dotnet/templating/wiki/Post-Action-Registry#add-a-reference-to-a-project-file the file name change is ignored when using targetFiles.

Commit https://github.com/dotnet/templating/commit/b7dc29745861400991ca519f85bfd8a9eee43fd4 in main branch resolved the problem. targetFiles can know the file name change when instantiating template.

GangWang01 avatar Aug 11 '22 03:08 GangWang01

Thanks @GangWang01

@das-kaesebrot it seems you can get the desired result when using "targetFiles": [ "./MyTemplateApp/MyTemplateApp.csproj" ]. though with number of limitations in .NET 6. in .NET 7 we have them all fixed.

please let us know if the workaround works for you and if you need more info on this issue, thank you.

vlada-shubina avatar Aug 15 '22 07:08 vlada-shubina

First of all, thanks for the feedback. Unfortunately, I'm not having any success with that either:

StdOut:
(empty)
StdErr:
Could not find project or directory `./test123/test123.csproj`.

das-kaesebrot avatar Aug 15 '22 08:08 das-kaesebrot

@das-kaesebrot As mentioned above the command with -n test123 is not supported for adding reference post action when using targetFiles in .NET 6. Please also see the reason mentioned above. To make the post action work, you need to remove parameter like -n test123.

GangWang01 avatar Aug 15 '22 08:08 GangWang01

I'm very sorry, but having to leave out the ability to give the project a name partly defeats the purpose of being able to create a project using a template. Unfortunately, replacing all occurrences of the project name afterwards is not really an option for us.

das-kaesebrot avatar Aug 15 '22 08:08 das-kaesebrot

We may consider servicing the following for 6.0.4xx:

  • https://github.com/dotnet/templating/pull/4869
  • https://github.com/dotnet/templating/pull/4922
  • https://github.com/dotnet/templating/pull/4948

I'll keep posted on decision made.

vlada-shubina avatar Aug 15 '22 08:08 vlada-shubina

We got approval for servicing the fixes. Preliminary, they should delivered with Oct update.

vlada-shubina avatar Aug 31 '22 13:08 vlada-shubina

Thank you!

das-kaesebrot avatar Sep 13 '22 17:09 das-kaesebrot