mirror of
https://github.com/microsoft/playwright-dotnet.git
synced 2026-10-17 06:00:51 +08:00
devops(pipeline): resolve NuGet and npm packages from DevDiv_PublicPackages feed (#3352)
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
NuGet configuration used only by the Azure Pipelines release build (publish.yml).
|
||||
|
||||
Routes all package restores through the DevDiv_PublicPackages Azure Artifacts
|
||||
feed instead of nuget.org, as required by SFI-ES4.2.4. The pipeline copies it to
|
||||
the repository root before any dotnet command so every restore discovers it, and
|
||||
NuGetAuthenticate@1 provides the credentials for the feed.
|
||||
-->
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<add key="DevDiv_PublicPackages" value="https://pkgs.dev.azure.com/devdiv/DevDiv/_packaging/DevDiv_PublicPackages/nuget/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
@@ -56,6 +56,17 @@ extends:
|
||||
displayName: 'Publish Artifact'
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)'
|
||||
steps:
|
||||
- powershell: |
|
||||
if ($env:CURRENT_BRANCH -notmatch '^v1\.') {
|
||||
Write-Host "Can only publish from a release tag (v1.*)."
|
||||
Write-Host "Unexpected ref name: $env:CURRENT_BRANCH"
|
||||
exit 1
|
||||
}
|
||||
env:
|
||||
CURRENT_BRANCH: ${{ variables['Build.SourceBranchName'] }}
|
||||
displayName: 'Check the ref is a release tag'
|
||||
# Allow manual runs on any branch to exercise the build without publishing.
|
||||
condition: ne(variables['Build.Reason'], 'Manual')
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Use .NET 8 SDK'
|
||||
inputs:
|
||||
@@ -66,6 +77,29 @@ extends:
|
||||
inputs:
|
||||
packageType: sdk
|
||||
version: 10.x
|
||||
# All NuGet restores go through the DevDiv_PublicPackages feed instead of
|
||||
# nuget.org (SFI-ES4.2.4): the copied nuget.config is discovered from every
|
||||
# project directory and its <clear /> drops the nuget.org source inherited
|
||||
# from the user-level config. NuGetAuthenticate@1 installs the credential
|
||||
# provider that authenticates to the feed.
|
||||
- powershell: Copy-Item .azure-pipelines/nuget.config nuget.config
|
||||
displayName: 'Use DevDiv_PublicPackages as the only NuGet source'
|
||||
- task: NuGetAuthenticate@1
|
||||
displayName: 'Authenticate NuGet to DevDiv_PublicPackages feed'
|
||||
# Playwright.Tooling fetches playwright-core with `npm pack`, which picks up
|
||||
# the registry and credentials from this .npmrc.
|
||||
- task: UseNode@1
|
||||
displayName: 'Install Node.js'
|
||||
inputs:
|
||||
version: '24.x'
|
||||
# Explicit ASCII encoding: Windows PowerShell redirection would write UTF-16,
|
||||
# which npm cannot read.
|
||||
- powershell: Add-Content -Path .npmrc -Encoding Ascii -Value "registry=https://devdiv.pkgs.visualstudio.com/DevDiv/_packaging/DevDiv_PublicPackages/npm/registry/"
|
||||
displayName: 'Point npm registry at DevDiv_PublicPackages feed'
|
||||
- task: npmAuthenticate@0
|
||||
displayName: 'Authenticate npm to DevDiv_PublicPackages feed'
|
||||
inputs:
|
||||
workingFile: .npmrc
|
||||
# We need to download the driver first, so we can build
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Download the driver
|
||||
@@ -98,7 +132,7 @@ extends:
|
||||
displayName: Publish Microsoft.Playwright{NUnit,MSTest,Xunit,TestAdapter}
|
||||
condition: or(
|
||||
eq('${{ parameters.doRelease }}', true),
|
||||
startsWith(variables['Build.SourceBranch'], 'refs/tags/')
|
||||
startsWith(variables['Build.SourceBranch'], 'refs/tags/v1.')
|
||||
)
|
||||
inputs:
|
||||
useDotNetTask: false
|
||||
|
||||
+5
-1
@@ -359,4 +359,8 @@ testCert.cer
|
||||
|
||||
coverage-report/
|
||||
src/Playwright.Tests/coverage.*.xml
|
||||
|
||||
|
||||
# Written by the release pipeline: npm credentials (npmAuthenticate@0) and the
|
||||
# root copy of .azure-pipelines/nuget.config.
|
||||
.npmrc
|
||||
/nuget.config
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
## Building
|
||||
|
||||
```bash
|
||||
./build.sh --download-driver # download the Playwright driver
|
||||
./build.sh --download-driver # download the Playwright driver (needs Node.js/npm on PATH)
|
||||
dotnet build ./src # build the entire solution
|
||||
```
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Formats.Tar;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
@@ -168,7 +169,7 @@ internal class DriverDownloader
|
||||
|
||||
var tasks = new List<Task>
|
||||
{
|
||||
DownloadPlaywrightPackageAsync(client, driversDirectory.FullName),
|
||||
DownloadPlaywrightPackageAsync(driversDirectory.FullName),
|
||||
};
|
||||
foreach (var (platformId, nodeSuffix) in _platforms)
|
||||
{
|
||||
@@ -185,12 +186,60 @@ internal class DriverDownloader
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task DownloadPlaywrightPackageAsync(HttpClient client, string driversDirectory)
|
||||
private static string ResolveNpmExecutable()
|
||||
{
|
||||
string url = $"https://registry.npmjs.org/playwright-core/-/playwright-core-{DriverVersion}.tgz";
|
||||
await WithRetriesAsync(url, async () =>
|
||||
string name = OperatingSystem.IsWindows() ? "npm.cmd" : "npm";
|
||||
// On Windows npm.cmd must be started by its full path: launched by bare name,
|
||||
// the script's %~dp0 expands to the working directory instead of its own
|
||||
// directory and it fails to find node_modules/npm/bin/npm-cli.js.
|
||||
string path = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
||||
foreach (string directory in path.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
using var stream = await GetStreamAsync(client, url).ConfigureAwait(false);
|
||||
string candidate = Path.Combine(directory.Trim('"'), name);
|
||||
if (File.Exists(candidate))
|
||||
{
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private async Task DownloadPlaywrightPackageAsync(string driversDirectory)
|
||||
{
|
||||
// Fetched with `npm pack` rather than a hard-coded registry URL so that the
|
||||
// registry configured for npm (and its credentials) are used, e.g. the
|
||||
// root-level .npmrc the release pipeline writes to point at the internal
|
||||
// Azure Artifacts feed. npm is run from the repository root for that reason.
|
||||
string package = $"playwright-core@{DriverVersion}";
|
||||
string tempDirectory = Directory.CreateTempSubdirectory("playwright-core-").FullName;
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Downloading {package} with npm pack");
|
||||
var startInfo = new ProcessStartInfo(ResolveNpmExecutable())
|
||||
{
|
||||
WorkingDirectory = Path.GetFullPath(BasePath),
|
||||
UseShellExecute = false,
|
||||
};
|
||||
startInfo.ArgumentList.Add("pack");
|
||||
startInfo.ArgumentList.Add(package);
|
||||
startInfo.ArgumentList.Add("--pack-destination");
|
||||
startInfo.ArgumentList.Add(tempDirectory);
|
||||
using (var process = Process.Start(startInfo) ?? throw new Exception("Failed to start npm"))
|
||||
{
|
||||
await process.WaitForExitAsync().ConfigureAwait(false);
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
throw new Exception($"npm pack {package} failed with exit code {process.ExitCode}");
|
||||
}
|
||||
}
|
||||
|
||||
string tgz = Path.Combine(tempDirectory, $"playwright-core-{DriverVersion}.tgz");
|
||||
if (!File.Exists(tgz))
|
||||
{
|
||||
throw new Exception($"npm pack did not produce {tgz}");
|
||||
}
|
||||
|
||||
using var stream = File.OpenRead(tgz);
|
||||
using var gzip = new GZipStream(stream, CompressionMode.Decompress);
|
||||
using var tar = new TarReader(gzip);
|
||||
bool extractedAnything = false;
|
||||
@@ -207,9 +256,13 @@ internal class DriverDownloader
|
||||
}
|
||||
if (!extractedAnything)
|
||||
{
|
||||
throw new Exception($"No files were extracted from {url}");
|
||||
throw new Exception($"No files were extracted from {tgz}");
|
||||
}
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.Delete(tempDirectory, true);
|
||||
}
|
||||
Console.WriteLine($"Extracted playwright-core {DriverVersion}");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user