build/Update-MsalDependency.ps1
|
<#
.SYNOPSIS Pins the MSAL.NET dependency closure in Data/MsalDependency.psd1, then restores lib/. .DESCRIPTION Runs "dotnet restore" on build/MsalDependency.csproj into a temporary folder (no compilation), reads the resolved closure from project.assets.json, and writes, for every package of the net472 and net8.0 closures, its version, the SHA-512 of its .nupkg as nuget.org publishes it, and the SHA-256 of every file Posh-MSAL takes from it. Then runs Restore-MsalDependency.ps1, which downloads the packages again and checks them against these pins. Needs the .NET SDK 8 or later. Run it only to change the bundled MSAL.NET version. .EXAMPLE PS C:\>./build/Update-MsalDependency.ps1 #> [CmdletBinding()] param ( # Native broker runtimes to bundle: the broker is used on Windows only for now (linux-x64 alone # weighs 40 MB, and macOS is not supported). [string[]] $RuntimeIdentifier = @('win-x64', 'win-x86', 'win-arm64') ) Set-StrictMode -Version 3.0 $ErrorActionPreference = 'Stop' $RepositoryRoot = Split-Path -Parent $PSScriptRoot $ProjectPath = Join-Path $PSScriptRoot 'MsalDependency.csproj' $DataPath = Join-Path (Join-Path $RepositoryRoot 'Data') 'MsalDependency.psd1' # Target framework folder => the names project.assets.json may key it by (format 4 uses the short one). $TargetFrameworks = [ordered]@{ 'net472' = @('net472', '.NETFramework,Version=v4.7.2'); 'net8.0' = @('net8.0', '.NETCoreApp,Version=v8.0') } $WorkFolder = Join-Path ([System.IO.Path]::GetTempPath()) ('posh-msal-update-' + [guid]::NewGuid().Guid.Substring(0, 8)) $PackagesFolder = Join-Path $WorkFolder 'packages' $ObjFolder = Join-Path $WorkFolder 'obj' [void] (New-Item -ItemType Directory -Path $PackagesFolder, $ObjFolder) try { & dotnet restore $ProjectPath --packages $PackagesFolder "-p:BaseIntermediateOutputPath=$ObjFolder$([System.IO.Path]::DirectorySeparatorChar)" --nologo if ($LASTEXITCODE -ne 0) { throw "dotnet restore failed with exit code $LASTEXITCODE." } $Assets = Get-Content -LiteralPath (Join-Path $ObjFolder 'project.assets.json') -Raw | ConvertFrom-Json # .NET 8 ships some of these assemblies itself, in a newer version: the SDK drops the package's # copy, and so does this script (loading ours next to the framework's would be a conflict). $FrameworkAssemblies = @{} $FrameworkList = Get-ChildItem -Path (Join-Path $PackagesFolder 'microsoft.netcore.app.ref') -Filter 'FrameworkList.xml' -Recurse | Select-Object -First 1 if (-not $FrameworkList) { throw 'Microsoft.NETCore.App.Ref was not restored: cannot tell which assemblies .NET 8 provides.' } foreach ($Match in (Select-String -LiteralPath $FrameworkList.FullName -Pattern 'Type="Managed"[^>]*AssemblyName="([^"]+)"[^>]*AssemblyVersion="([^"]+)"')) { $FrameworkAssemblies[$Match.Matches[0].Groups[1].Value] = [version] $Match.Matches[0].Groups[2].Value } $Packages = [ordered]@{} foreach ($Tfm in $TargetFrameworks.Keys) { $Target = $Assets.targets.psobject.Properties | Where-Object { $TargetFrameworks[$Tfm] -contains $_.Name } | Select-Object -First 1 if (-not $Target) { throw "No $Tfm target in project.assets.json." } # Windows PowerShell only runs on Windows: its build takes the Windows broker runtimes only. $Rids = if ($Tfm -eq 'net472') { @($RuntimeIdentifier -like 'win-*') } else { $RuntimeIdentifier } foreach ($Library in $Target.Value.psobject.Properties) { if ($Library.Value.type -ne 'package') { continue } $Id, $Version = $Library.Name -split '/', 2 $PackageFolder = Join-Path (Join-Path $PackagesFolder $Id.ToLowerInvariant()) $Version.ToLowerInvariant() if (-not $Packages.Contains($Library.Name)) { $Packages[$Library.Name] = [ordered]@{ Id = $Id Version = $Version # The hash of the .nupkg bytes as served. project.assets.json holds NuGet's content # hash instead, which leaves out the repository signature and matches no download. Sha512 = (Get-Content -LiteralPath (Join-Path $PackageFolder ('{0}.{1}.nupkg.sha512' -f $Id.ToLowerInvariant(), $Version.ToLowerInvariant())) -Raw).Trim() Files = New-Object System.Collections.Generic.List[object] } } $Picked = @() if ($Library.Value.psobject.Properties['runtime']) { foreach ($Source in $Library.Value.runtime.psobject.Properties.Name) { if ($Source -like '*/_._') { continue } if ($Tfm -eq 'net8.0') { $AssemblyName = [System.Reflection.AssemblyName]::GetAssemblyName((Join-Path $PackageFolder $Source)) if ($FrameworkAssemblies.ContainsKey($AssemblyName.Name) -and $FrameworkAssemblies[$AssemblyName.Name] -ge $AssemblyName.Version) { Write-Verbose ('{0}: skipped, .NET 8 provides {1}.' -f $Source, $FrameworkAssemblies[$AssemblyName.Name]) continue } } $Picked += , @($Source, ('{0}/{1}' -f $Tfm, ($Source -split '/')[-1])) } } if ($Library.Value.psobject.Properties['runtimeTargets']) { foreach ($RuntimeTarget in $Library.Value.runtimeTargets.psobject.Properties) { # Only native broker runtimes: RID-specific managed assets are not used by the loader. if ($RuntimeTarget.Value.assetType -eq 'native' -and $Rids -contains $RuntimeTarget.Value.rid) { $Picked += , @($RuntimeTarget.Name, ('{0}/runtimes/{1}/native/{2}' -f $Tfm, $RuntimeTarget.Value.rid, ($RuntimeTarget.Name -split '/')[-1])) } } } foreach ($Asset in $Picked) { $SourceFile = Join-Path $PackageFolder $Asset[0] $Packages[$Library.Name].Files.Add([ordered]@{ Source = $Asset[0] Target = $Asset[1] Sha256 = (Get-FileHash -LiteralPath $SourceFile -Algorithm SHA256).Hash }) } } } $Lines = New-Object System.Collections.Generic.List[string] $Lines.Add('# Generated by build/Update-MsalDependency.ps1 from build/MsalDependency.csproj. Do not edit by hand.') $Lines.Add('# Restore-MsalDependency.ps1 rebuilds lib/ from these pins; Tests/Dependency.Tests.ps1 checks lib/ against them.') $Lines.Add('@{') $Lines.Add(' Packages = @(') foreach ($Package in $Packages.Values | Sort-Object { $_.Id }) { if ($Package.Files.Count -eq 0) { continue } $Lines.Add(' @{') $Lines.Add((" Id = '{0}'" -f $Package.Id)) $Lines.Add((" Version = '{0}'" -f $Package.Version)) $Lines.Add((" Sha512 = '{0}'" -f $Package.Sha512)) $Lines.Add(' Files = @(') foreach ($File in $Package.Files | Sort-Object { $_.Target }) { $Lines.Add((" @{{ Source = '{0}'; Target = '{1}'; Sha256 = '{2}' }}" -f $File.Source, $File.Target, $File.Sha256)) } $Lines.Add(' )') $Lines.Add(' }') } $Lines.Add(' )') $Lines.Add('}') [void] (New-Item -ItemType Directory -Path (Split-Path -Parent $DataPath) -Force) [System.IO.File]::WriteAllLines($DataPath, $Lines) Write-Verbose "Pins written to $DataPath." -Verbose } finally { Remove-Item -LiteralPath $WorkFolder -Recurse -Force -ErrorAction SilentlyContinue } & (Join-Path $PSScriptRoot 'Restore-MsalDependency.ps1') |