Skip to content

Commit 9f57b42

Browse files
mitchdennyCopilot
andcommitted
Fix Playwright CLI provenance verification for tag format change
@playwright/cli 0.1.7 changed their git tag naming convention from 'v0.1.7' to '0.1.7' (dropped the 'v' prefix). This caused our provenance verification to fail with WorkflowRefMismatch. - Bump minimum version from >=0.1.3 to >=0.1.7 - Update tag validation to expect tags without the 'v' prefix - Add test to verify the callback accepts the new tag format Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 442d45d commit 9f57b42

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

src/Aspire.Cli/Agents/Playwright/PlaywrightCliInstaller.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ internal sealed class PlaywrightCliInstaller(
5454
internal const string PackageName = "@playwright/cli";
5555

5656
/// <summary>
57-
/// The version range to resolve. Accepts any version from 0.1.3 onwards.
57+
/// The version range to resolve. Accepts any version from 0.1.7 onwards.
5858
/// </summary>
59-
internal const string VersionRange = ">=0.1.3";
59+
internal const string VersionRange = ">=0.1.7";
6060

6161
/// <summary>
6262
/// The expected source repository for provenance verification.
@@ -185,7 +185,7 @@ internal sealed class PlaywrightCliInstaller(
185185
ExpectedWorkflowPath,
186186
ExpectedBuildType,
187187
refInfo => string.Equals(refInfo.Kind, "tags", StringComparison.Ordinal) &&
188-
string.Equals(refInfo.Name, $"v{packageInfo.Version}", StringComparison.Ordinal),
188+
string.Equals(refInfo.Name, $"{packageInfo.Version}", StringComparison.Ordinal),
189189
cancellationToken,
190190
sriIntegrity: packageInfo.Integrity);
191191

tests/Aspire.Cli.Tests/Agents/PlaywrightCliInstallerTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,41 @@ public void VerifyIntegrity_WithNonSha512Prefix_ReturnsFalse()
429429
}
430430
}
431431

432+
[Fact]
433+
public async Task InstallAsync_WorkflowRefValidator_AcceptsTagWithoutVPrefix()
434+
{
435+
var tempDir = CreateTestRepoRoot();
436+
437+
try
438+
{
439+
var version = SemVersion.Parse("0.1.7", SemVersionStyles.Strict);
440+
var npmRunner = new TestNpmRunner
441+
{
442+
ResolveResult = new NpmPackageInfo { Version = version, Integrity = "sha512-abc123" }
443+
};
444+
var provenanceChecker = new TestNpmProvenanceChecker();
445+
var playwrightRunner = new TestPlaywrightCliRunner();
446+
var installer = new PlaywrightCliInstaller(npmRunner, provenanceChecker, playwrightRunner, new TestInteractionService(), new ConfigurationBuilder().Build(), NullLogger<PlaywrightCliInstaller>.Instance);
447+
448+
await installer.InstallAsync(tempDir, s_emptySkillDirs, CancellationToken.None);
449+
450+
Assert.True(provenanceChecker.ProvenanceCalled);
451+
Assert.NotNull(provenanceChecker.CapturedValidateWorkflowRef);
452+
453+
// The Playwright team dropped the 'v' prefix from tags starting with 0.1.7.
454+
// Verify the callback accepts the new format (e.g., "0.1.7" not "v0.1.7").
455+
Assert.True(WorkflowRefInfo.TryParse($"refs/tags/{version}", out var refInfo));
456+
Assert.True(provenanceChecker.CapturedValidateWorkflowRef(refInfo!));
457+
}
458+
finally
459+
{
460+
if (Directory.Exists(tempDir))
461+
{
462+
Directory.Delete(tempDir, recursive: true);
463+
}
464+
}
465+
}
466+
432467
[Fact]
433468
public async Task InstallAsync_WhenProvenanceCheckFails_ReturnsErrorMessage()
434469
{
@@ -997,10 +1032,12 @@ private sealed class TestNpmProvenanceChecker : INpmProvenanceChecker
9971032
{
9981033
public ProvenanceVerificationOutcome ProvenanceOutcome { get; set; } = ProvenanceVerificationOutcome.Verified;
9991034
public bool ProvenanceCalled { get; private set; }
1035+
public Func<WorkflowRefInfo, bool>? CapturedValidateWorkflowRef { get; private set; }
10001036

10011037
public Task<ProvenanceVerificationResult> VerifyProvenanceAsync(string packageName, string version, string expectedSourceRepository, string expectedWorkflowPath, string expectedBuildType, Func<WorkflowRefInfo, bool>? validateWorkflowRef, CancellationToken cancellationToken, string? sriIntegrity = null)
10021038
{
10031039
ProvenanceCalled = true;
1040+
CapturedValidateWorkflowRef = validateWorkflowRef;
10041041
return Task.FromResult(new ProvenanceVerificationResult
10051042
{
10061043
Outcome = ProvenanceOutcome,

0 commit comments

Comments
 (0)