Skip to content

Commit

Permalink
chore: Add snapshot tests support that are executed on forked reposit…
Browse files Browse the repository at this point in the history
…ory (#9759)

* chore: Add snapshot tests support that are executed on forked repository

* chore: Add docs for DOCFX_SOURCE_REPOSITORY

* chore: change env variable name from DOCFX_SOURCE_REPOSITORY to DOCFX_SOURCE_REPOSITORY_URL

---------

Co-authored-by: Yufei Huang <yufeih@live.com>
  • Loading branch information
filzrev and yufeih committed Apr 1, 2024
1 parent aa982be commit a470aa5
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 4 deletions.
5 changes: 5 additions & 0 deletions docs/reference/docfx-environment-variables-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ If set true. Keep following debug info in output HTML.

Used to override git branch name.

## `DOCFX_SOURCE_REPOSITORY_URL`

Used to override git organization and repository names.
It must be defined in the `https://{host_name}/{organization}/{repository_name}` format (e.g.`https://github.com/dotnet/docfx`).

## `DOCFX_NO_CHECK_CERTIFICATE_REVOCATION_LIST`

Used to disable CRL check.
Expand Down
57 changes: 54 additions & 3 deletions src/Docfx.Common/Git/GitUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ record Repo(string path, string url, string branch);
if (repo is null)
return null;

var repoUrl = ResolveDocfxSourceRepoUrl(repo.url);

return new()
{
Repo = repo.url,
Repo = repoUrl,
Branch = repo.branch,
Path = Path.GetRelativePath(repo.path, filePath).Replace('\\', '/'),
};
Expand All @@ -49,10 +51,12 @@ record Repo(string path, string url, string branch);
public static string? RawContentUrlToContentUrl(string rawUrl)
{
// GitHub
return Regex.Replace(
var url = Regex.Replace(
rawUrl,
@"^https://raw\.githubusercontent\.com/([^/]+)/([^/]+)/([^/]+)/(.+)$",
string.IsNullOrEmpty(s_branch) ? "https://github.com/$1/$2/blob/$3/$4" : $"https://github.com/$1/$2/blob/{s_branch}/$4");

return ResolveDocfxSourceRepoUrl(url);
}

public static string? GetSourceUrl(GitSource source)
Expand All @@ -65,7 +69,7 @@ record Repo(string path, string url, string branch);

var path = source.Path.Replace('\\', '/');

return url.Host switch
var sourceUrl = url.Host switch
{
"github.com" => $"https://github.com{url.AbsolutePath}/blob/{source.Branch}/{path}{(source.Line > 0 ? $"#L{source.Line}" : null)}",
"bitbucket.org" => $"https://bitbucket.org{url.AbsolutePath}/src/{source.Branch}/{path}{(source.Line > 0 ? $"#lines-{source.Line}" : null)}",
Expand All @@ -74,6 +78,11 @@ _ when url.Host.EndsWith(".visualstudio.com") || url.Host == "dev.azure.com" =>
_ => null,
};

if (sourceUrl == null)
return null;

return ResolveDocfxSourceRepoUrl(sourceUrl);

static bool IsCommit(string branch)
{
return branch.Length == 40 && branch.All(char.IsLetterOrDigit);
Expand Down Expand Up @@ -173,4 +182,46 @@ static string GitUrlToHttps(string url)
}
}
}

/// <summary>
/// Rewrite path if `DOCFX_SOURCE_REPOSITORY_URL` environment variable is specified.
/// </summary>
private static string ResolveDocfxSourceRepoUrl(string originalUrl)
{
var docfxSourceRepoUrl = Environment.GetEnvironmentVariable("DOCFX_SOURCE_REPOSITORY_URL");
if (docfxSourceRepoUrl == null)
return originalUrl;

if (!Uri.TryCreate(originalUrl, UriKind.Absolute, out var parsedOriginalUrl)
|| !Uri.TryCreate(docfxSourceRepoUrl, UriKind.Absolute, out var parsedOverrideUrl)
|| parsedOriginalUrl.Host != parsedOverrideUrl.Host)
{
return originalUrl;
}

// Parse value that defined with `{orgName}/{repoName}` format.
var parts = parsedOverrideUrl.LocalPath.Split('/', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (parts.Length < 2)
return originalUrl;

string orgName = parts[0];
string repoName = parts[1];

switch (parsedOriginalUrl.Host)
{
case "github.com":
case "bitbucket.org":
case "dev.azure.com":
{
// Replace `/{orgName}/{repoName}` and remove `.git` suffix.
var builder = new UriBuilder(parsedOriginalUrl);
builder.Path = Regex.Replace(builder.Path.TrimEnd(".git"), @"^/[^/]+/[^/]+", $"/{orgName}/{repoName}");
return builder.Uri.ToString();
}

// Currently other URL formats are not supported (e.g. visualstudio.com, GitHub Enterprise Server)
default:
return originalUrl;
}
}
}
64 changes: 64 additions & 0 deletions test/Docfx.Common.Tests/GitUtilityWithSourceRepoUrlTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Docfx.Common.Git;
using Xunit;

namespace Docfx.Common.Tests;

[Collection("docfx STA")]
public class GitUtilityWithSourceRepositoryUrlTest : IDisposable
{
private readonly string _originalBranchName;
private readonly string _originalSourceRepoUrl;

private const string ORG_NAME = "dotnet";
private const string REPO_NAME = "docfx";

private const string BRANCH_NAME = "special-branch";
private const string DOCFX_SOURCE_BRANCH_NAME = nameof(DOCFX_SOURCE_BRANCH_NAME);
private const string DOCFX_SOURCE_REPOSITORY_URL = nameof(DOCFX_SOURCE_REPOSITORY_URL);

public GitUtilityWithSourceRepositoryUrlTest()
{
_originalBranchName = Environment.GetEnvironmentVariable(DOCFX_SOURCE_BRANCH_NAME);
_originalSourceRepoUrl = Environment.GetEnvironmentVariable(DOCFX_SOURCE_REPOSITORY_URL);

Environment.SetEnvironmentVariable(DOCFX_SOURCE_BRANCH_NAME, BRANCH_NAME);
Environment.SetEnvironmentVariable(DOCFX_SOURCE_REPOSITORY_URL, $"https://github.com/{ORG_NAME}/{REPO_NAME}");
}

public void Dispose()
{
Environment.SetEnvironmentVariable(DOCFX_SOURCE_BRANCH_NAME, _originalBranchName);
Environment.SetEnvironmentVariable(DOCFX_SOURCE_REPOSITORY_URL, _originalSourceRepoUrl);
}

[Fact]
public void TryGetFileDetailTest()
{
var info = GitUtility.TryGetFileDetail(Directory.GetCurrentDirectory());
Assert.Equal(BRANCH_NAME, info.Branch);
Assert.Equal("https://github.com/dotnet/docfx", info.Repo);
}

[Fact]
public void RawContentUrlToContentUrlTest()
{
string rawUrl = "https://raw.githubusercontent.com/dotnet/docfx/main/README.md";
string expected = "https://github.com/dotnet/docfx/blob/special-branch/README.md";

var result = GitUtility.RawContentUrlToContentUrl(rawUrl);

Assert.Equal(expected, result);
}

[Theory]
[InlineData("https://github.com/user/repo.git", "main", "path/to/file.cs", 0, $"https://github.com/{ORG_NAME}/{REPO_NAME}/blob/main/path/to/file.cs")]
[InlineData("https://github.com/user/repo.git", "main", "path/to/file.cs", 10, $"https://github.com/{ORG_NAME}/{REPO_NAME}/blob/main/path/to/file.cs#L10")]
[InlineData("git@github.com:user/repo.git", "main", "path/to/file.cs", 0, $"https://github.com/{ORG_NAME}/{REPO_NAME}/blob/main/path/to/file.cs")]
public void GetSourceUrlTest_GitHub(string repo, string branch, string path, int line, string result)
{
Assert.Equal(result, GitUtility.GetSourceUrl(new(repo, branch, path, line)));
}
}
17 changes: 16 additions & 1 deletion test/docfx.Snapshot.Tests/SamplesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,32 @@
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using Docfx.Dotnet;
using Docfx.Plugins;
using UglyToad.PdfPig;
using UglyToad.PdfPig.Actions;
using UglyToad.PdfPig.Annotations;
using UglyToad.PdfPig.Outline;

namespace Docfx.Tests;

public class SamplesTest
[Collection("docfx STA")]
[Trait("Stage", "Snapshot")]
public class SamplesTest : IDisposable
{
private static readonly string s_samplesDir = Path.GetFullPath("../../../../../samples");

private const string DOCFX_SOURCE_REPOSITORY_URL = nameof(DOCFX_SOURCE_REPOSITORY_URL);

public SamplesTest()
{
Environment.SetEnvironmentVariable(DOCFX_SOURCE_REPOSITORY_URL, "https://github.com/dotnet/docfx");
}

public void Dispose()
{
Environment.SetEnvironmentVariable(DOCFX_SOURCE_REPOSITORY_URL, null);
}

private class SamplesFactAttribute : FactAttribute
{
public SamplesFactAttribute()
Expand Down

0 comments on commit a470aa5

Please sign in to comment.