statiqdev / Statiq.Web

Statiq Web is a flexible static site generator written in .NET.

Home Page:https://statiq.dev/web

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Background AddProcess issue with Deploy

niktek opened this issue · comments

public static async Task<int> Main(string[] args) =>
	await Bootstrapper
	.Factory
	.CreateWeb(args)
	.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("npm", "install")
	{
		ContinueOnError = false,
		WorkingDirectory = "node",
	})
	.AddProcess(ProcessTiming.AfterExecution, _ => new ProcessLauncher("npm", "run", "watch")
	{
		WorkingDirectory = "node",
		IsBackground = true
	})
	.AddProcess(ProcessTiming.BeforeDeployment, _ => new ProcessLauncher("npm", "run", "publish")
	{
		WorkingDirectory = "node",
	})
	.RunAsync();

The above is for the usual TailwindCSS workflow, Initialization - npm i, AfterExecution - run tailwind in watch mode as a background process and then BeforeDeployment - run tailwind once with --minify option.

dotnet run -- preview works functionally (but you do lose the ability to enter any text at the prompt, including ctrl-c)
dotnet run -- deploy absolutely shows the npm run publish command being issued and you can see the --minify flag in the output, but it doesn't minify. Is there any chance that the ProcessTiming.AfterExecution process still gets triggered on a deploy (but somehow doesn't show in the console) and perhaps it overwrites the output from the BeforeDeployment process ?

Doing an npm run publish on its own in the terminal runs fine and produces the desired output.

And potentially it might be great to have another option on the ProcessLauncher to not run on deployment ?

Duh, so I commented out the AfterExecution process and did a straight deploy and everything worked as expected, so it is indeed being overwritten by the AfterExecution process.

I'm thinking this is more due to my unfamiliarity with how processes work and whether they had any connection to the preview/deploy commands. It's easy enough to work around the above issue by just checking on the args as passed in.

I'll go ahead and drop some answers in here even though it's closed just in case that helps you or others in the future.

Is there any chance that the ProcessTiming.AfterExecution process still gets triggered on a deploy (but somehow doesn't show in the console)

Correct. I think the disconnect here might be that "execution" describes the overall Statiq process, including deployment pipelines if those are run. In other words, Statiq always does execution, and sometimes that execution includes deployment as the last set of pipelines.

So with that in mind, when deploying BeforeDeployment processes will run partway through execution while AfterExecution processes will always run at the end of execution, regardless of whether a deployment happened or not.

This does make me wonder if we're missing a AfterDeployment timing that will run at the end of deployment (and thus also the end of execution), but unlike AfterExecution will only run when deployment happens. Would something like that solve your use case?

Or maybe it's more that you need a AfterExecution that will only run when deployment does not run? I can see how there might be a need for that.

What there doesn't seem to be is a way to do a Process only on deploy without checking the args passed into Main(). For instance, I only want to do minification on deploy - I end up with this:

Bootstrapper boot = Bootstrapper
.Factory
.CreateWeb(args)
.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("npm", "install")
{
	ContinueOnError = false,
	WorkingDirectory = "node",
})
.AddPreviewProcess(ProcessTiming.BeforeExecution, _ => new ProcessLauncher("npm", "run", "watch")
{
	IsBackground = true,
	WorkingDirectory = "node",
});
if (args.Length !=0 && args[0] == "deploy")
{
	boot.AddProcess(ProcessTiming.BeforeDeployment, _ => new ProcessLauncher("npm", "run", "publish")
		{
			WorkingDirectory = "node",
		});
}

return await boot.RunAsync();

I think there is some potential for confusion because there is some implicit tying of the Processes class to the preview command and it could be construed that the BeforeDeployment timing only makes sense on a process that is being used in conjunction with the deploy command - but the Processes class has no concept of deploy in it.