Skip to content

Commit

Permalink
feat: Remove Node.js runtime dependencies from docfx tools (#10066)
Browse files Browse the repository at this point in the history
  • Loading branch information
filzrev authored Jul 8, 2024
1 parent 46df7ca commit b40f492
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 4 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ jobs:

- name: dotnet publish
run: |
dotnet publish src/docfx -f net8.0 -c Release /p:Version=${GITHUB_REF_NAME#v} --self-contained -r win-x64 -o drop/publish/win-x64 /p:PlaywrightPlatform=win
dotnet publish src/docfx -f net8.0 -c Release /p:Version=${GITHUB_REF_NAME#v} --self-contained -r linux-x64 -o drop/publish/linux-x64 /p:PlaywrightPlatform=linux
dotnet publish src/docfx -f net8.0 -c Release /p:Version=${GITHUB_REF_NAME#v} --self-contained -r osx-x64 -o drop/publish/osx-x64 /p:PlaywrightPlatform=osx
dotnet publish src/docfx -f net8.0 -c Release /p:Version=${GITHUB_REF_NAME#v} --self-contained -r win-x64 -o drop/publish/win-x64
dotnet publish src/docfx -f net8.0 -c Release /p:Version=${GITHUB_REF_NAME#v} --self-contained -r linux-x64 -o drop/publish/linux-x64
dotnet publish src/docfx -f net8.0 -c Release /p:Version=${GITHUB_REF_NAME#v} --self-contained -r osx-x64 -o drop/publish/osx-x64
mkdir -p drop/bin
- run: zip -r ../../bin/docfx-win-x64-${GITHUB_REF_NAME}.zip .
Expand Down
8 changes: 8 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,12 @@
</PackageReference>
</ItemGroup>


<!-- Remove Node.js runtime dependencies that used by playwright -->
<Target Name="RemoveNodeJsRuntimes" AfterTargets="CopyPlaywrightFilesToOutput">
<ItemGroup>
<Content Remove="@(Content)" Condition="$([System.String]::Copy('%(Content.PlaywrightFolder)').Contains('node\'))" />
</ItemGroup>
</Target>

</Project>
7 changes: 6 additions & 1 deletion docs/reference/docfx-environment-variables-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ This setting is intended to be used on offline environment.

## `DOCFX_PDF_TIMEOUT`

Maximum time in milliseconds to override the default [Playwright timeout](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-timeout) for PDF generation.
Maximum time in milliseconds to override the default [Playwright timeout](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-timeout) for PDF generation.

## `PLAYWRIGHT_NODEJS_PATH`

Custom Node.js executable path that will be used by the `docfx pdf' command.
By default, docfx automatically detect installed Node.js from `PATH`.
1 change: 1 addition & 0 deletions src/Docfx.App/Docfx.App.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<ItemGroup>
<InternalsVisibleTo Include="docfx" />
<InternalsVisibleTo Include="docfx.Tests" />
<InternalsVisibleTo Include="docfx.Snapshot.Tests" />
</ItemGroup>

<ItemGroup>
Expand Down
80 changes: 80 additions & 0 deletions src/Docfx.App/Helpers/PlaywrightHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;
using Docfx.Common;
using Docfx.Exceptions;

#nullable enable

namespace Docfx;

internal static class PlaywrightHelper
{
public static void EnsurePlaywrightNodeJsPath()
{
// Skip if playwright environment variable exists.
if (Environment.GetEnvironmentVariable("PLAYWRIGHT_DRIVER_SEARCH_PATH") != null)
return;

if (Environment.GetEnvironmentVariable("PLAYWRIGHT_NODEJS_PATH") != null)
return;

if (!TryFindNodeExecutable(out var exePath, out var nodeVersion))
{
throw new DocfxException("Node.js executable is not found. Try to install Node.js or set the `PLAYWRIGHT_NODEJS_PATH` environment variable.");
}

Logger.LogInfo($"Using Node.js {nodeVersion} executable.");
Logger.LogVerbose($"Path: {exePath}");

Environment.SetEnvironmentVariable("PLAYWRIGHT_NODEJS_PATH", exePath, EnvironmentVariableTarget.Process);
}

private static bool TryFindNodeExecutable(out string exePath, out string nodeVersion)
{
// Find Node.js executable installation path from PATHs.
string exeName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "node.exe" : "node";

var pathEnv = Environment.GetEnvironmentVariable("PATH");
if (pathEnv == null)
throw new DocfxException("Failed to get `PATH` environment variable.");

var paths = pathEnv.Split(Path.PathSeparator);
foreach (var path in paths)
{
string fullPath = Path.GetFullPath(Path.Combine(path, exeName));

if (File.Exists(fullPath))
{
exePath = fullPath;
nodeVersion = GetNodeVersion(exePath);
return true;
}
}

exePath = "";
nodeVersion = "";
return false;
}

/// <summary>
/// Returns `node --version` command result
/// </summary>
private static string GetNodeVersion(string exePath)
{
using var memoryStream = new MemoryStream();
using var stdoutWriter = new StreamWriter(memoryStream);

var exitCode = CommandUtility.RunCommand(new CommandInfo { Name = exePath, Arguments = "--version" }, stdoutWriter);

if (exitCode != 0)
return "";

stdoutWriter.Flush();
memoryStream.Position = 0;

using var streamReader = new StreamReader(memoryStream);
return streamReader.ReadLine() ?? "";
}
}
5 changes: 5 additions & 0 deletions src/Docfx.App/PdfBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ class Outline
public string? pdfFooterTemplate { get; init; }
}

static PdfBuilder()
{
PlaywrightHelper.EnsurePlaywrightNodeJsPath();
}

public static Task Run(BuildJsonConfig config, string configDirectory, string? outputDirectory = null)
{
var outputFolder = Path.GetFullPath(Path.Combine(
Expand Down
1 change: 1 addition & 0 deletions test/docfx.Snapshot.Tests/PercyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public PercyFactAttribute()

static PercyTest()
{
PlaywrightHelper.EnsurePlaywrightNodeJsPath();
Microsoft.Playwright.Program.Main(["install", "chromium"]);
}

Expand Down

0 comments on commit b40f492

Please sign in to comment.