Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/Runner.Plugins/Repository/v1.0/RepositoryPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ namespace GitHub.Runner.Plugins.Repository.v1_0
{
public class CheckoutTask : IRunnerActionPlugin
{
private readonly Regex _validSha1 = new(@"\b[0-9a-f]{40}\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled, TimeSpan.FromSeconds(2));

public async Task RunAsync(RunnerActionPluginExecutionContext executionContext, CancellationToken token)
{
string runnerWorkspace = executionContext.GetRunnerContext("workspace");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public static class WellKnownRegularExpressions
public const String Email = nameof(Email);
public const String IPv4Address = nameof(IPv4Address);
public const String SHA1 = nameof(SHA1);
public const String CommitHash = nameof(CommitHash);
public const String Url = nameof(Url);

/// <summary>
Expand All @@ -24,7 +25,8 @@ public static Lazy<Regex> GetRegex(String regexType)
case IPv4Address:
return s_validIPv4Address;
case SHA1:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to remove the SHA1 and update all the caller to use the CommitHash?

return s_validSha1;
case CommitHash:
return s_validCommitHash;
case Url:
return s_validUrl;
default:
Expand All @@ -46,9 +48,9 @@ public static Lazy<Regex> GetRegex(String regexType)
)
);

// 40 hex characters
private static readonly Lazy<Regex> s_validSha1 = new Lazy<Regex>(() => new Regex(
@"\b[0-9a-f]{40}\b",
// 40 or 64 hex characters (SHA-1 or SHA-256 commit hash)
private static readonly Lazy<Regex> s_validCommitHash = new Lazy<Regex>(() => new Regex(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex change looks correct, but WellKnownRegularExpressions currently has no dedicated unit tests.

Would be good if we could add a test class (e.g. src/Test/L0/Sdk/WellKnownRegularExpressionsL0.cs alongside the existing ExpressionParserL0.cs) with these minimum:

  • 40-char hex → matches (regression guard)
  • 64-char hex → matches (the new case this PR adds)
  • 63-char and 65-char hex → do NOT match (boundary)
  • Mixed-case 64-char → matches (IgnoreCase still works)

Would be good to avoid a regression in the future, in-case a future change breaks 64-char support to avoid it going undetected since nothing in CI directly tests it.

@"\b(?:[0-9a-f]{40}|[0-9a-f]{64})\b",
RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled, RegexUtility.GetRegexTimeOut()
)
);
Expand Down
100 changes: 100 additions & 0 deletions src/Test/L0/Sdk/WellKnownRegularExpressionsL0.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using GitHub.DistributedTask.Pipelines.Expressions;
using Xunit;

namespace GitHub.Runner.Common.Tests.Sdk
{
public sealed class WellKnownRegularExpressionsL0
{
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void SHA1_Key_Returns_CommitHash_Regex()
{
var regex = WellKnownRegularExpressions.GetRegex(WellKnownRegularExpressions.SHA1);

Assert.NotNull(regex);
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void CommitHash_Key_Returns_CommitHash_Regex()
{
var regex = WellKnownRegularExpressions.GetRegex(WellKnownRegularExpressions.CommitHash);

Assert.NotNull(regex);
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void SHA1_And_CommitHash_Return_Same_Regex()
{
var sha1Regex = WellKnownRegularExpressions.GetRegex(WellKnownRegularExpressions.SHA1);
var commitHashRegex = WellKnownRegularExpressions.GetRegex(WellKnownRegularExpressions.CommitHash);

Assert.Same(sha1Regex, commitHashRegex);
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void Matches_40_Char_Hex()
{
var regex = WellKnownRegularExpressions.GetRegex(WellKnownRegularExpressions.CommitHash);

Assert.Matches(regex.Value, new string((char)97, 40));
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void Matches_64_Char_Hex()
{
var regex = WellKnownRegularExpressions.GetRegex(WellKnownRegularExpressions.CommitHash);

Assert.Matches(regex.Value, new string((char)97, 64));
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void Does_Not_Match_63_Char_Hex()
{
var regex = WellKnownRegularExpressions.GetRegex(WellKnownRegularExpressions.CommitHash);

Assert.DoesNotMatch(regex.Value, new string((char)97, 63));
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void Does_Not_Match_65_Char_Hex()
{
var regex = WellKnownRegularExpressions.GetRegex(WellKnownRegularExpressions.CommitHash);

Assert.DoesNotMatch(regex.Value, new string((char)97, 65));
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void Matches_Mixed_Case_64_Char()
{
var regex = WellKnownRegularExpressions.GetRegex(WellKnownRegularExpressions.CommitHash);
var value = new string((char)65, 32) + new string((char)98, 32);

Assert.Matches(regex.Value, value);
}

[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Sdk")]
public void Unknown_Key_Returns_Null()
{
var regex = WellKnownRegularExpressions.GetRegex("UnknownType");

Assert.Null(regex);
}
}
}
Loading