cake-contrib / Cake.Mage

Cake addin providing Mage.exe support
https://cake-contrib.github.io/Cake.Mage/docs/
MIT License
4 stars 9 forks source link

Launcher should specified for .net3+ builds #31

Open unseensenpai opened 2 days ago

unseensenpai commented 2 days ago

Mage.exe is updated by dotnet. Dotnet-Mage.exe used on operations. And it requires launcher specification by https://github.com/dotnet/deployment-tools/blob/main/docs/dotnet-mage/README.md#dotnet-mage

Expected Behavior

Launcher should specified to command line builder for deployment operation.

MageSign operation or specific updated operation should -al (add launcher) and -td (target directory) options.

Current Behavior

Cannot create click once because of launcher.exe not exist. Manifest goes with exception inside.

Just imput -al and -td append side.

Possible Solution

I made another method for cake context.

/// <summary>
/// .Net6 or later programs need launcher implementation. 
/// Need entry point dll or exe file path 
/// and target directory to create it.
/// </summary>
/// <param name="context"></param>
/// <param name="settings"></param>

I have created Mage Settings for update.

/// <summary>
/// Class SignSettings.
/// </summary>
/// <seealso cref="Cake.Core.Tooling.ToolSettings" />
public class LauncherSettings : BaseNewAndUpdateMageSettings
{

    /// <summary>
    /// Gets or sets the launcher exe's folder.
    /// </summary>
    /// <value>To file.</value>
    public DirectoryPath TargetDirectory { get; set; }

    /// <summary>
    /// Launchers entry point is DLL or EXE for .net6+ UI projects.
    /// </summary>
    public string LauncherEntryPoint { get; set; }
}

Now new and update tool can be handle this settings:

NewOrUpdateMageTool.cs

else
{
    var launcherSettings = (LauncherSettings)settings;
    if (launcherSettings is null || string.IsNullOrWhiteSpace(launcherSettings.LauncherEntryPoint) || launcherSettings.TargetDirectory is null)
    {
        ArgumentNullException.ThrowIfNull(nameof(launcherSettings));
    }
    return builder
            //.Append("mage")
            .AppendNonNullFileNameSwitch("-al", launcherSettings.LauncherEntryPoint, Environment)
            .AppendNonNullDirectoryPathSwitch("-td", launcherSettings.TargetDirectory, Environment);
}
[CakeMethodAlias]
public static void MageAddLauncher(this ICakeContext context, LauncherSettings settings)
{
    if (settings == null) throw new ArgumentNullException(nameof(settings));

    NewOrUpdate(context, settings);

}

MageRunner.cs should dotnet-mage.exe image

Dotnet Tool Resolver should have dotnet-mage.exe path

var userProfilePath = _environment.GetSpecialPath(SpecialPath.UserProfile);
    var files = new List<FilePath>
    {
        // 64-bit
        programFiles64Bit.Combine(@"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools").CombineWithFilePath(toolExecutable),
        programFiles64Bit.Combine(@"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools").CombineWithFilePath(toolExecutable),
        programFiles64Bit.Combine(@"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools").CombineWithFilePath(toolExecutable),
        programFiles64Bit.Combine(@"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools").CombineWithFilePath(toolExecutable),
        programFiles64Bit.Combine(@"Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools").CombineWithFilePath(toolExecutable),
        programFiles64Bit.Combine(@"Windows Kits\8.1\bin\x64").CombineWithFilePath(toolExecutable),
        programFiles64Bit.Combine(@"Windows Kits\8.0\bin\x64").CombineWithFilePath(toolExecutable),
        programFiles64Bit.Combine(@"Microsoft SDKs\Windows\v7.1A\Bin").CombineWithFilePath(toolExecutable),
        programFiles64Bit.Combine("dotnet").CombineWithFilePath(toolExecutable),
        userProfilePath.Combine(@".dotnet\tools").CombineWithFilePath(toolExecutable),

        // x86
        programFilesX86.Combine(@"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools").CombineWithFilePath(toolExecutable),
        programFilesX86.Combine(@"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools").CombineWithFilePath(toolExecutable),
        programFilesX86.Combine(@"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools").CombineWithFilePath(toolExecutable),
        programFilesX86.Combine(@"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools").CombineWithFilePath(toolExecutable),
        programFilesX86.Combine(@"Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools").CombineWithFilePath(toolExecutable),
        programFilesX86.Combine(@"Windows Kits\8.1\bin\x86").CombineWithFilePath(toolExecutable),
        programFilesX86.Combine(@"Windows Kits\8.0\bin\x86").CombineWithFilePath(toolExecutable),
        programFilesX86.Combine(@"Microsoft SDKs\Windows\v7.1A\Bin").CombineWithFilePath(toolExecutable),
        programFilesX86.Combine("dotnet").CombineWithFilePath(toolExecutable),
        userProfilePath.Combine(@".dotnet\tools").CombineWithFilePath(toolExecutable)
};

So cake script can call like this:

MageAddLauncher(new LauncherSettings{
            LauncherEntryPoint = "Winform.UI.Project.Container.exe",
            TargetDirectory = localPublishFolder
        });

Steps to Reproduce (for bugs)

1. 2. 3. 4.

Context

Your Environment

MihaMarkic commented 1 day ago

Hi, you did a nice research. However, there is the problem of discovering executable. First, the old and new are differently named (mage.exe vs dotnet-mage.exe). I'd say there should be a version 2 of this plugin that ditches the old one and embraces only dotnet way. People with legacy mage can still use version 1.x.

MihaMarkic commented 1 day ago

Pushed branch feature/dotnetmage with prototype based on your work. Would you mind checking it out?

unseensenpai commented 23 hours ago

Seems like its working.

image

I tried on someshitty project cant confirm fully executable but there is a launcher.exe.

About dotnet-mage vs mage.exe, if there is no manifest problem go ahead.

Thanks for update.

MihaMarkic commented 11 hours ago

What manifest problem did you have in mind?

unseensenpai commented 10 hours ago

There is a entryPoint brackets(xml node parent) in exe.manifest for click once operation.

image

I didnt try that with other type of .net projects (like WPF, WinForms)

Should tested but documentation says it will work: image

So if cake mage consumers writes scripts in a correct order that works like in screenshot .net says.

The Correct Order Is:

MageAddLauncher() // Launcher Settings -> Launcher Entry Point (exe or dll) and Target Directory (deployment directory) MageNewApplication() // Application Settings MageSign() // Sign Settings -> Manifest File -> Cert File MageNewDeployment // Deployment Settings -> Manifest File -> Application File MageSign() // Sign Settings -> Application File -> Cert File

And its done.

MihaMarkic commented 7 hours ago

At the end of the day Cake.Mage would merely invoke dotnet-mage tool, so I guess the addin itself can't deal with these issues?