Skip to content
Merged
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
30 changes: 26 additions & 4 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ stages:
git config --global core.autocrlf true
displayName: Setup git identity

- template: azure-pipelines-templates/install-nbgv-tool.yml@templates

# waiting for project to be public to enable SonarCloud analysis
# - task: SonarCloudPrepare@3
# condition: >-
Expand Down Expand Up @@ -173,6 +171,7 @@ stages:

- task: DotNetCoreCLI@2
displayName: Pack
condition: succeeded()
inputs:
command: 'pack'
packagesToPack: '**/nanoFramework.NET.Sdk.csproj'
Expand Down Expand Up @@ -228,7 +227,14 @@ stages:
throw "Couldn't infer SDK version from package '$($sdkPackage.Name)'."
}

$sdkVersion = $match.Groups[1].Value
# Use the nbgv CLI to get the authoritative NuGet package version.
$sdkVersion = (& nbgv get-version --public-release -v NuGetPackageVersion).Trim()

if ([string]::IsNullOrWhiteSpace($sdkVersion))
{
throw "Couldn't determine SDK version via 'nbgv get-version'."
}

Write-Host "Using SmokeTest SDK package: $($sdkPackage.Name)"
Write-Host "Using SmokeTest SDK version: $sdkVersion"

Expand Down Expand Up @@ -271,12 +277,21 @@ stages:
nugetConfigPath: '$(Build.SourcesDirectory)/test/SmokeTest/NuGet.Azdo.Config'

- task: DotNetCoreCLI@2
displayName: Build SmokeTest
displayName: Build SmokeTest (dotnet build)
inputs:
command: 'build'
projects: 'test/SmokeTest/SmokeTest.csproj'
arguments: '--configuration $(buildConfiguration) --no-restore'

- task: VSBuild@1
displayName: Build SmokeTest (MSBuild)
inputs:
solution: 'test/SmokeTest/SmokeTest.csproj'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
vsVersion: 'latest'
msbuildArgs: '/t:Build /p:Restore=false'

- task: PowerShell@2
displayName: Validate SmokeTest native checksum
inputs:
Expand All @@ -292,6 +307,13 @@ stages:
}

Write-Host "Smoke test assembly checksum matches expected value: $expectedChecksum."

- task: PowerShell@2
displayName: Validate SmokeTest resource parity
inputs:
targetType: filePath
filePath: 'test/SmokeTest/Verify-Parity.ps1'
arguments: '-Configuration $(buildConfiguration)'

- task: NuGetCommand@2
condition: >-
Expand Down
146 changes: 146 additions & 0 deletions test/SmokeTest/Verify-Parity.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
[CmdletBinding()]
param(
[string]$Project = '',
[ValidateSet('Debug', 'Release')]
[string]$Configuration = 'Debug'
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

function Find-MSBuild {
$command = Get-Command msbuild.exe -ErrorAction SilentlyContinue
if ($null -ne $command) {
return $command.Source
}

$programFilesX86 = [Environment]::GetFolderPath('ProgramFilesX86')
$vswhere = Join-Path $programFilesX86 'Microsoft Visual Studio\Installer\vswhere.exe'
if (-not (Test-Path -LiteralPath $vswhere)) {
throw "Unable to locate msbuild.exe. Install Visual Studio Build Tools, or run from a Developer PowerShell where msbuild.exe is on PATH."
}

$msbuildPath = & $vswhere -latest -products * -requires Microsoft.Component.MSBuild -find 'MSBuild\**\Bin\MSBuild.exe' | Select-Object -First 1
if ([string]::IsNullOrWhiteSpace($msbuildPath)) {
throw "Unable to locate msbuild.exe with vswhere. Install Visual Studio Build Tools, or run from a Developer PowerShell where msbuild.exe is on PATH."
}

return $msbuildPath
}

if ([string]::IsNullOrWhiteSpace($Project)) {
$scriptPath = $PSCommandPath
if ([string]::IsNullOrWhiteSpace($scriptPath)) {
$scriptPath = $MyInvocation.MyCommand.Path
}
if ([string]::IsNullOrWhiteSpace($scriptPath)) {
throw 'Unable to resolve script path. Pass -Project explicitly.'
}

$scriptDirectory = Split-Path -Parent $scriptPath
$Project = Join-Path $scriptDirectory 'SmokeTest.csproj'
}

if (-not (Test-Path -LiteralPath $Project)) {
throw "Project not found: $Project"
}

function Build-And-CaptureNanoResources {
param(
[Parameter(Mandatory = $true)]
[ValidateSet('dotnet', 'msbuild')]
[string]$Toolchain,
[Parameter(Mandatory = $true)]
[string]$ProjectPath,
[Parameter(Mandatory = $true)]
[string]$BuildConfiguration,
[Parameter(Mandatory = $true)]
[string]$CaptureDirectory,
[string]$MSBuildPath
)

$projectDirectory = Split-Path -Parent $ProjectPath
$resourceDirectory = Join-Path $projectDirectory "obj\$BuildConfiguration\netnano1.0"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

if (Test-Path -LiteralPath $resourceDirectory) {
Get-ChildItem -LiteralPath $resourceDirectory -Filter '*.nanoresources' -File | Remove-Item -Force
}

if ($Toolchain -eq 'dotnet') {
& dotnet build $ProjectPath -c $BuildConfiguration /nologo /v:minimal
$exitCode = $LASTEXITCODE
}
else {
& $MSBuildPath $ProjectPath /t:Build /p:Configuration=$BuildConfiguration /nologo /verbosity:minimal
$exitCode = $LASTEXITCODE
}

if (-not (Test-Path -LiteralPath $resourceDirectory)) {
throw "Expected intermediate output directory was not produced: $resourceDirectory"
}

$resourceFiles = @(Get-ChildItem -LiteralPath $resourceDirectory -Filter '*.nanoresources' -File)
if ($exitCode -ne 0) {
throw "$Toolchain build failed with exit code $exitCode."
}

if ($resourceFiles.Count -eq 0) {
throw "No .nanoresources files were produced under: $resourceDirectory"
}

foreach ($file in $resourceFiles) {
Copy-Item -LiteralPath $file.FullName -Destination (Join-Path $CaptureDirectory $file.Name) -Force
}
}

$resolvedProject = (Resolve-Path -LiteralPath $Project).Path
$msbuild = Find-MSBuild
$tempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("nf-smoketest-parity-" + [Guid]::NewGuid().ToString('N'))
$null = New-Item -ItemType Directory -Path $tempRoot -Force

try {
$coreCapture = Join-Path $tempRoot 'net8.0'
$frameworkCapture = Join-Path $tempRoot 'net472'
$null = New-Item -ItemType Directory -Path $coreCapture -Force
$null = New-Item -ItemType Directory -Path $frameworkCapture -Force

Build-And-CaptureNanoResources -Toolchain dotnet -ProjectPath $resolvedProject -BuildConfiguration $Configuration -CaptureDirectory $coreCapture
Build-And-CaptureNanoResources -Toolchain msbuild -ProjectPath $resolvedProject -BuildConfiguration $Configuration -CaptureDirectory $frameworkCapture -MSBuildPath $msbuild

$coreFiles = Get-ChildItem -LiteralPath $coreCapture -Filter '*.nanoresources' -File | Sort-Object -Property Name
$frameworkFiles = Get-ChildItem -LiteralPath $frameworkCapture -Filter '*.nanoresources' -File | Sort-Object -Property Name

$coreNames = @($coreFiles.Name)
$frameworkNames = @($frameworkFiles.Name)
if (@(Compare-Object -ReferenceObject $coreNames -DifferenceObject $frameworkNames).Count -ne 0) {
throw "Parity check failed: generated .nanoresources file sets differ.`nnet8.0 : $($coreNames -join ', ')`nnet472 : $($frameworkNames -join ', ')"
}

$mismatches = @()
foreach ($name in $coreNames) {
$corePath = Join-Path $coreCapture $name
$frameworkPath = Join-Path $frameworkCapture $name

$coreHash = Get-FileHash -LiteralPath $corePath -Algorithm SHA256
$frameworkHash = Get-FileHash -LiteralPath $frameworkPath -Algorithm SHA256

Write-Host "$name"
Write-Host " net8.0: $($coreHash.Hash)"
Write-Host " net472: $($frameworkHash.Hash)"

if ($coreHash.Hash -ne $frameworkHash.Hash) {
$mismatches += $name
}
}

if ($mismatches.Count -gt 0) {
throw "Parity check failed: hash mismatch in .nanoresources files: $($mismatches -join ', ')"
}

Write-Host 'Parity check passed: all .nanoresources files are byte-identical for net8.0 and net472.'
}
finally {
if (Test-Path -LiteralPath $tempRoot) {
Remove-Item -LiteralPath $tempRoot -Recurse -Force
}
}