diff --git a/build.psm1 b/build.psm1 index 4330011863e..a895b2906c9 100644 --- a/build.psm1 +++ b/build.psm1 @@ -2258,7 +2258,7 @@ function Find-Dotnet() { $dotnetCLIInstalledVersion = Get-LatestInstalledSDK Pop-Location - Write-Verbose "dotnetCLIInstalledVersion = $dotnetCLIInstalledVersion; chosenDotNetVersion = $chosenDotNetVersion" + Write-Verbose -Message "Find-DotNet: dotnetCLIInstalledVersion = $dotnetCLIInstalledVersion; chosenDotNetVersion = $chosenDotNetVersion" if ($dotnetCLIInstalledVersion -ne $chosenDotNetVersion) { Write-Warning "The 'dotnet' in the current path can't find SDK version ${dotnetCLIRequiredVersion}, prepending $dotnetPath to PATH." diff --git a/tools/cgmanifest.json b/tools/cgmanifest.json index 15bcbacc172..e8caa3fbdcb 100644 --- a/tools/cgmanifest.json +++ b/tools/cgmanifest.json @@ -685,7 +685,7 @@ "Type": "nuget", "Nuget": { "Name": "StyleCop.Analyzers.Unstable", - "Version": "1.2.0.376" + "Version": "1.2.0.406" } }, "DevelopmentDependency": true diff --git a/tools/packaging/packaging.psd1 b/tools/packaging/packaging.psd1 index 8de303ef45c..e9dec523acd 100644 --- a/tools/packaging/packaging.psd1 +++ b/tools/packaging/packaging.psd1 @@ -15,6 +15,8 @@ 'New-DotnetSdkContainerFxdPackage' 'New-ExePackage' 'New-GlobalToolNupkg' + 'New-ILNugetPackageSource' + 'New-ILNugetPackageFromSource' 'New-ILNugetPackage' 'New-MSIPatch' 'New-PSBuildZip' diff --git a/tools/packaging/packaging.psm1 b/tools/packaging/packaging.psm1 index bca41d3c816..5f389d7c0bd 100644 --- a/tools/packaging/packaging.psm1 +++ b/tools/packaging/packaging.psm1 @@ -1699,6 +1699,9 @@ function New-PdbZipPackage function CreateNugetPlatformFolder { param( + [Parameter(Mandatory = $true)] + [string] $FileName, + [Parameter(Mandatory = $true)] [string] $Platform, @@ -1710,46 +1713,192 @@ function CreateNugetPlatformFolder ) $destPath = New-Item -ItemType Directory -Path (Join-Path $PackageRuntimesFolder "$Platform/lib/$script:netCoreRuntime") - $fullPath = Join-Path $PlatformBinPath $file + $fullPath = Join-Path $PlatformBinPath $FileName if (-not(Test-Path $fullPath)) { throw "File not found: $fullPath" } Copy-Item -Path $fullPath -Destination $destPath - Write-Log "Copied $file to $Platform" + Write-Log "Copied $FileName to $Platform at path: $destPath" } <# .SYNOPSIS -Creates NuGet packages containing linux, osx and Windows runtime assemblies. +Creates a CGManifest file containing package dependencies for specified file. + +.PARAMETER FilePath +File path name of CGManifest file to be created. + +.PARAMETER Dependencies +Array list of dependency tuples: +[tuple[ [tuple[string, string]], [tuple[string, string]] ] []] +["Id", "Microsoft.PowerShell.SecretStore"], ["Version", "1.1.1.0"] +#> +function New-CGManifest +{ + param ( + [parameter(Mandatory = $true)] + [string] $FilePath, + + [parameter(Mandatory = $false)] + [tuple[ [tuple[string, string]], [tuple[string, string]] ] []] $Dependencies + ) + + Write-Verbose -Verbose -Message "Creating CGManifest for SBOM: $Filepath" + + $Registrations = @() + + foreach ($dependency in $Dependencies) { + $component = @{ + Component = @{ + Type = "nuget"; + NuGet = @{ + Name = ($dependency.Item1.Item2); Version = ($dependency.Item2.Item2) + } + }; + DevelopmentDependency = "true" + } + + $Registrations += $component + } + + $manifest = @{ Registrations = $Registrations } + $jsonManifest = $manifest | ConvertTo-Json -Depth 10 + + $jsonManifest | Out-File -FilePath $FilePath +} + +function New-FileDependencies +{ + param ( + [parameter(Mandatory = $true)] + [string] $FileBaseName, + + [parameter(Mandatory = $true)] + [string] $PackageVersion + ) + + # Filed a tracking bug for automating generation of dependecy list: https://github.com/PowerShell/PowerShell/issues/6247 + $deps = [System.Collections.ArrayList]::new() + + switch ($FileBaseName) { + 'Microsoft.Management.Infrastructure.CimCmdlets' { + $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null + } + + 'Microsoft.PowerShell.Commands.Diagnostics' { + $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null + } + + 'Microsoft.PowerShell.Commands.Management' { + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Security'), [tuple]::Create('version', $PackageVersion))) > $null + foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $FileBaseName)) + { + $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null + } + } + + 'Microsoft.PowerShell.Commands.Utility' { + $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null + + foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $FileBaseName)) + { + $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null + } + } + + 'Microsoft.PowerShell.ConsoleHost' { + $deps.Add([tuple]::Create( [tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null + foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $FileBaseName)) + { + $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null + } + } + + 'Microsoft.PowerShell.CoreCLR.Eventing' { + foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $FileBaseName)) + { + $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null + } + } + + 'Microsoft.PowerShell.SDK' { + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Commands.Management'), [tuple]::Create('version', $PackageVersion))) > $null + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Commands.Utility'), [tuple]::Create('version', $PackageVersion))) > $null + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.ConsoleHost'), [tuple]::Create('version', $PackageVersion))) > $null + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Security'), [tuple]::Create('version', $PackageVersion))) > $null + $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null + foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $FileBaseName)) + { + $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null + } + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.WSMan.Management'), [tuple]::Create('version', $PackageVersion))) > $null + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Commands.Diagnostics'), [tuple]::Create('version', $PackageVersion))) > $null + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.Management.Infrastructure.CimCmdlets'), [tuple]::Create('version', $PackageVersion))) > $null + } + + 'Microsoft.PowerShell.Security' { + $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null + } + + 'Microsoft.WSMan.Management' { + $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.WSMan.Runtime'), [tuple]::Create('version', $PackageVersion))) > $null + foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $FileBaseName)) + { + $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null + } + } + + 'Microsoft.WSMan.Runtime' { + ## No dependencies + } + + 'System.Management.Automation' { + $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.CoreCLR.Eventing'), [tuple]::Create('version', $PackageVersion))) > $null + foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $FileBaseName)) + { + $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null + } + } + } + + Write-Output $deps +} + +<# +.SYNOPSIS +Creates nuget package sources for a single provided binary file. .DESCRIPTION -Creates a NuGet package of IL assemblies for unix and windows. -The packages for Microsoft.PowerShell.Commands.Diagnostics, Microsoft.PowerShell.Commands.Management, -Microsoft.PowerShell.Commands.Utility, Microsoft.PowerShell.ConsoleHost, Microsoft.PowerShell.CoreCLR.Eventing, -Microsoft.PowerShell.SDK, Microsoft.PowerShell.Security, Microsoft.WSMan.Management, Microsoft.WSMan.Runtime, -System.Management.Automation are created. +Creates IL assemblies, for a single binary file, to be packaged in a NuGet file. +Includes runtime assemblies for linux and Windows runtime assemblies. + +.PARAMETER FileName +File name of binary to create nuget sources for. .PARAMETER PackagePath -Path where the package will be created. +Path where the package source files will be created. .PARAMETER PackageVersion Version of the created package. .PARAMETER WinFxdBinPath -Path to folder containing Windows framework dependent assemblies. +Path to source folder containing Windows framework dependent assemblies. .PARAMETER LinuxFxdBinPath -Path to folder containing Linux framework dependent assemblies. +Path to source folder containing Linux framework dependent assemblies. .PARAMETER GenAPIToolPath Path to the GenAPI.exe tool. #> -function New-ILNugetPackage +function New-ILNugetPackageSource { [CmdletBinding(SupportsShouldProcess = $true)] - param( + param ( + [Parameter(Mandatory = $true)] + [string] $FileName, [Parameter(Mandatory = $true)] [string] $PackagePath, @@ -1764,12 +1913,20 @@ function New-ILNugetPackage [string] $LinuxFxdBinPath, [Parameter(Mandatory = $true)] - [string] $GenAPIToolPath + [string] $GenAPIToolPath, + + [Parameter(Mandatory = $true)] + [string] $CGManifestPath ) - if (-not $Environment.IsWindows) + if (! $Environment.IsWindows) + { + throw "New-ILNugetPackageSource can be only executed on Windows platform." + } + + if (! $PSCmdlet.ShouldProcess("Create nuget packages at: $PackagePath")) { - throw "New-ILNugetPackage can be only executed on Windows platform." + return } $fileList = @( @@ -1792,191 +1949,166 @@ function New-ILNugetPackage "Microsoft.WSMan.Management.dll", "Microsoft.WSMan.Runtime.dll") - if ($PSCmdlet.ShouldProcess("Create nuget packages at: $PackagePath")) - { - $refBinPath = New-TempFolder - $SnkFilePath = "$RepoRoot\src\signing\visualstudiopublic.snk" + $refBinPath = New-TempFolder + $SnkFilePath = "$RepoRoot\src\signing\visualstudiopublic.snk" - New-ReferenceAssembly -linux64BinPath $LinuxFxdBinPath -RefAssemblyDestinationPath $refBinPath -RefAssemblyVersion $PackageVersion -SnkFilePath $SnkFilePath -GenAPIToolPath $GenAPIToolPath + New-ReferenceAssembly -linux64BinPath $LinuxFxdBinPath -RefAssemblyDestinationPath $refBinPath -RefAssemblyVersion $PackageVersion -SnkFilePath $SnkFilePath -GenAPIToolPath $GenAPIToolPath - foreach ($file in $fileList) - { - $tmpPackageRoot = New-TempFolder - # Remove '.dll' at the end - $fileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($file) - $filePackageFolder = New-Item (Join-Path $tmpPackageRoot $fileBaseName) -ItemType Directory -Force - $packageRuntimesFolder = New-Item (Join-Path $filePackageFolder.FullName 'runtimes') -ItemType Directory + if (! (Test-Path $PackagePath)) { + $null = New-Item -Path $PackagePath -ItemType Directory + } - #region ref - $refFolder = New-Item (Join-Path $filePackageFolder.FullName "ref/$script:netCoreRuntime") -ItemType Directory -Force - CopyReferenceAssemblies -assemblyName $fileBaseName -refBinPath $refBinPath -refNugetPath $refFolder -assemblyFileList $fileList - #endregion ref + # Remove '.dll' at the end + $fileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($FileName) + $filePackageFolder = New-Item (Join-Path $PackagePath $fileBaseName) -ItemType Directory -Force + $packageRuntimesFolder = New-Item (Join-Path $filePackageFolder.FullName 'runtimes') -ItemType Directory - $packageRuntimesFolderPath = $packageRuntimesFolder.FullName + Write-Verbose -Verbose "New-ILNugetPackageSource: Creating package source folder for file: $FileName at: $filePackageFolder" - CreateNugetPlatformFolder -Platform 'win' -PackageRuntimesFolder $packageRuntimesFolderPath -PlatformBinPath $WinFxdBinPath + #region ref + $refFolder = New-Item (Join-Path $filePackageFolder.FullName "ref/$script:netCoreRuntime") -ItemType Directory -Force + CopyReferenceAssemblies -assemblyName $fileBaseName -refBinPath $refBinPath -refNugetPath $refFolder -assemblyFileList $fileList + #endregion ref - if ($linuxExceptionList -notcontains $file ) - { - CreateNugetPlatformFolder -Platform 'unix' -PackageRuntimesFolder $packageRuntimesFolderPath -PlatformBinPath $LinuxFxdBinPath - } + $packageRuntimesFolderPath = $packageRuntimesFolder.FullName - if ($file -eq "Microsoft.PowerShell.SDK.dll") - { - # Copy the '$PSHOME\ref' folder to the NuGet package, so 'dotnet publish' can deploy the 'ref' folder to the publish folder. - # This is to make 'Add-Type' work in application that hosts PowerShell. - - $contentFolder = New-Item (Join-Path $filePackageFolder "contentFiles\any\any") -ItemType Directory -Force - $dotnetRefAsmFolder = Join-Path -Path $WinFxdBinPath -ChildPath "ref" - Copy-Item -Path $dotnetRefAsmFolder -Destination $contentFolder -Recurse -Force - Write-Log "Copied the reference assembly folder to contentFiles for the SDK package" - - # Copy the built-in module folders to the NuGet package, so 'dotnet publish' can deploy those modules to the $pshome module path. - # This is for enabling applications that hosts PowerShell to ship the built-in modules. - - $winBuiltInModules = @( - "CimCmdlets", - "Microsoft.PowerShell.Diagnostics", - "Microsoft.PowerShell.Host", - "Microsoft.PowerShell.Management", - "Microsoft.PowerShell.Security", - "Microsoft.PowerShell.Utility", - "Microsoft.WSMan.Management", - "PSDiagnostics" - ) - - $unixBuiltInModules = @( - "Microsoft.PowerShell.Host", - "Microsoft.PowerShell.Management", - "Microsoft.PowerShell.Security", - "Microsoft.PowerShell.Utility" - ) - - $winModuleFolder = New-Item (Join-Path $contentFolder "runtimes\win\lib\$script:netCoreRuntime\Modules") -ItemType Directory -Force - $unixModuleFolder = New-Item (Join-Path $contentFolder "runtimes\unix\lib\$script:netCoreRuntime\Modules") -ItemType Directory -Force - - foreach ($module in $winBuiltInModules) { - $source = Join-Path $WinFxdBinPath "Modules\$module" - Copy-Item -Path $source -Destination $winModuleFolder -Recurse -Force - } + CreateNugetPlatformFolder -FileName $FileName -Platform 'win' -PackageRuntimesFolder $packageRuntimesFolderPath -PlatformBinPath $WinFxdBinPath - foreach ($module in $unixBuiltInModules) { - $source = Join-Path $LinuxFxdBinPath "Modules\$module" - Copy-Item -Path $source -Destination $unixModuleFolder -Recurse -Force - } + if ($linuxExceptionList -notcontains $FileName ) + { + CreateNugetPlatformFolder -FileName $FileName -Platform 'unix' -PackageRuntimesFolder $packageRuntimesFolderPath -PlatformBinPath $LinuxFxdBinPath + } - Write-Log "Copied the built-in modules to contentFiles for the SDK package" - } + if ($FileName -eq "Microsoft.PowerShell.SDK.dll") + { + # Copy the '$PSHOME\ref' folder to the NuGet package, so 'dotnet publish' can deploy the 'ref' folder to the publish folder. + # This is to make 'Add-Type' work in application that hosts PowerShell. + + $contentFolder = New-Item (Join-Path $filePackageFolder "contentFiles\any\any") -ItemType Directory -Force + $dotnetRefAsmFolder = Join-Path -Path $WinFxdBinPath -ChildPath "ref" + Copy-Item -Path $dotnetRefAsmFolder -Destination $contentFolder -Recurse -Force + Write-Log "Copied the reference assembly folder to contentFiles for the SDK package" + + # Copy the built-in module folders to the NuGet package, so 'dotnet publish' can deploy those modules to the $pshome module path. + # This is for enabling applications that hosts PowerShell to ship the built-in modules. + + $winBuiltInModules = @( + "CimCmdlets", + "Microsoft.PowerShell.Diagnostics", + "Microsoft.PowerShell.Host", + "Microsoft.PowerShell.Management", + "Microsoft.PowerShell.Security", + "Microsoft.PowerShell.Utility", + "Microsoft.WSMan.Management", + "PSDiagnostics" + ) - #region nuspec - # filed a tracking bug for automating generation of dependecy list: https://github.com/PowerShell/PowerShell/issues/6247 - $deps = [System.Collections.ArrayList]::new() + $unixBuiltInModules = @( + "Microsoft.PowerShell.Host", + "Microsoft.PowerShell.Management", + "Microsoft.PowerShell.Security", + "Microsoft.PowerShell.Utility" + ) - switch ($fileBaseName) { - 'Microsoft.Management.Infrastructure.CimCmdlets' { - $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null - } + $winModuleFolder = New-Item (Join-Path $contentFolder "runtimes\win\lib\$script:netCoreRuntime\Modules") -ItemType Directory -Force + $unixModuleFolder = New-Item (Join-Path $contentFolder "runtimes\unix\lib\$script:netCoreRuntime\Modules") -ItemType Directory -Force - 'Microsoft.PowerShell.Commands.Diagnostics' { - $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null - } + foreach ($module in $winBuiltInModules) { + $source = Join-Path $WinFxdBinPath "Modules\$module" + Copy-Item -Path $source -Destination $winModuleFolder -Recurse -Force + } - 'Microsoft.PowerShell.Commands.Management' { - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Security'), [tuple]::Create('version', $PackageVersion))) > $null - foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $fileBaseName)) - { - $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null - } - } + foreach ($module in $unixBuiltInModules) { + $source = Join-Path $LinuxFxdBinPath "Modules\$module" + Copy-Item -Path $source -Destination $unixModuleFolder -Recurse -Force + } - 'Microsoft.PowerShell.Commands.Utility' { - $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null + Write-Log "Copied the built-in modules to contentFiles for the SDK package" + } - foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $fileBaseName)) - { - $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null - } - } + # Create a CGManifest file that lists all dependencies for this package, which is used when creating the SBOM. + if (! (Test-Path -Path $CGManifestPath)) { + $null = New-Item -Path $CGManifestPath -ItemType Directory + } + $deps = New-FileDependencies -FileBaseName $fileBaseName -PackageVersion $PackageVersion + New-CGManifest -FilePath (Join-Path -Path $CGManifestPath -ChildPath "CGManifest.json") -Dependencies $deps - 'Microsoft.PowerShell.ConsoleHost' { - $deps.Add([tuple]::Create( [tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null - foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $fileBaseName)) - { - $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null - } - } + if (Test-Path $refBinPath) { + Remove-Item $refBinPath -Recurse -Force -ErrorAction SilentlyContinue + } +} - 'Microsoft.PowerShell.CoreCLR.Eventing' { - foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $fileBaseName)) - { - $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null - } - } +<# +.SYNOPSIS +Creates a nuget package file from the provided source path. - 'Microsoft.PowerShell.SDK' { - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Commands.Management'), [tuple]::Create('version', $PackageVersion))) > $null - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Commands.Utility'), [tuple]::Create('version', $PackageVersion))) > $null - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.ConsoleHost'), [tuple]::Create('version', $PackageVersion))) > $null - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Security'), [tuple]::Create('version', $PackageVersion))) > $null - $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null - foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $fileBaseName)) - { - $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null - } - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.WSMan.Management'), [tuple]::Create('version', $PackageVersion))) > $null - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.Commands.Diagnostics'), [tuple]::Create('version', $PackageVersion))) > $null - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.Management.Infrastructure.CimCmdlets'), [tuple]::Create('version', $PackageVersion))) > $null - } +.PARAMETER FileName +File name of binary to create nuget package for. - 'Microsoft.PowerShell.Security' { - $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null - } +.PARAMETER PackagePath +Path for the source files and the created NuGet package file. +#> +function New-ILNugetPackageFromSource +{ + [CmdletBinding(SupportsShouldProcess = $true)] + param ( + [Parameter(Mandatory = $true)] + [string] $FileName, - 'Microsoft.WSMan.Management' { - $deps.Add([tuple]::Create([tuple]::Create('id', 'System.Management.Automation'), [tuple]::Create('version', $PackageVersion))) > $null - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.WSMan.Runtime'), [tuple]::Create('version', $PackageVersion))) > $null - foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $fileBaseName)) - { - $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null - } - } + [Parameter(Mandatory = $true)] + [string] $PackageVersion, - 'Microsoft.WSMan.Runtime' { - ## No dependencies - } + [Parameter(Mandatory = $true)] + [string] $PackagePath + ) - 'System.Management.Automation' { - $deps.Add([tuple]::Create([tuple]::Create('id', 'Microsoft.PowerShell.CoreCLR.Eventing'), [tuple]::Create('version', $PackageVersion))) > $null - foreach($packageInfo in (Get-ProjectPackageInformation -ProjectName $fileBaseName)) - { - $deps.Add([tuple]::Create([tuple]::Create('id', $packageInfo.Name), [tuple]::Create('version', $packageInfo.Version))) > $null - } - } - } + if (! $Environment.IsWindows) + { + throw "New-ILNugetPackageFromSource can be only executed on Windows platform." + } - New-NuSpec -PackageId $fileBaseName -PackageVersion $PackageVersion -Dependency $deps -FilePath (Join-Path $filePackageFolder.FullName "$fileBaseName.nuspec") + if (! $PSCmdlet.ShouldProcess("Create nuget package for file $FileName at: $PackagePath")) + { + return + } - # Copy icon file to package - Copy-Item -Path $iconPath -Destination "$($filePackageFolder.Fullname)/$iconFileName" -Verbose + $fileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($FileName) - New-NugetPackage -NuSpecPath $filePackageFolder.FullName -PackageDestinationPath $PackagePath - } + $deps = New-FileDependencies -FileBaseName $fileBaseName -PackageVersion $PackageVersion - if (Test-Path $refBinPath) - { - Remove-Item $refBinPath -Recurse -Force -ErrorAction SilentlyContinue - } + $srcFilePackagePath = Join-Path $PackagePath $fileBaseName - if (Test-Path $tmpPackageRoot) - { - Remove-Item $tmpPackageRoot -Recurse -Force -ErrorAction SilentlyContinue - } + Write-Verbose -Verbose "New-ILNugetPackageFromSource: Creating nuget package for file: $FileName from source path: $srcFilePackagePath" + + if (! (Test-Path $srcFilePackagePath)) { + $msg = "Expected nuget source path $srcFilePackagePath for file $fileBaseName does not exist." + Write-Verbose -Verbose -Message $msg + throw $msg } + + # Remove the CGManifest file used to create the SBOM. + $cgManifestPath = Join-Path -Path $PackagePath -ChildPath 'CGManifest' + $cgManifestFilePath = Join-Path -Path $cgManifestPath -ChildPath 'CGManifest.json' + if (Test-Path -Path $cgManifestFilePath) + { + Write-Verbose -Verbose "Removing CGManifest file: $cgManifestFilePath" + Remove-Item -Path $cgManifestFilePath -Force -ErrorAction Continue + } + + New-NuSpec -PackageId $fileBaseName -PackageVersion $PackageVersion -Dependency $deps -FilePath (Join-Path $srcFilePackagePath "$fileBaseName.nuspec") + + # Copy icon file to package + Copy-Item -Path $iconPath -Destination "$srcFilePackagePath/$iconFileName" -Verbose + + New-NugetPackage -NuSpecPath $srcFilePackagePath -PackageDestinationPath $PackagePath + + # Remove file nuget package source directory + Remove-Item $srcFilePackagePath -Recurse -Force -ErrorAction SilentlyContinue } <# Copy the generated reference assemblies to the 'ref/net6.0' folder properly. - This is a helper function used by 'New-ILNugetPackage' + This is a helper function used by 'New-ILNugetPackageSource'. #> function CopyReferenceAssemblies { @@ -2081,7 +2213,7 @@ function New-NuSpec { [Parameter(Mandatory = $false)] # An array of tuples of tuples to define the dependencies. # First tuple defines 'id' and value eg: ["id", "System.Data.SqlClient"] - # Second tuple defines 'version' and vale eg: ["version", "4.4.2"] + # Second tuple defines 'version' and value eg: ["version", "4.4.2"] # Both these tuples combined together define one dependency. # An array represents all the dependencies. [tuple[ [tuple[string, string]], [tuple[string, string]] ] []] $Dependency, @@ -2183,6 +2315,9 @@ function New-ReferenceAssembly "Microsoft.PowerShell.ConsoleHost" ) + # Ensure needed dotNet version is available. Find-DotNet does this, and is part of build.psm1 which should already be imported. + Find-DotNet -Verbose + foreach ($assemblyName in $assemblyNames) { Write-Log "Building reference assembly for '$assemblyName'" @@ -2428,7 +2563,7 @@ function GenerateBuildArguments Create a NuGet package from a nuspec. .DESCRIPTION -Creates a NuGet using the nuspec using at the specified folder. +Creates a NuGet using the nuspec at the specified folder. It is expected that the lib / ref / runtime folders are welformed. The genereated NuGet package is copied over to the $PackageDestinationPath diff --git a/tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml b/tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml new file mode 100644 index 00000000000..fe8c1a872ff --- /dev/null +++ b/tools/releaseBuild/azureDevOps/templates/nuget-pkg-sbom.yml @@ -0,0 +1,70 @@ +parameters: + - name: PackageVersion + - name: PackagePath + - name: WinFxdPath + - name: LinuxFxdPath + - name: GenAPIToolPath + - name: ListOfFiles + type: object + default: + - Microsoft.Management.Infrastructure.CimCmdlets.dll + - Microsoft.PowerShell.Commands.Diagnostics.dll + - Microsoft.PowerShell.Commands.Management.dll + - Microsoft.PowerShell.Commands.Utility.dll + - Microsoft.PowerShell.ConsoleHost.dll + - Microsoft.PowerShell.CoreCLR.Eventing.dll + - Microsoft.PowerShell.Security.dll + - Microsoft.PowerShell.SDK.dll + - Microsoft.WSMan.Management.dll + - Microsoft.WSMan.Runtime.dll + - System.Management.Automation.dll + +steps: +- ${{ each value in parameters.ListOfFiles }}: + - pwsh: | + $FileName = '${{ value }}' + $FileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($FileName) + $FilePackagePath = Join-Path -Path '${{ parameters.PackagePath }}' -ChildPath $FileBaseName + $CGManifestPath = Join-Path -Path '${{ parameters.PackagePath }}' -ChildPath 'CGManifest' + Write-Verbose -Verbose "FileName to package: $FileName" + Write-Verbose -Verbose "FilePackage path: $FilePackagePath" + Write-Verbose -Verbose "CGManifest path: $CGManifestPath" + # Set SBOM package name + $vstsCommandString = "vso[task.setvariable variable=SbomFilePackageName]${FileBaseName}" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + # Set SBOM package path variable + $vstsCommandString = "vso[task.setvariable variable=SbomFilePackagePath]${FilePackagePath}" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + # Set CGManifest path variable + $vstsCommandString = "vso[task.setvariable variable=CGManifestPath]${CGManifestPath}" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + # Create Nuget package sources + Import-Module -Name $env:REPOROOT\build.psm1 + Import-Module -Name $env:REPOROOT\tools\packaging + Find-DotNet + New-ILNugetPackageSource -File $FileName -PackagePath '${{ parameters.PackagePath }}' -PackageVersion '${{ parameters.PackageVersion }}' -WinFxdBinPath '${{ parameters.WinFxdPath }}' -LinuxFxdBinPath '${{ parameters.LinuxFxdPath }}' -GenAPIToolPath '${{ parameters.GenAPIToolPath }}' -CGManifestPath $CGManifestPath + displayName: 'Create NuGet Package source for single file' + + - template: Sbom.yml@ComplianceRepo + parameters: + BuildDropPath: $(SbomFilePackagePath) + Build_Repository_Uri: 'https://github.com/powershell/powershell' + PackageName: $(SbomFilePackageName) + PackageVersion: ${{ parameters.PackageVersion }} + sourceScanPath: $(CGManifestPath) + displayName: SBOM for NuGetPkg + + - pwsh: | + $FileName = '${{ value }}' + $FileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($FileName) + $FilePackagePath = Join-Path -Path '${{ parameters.PackagePath }}' -ChildPath $FileBaseName + Write-Verbose -Verbose "FileName to package: $FileName" + Write-Verbose -Verbose "FilePackage path: $FilePackagePath" + Import-Module -Name $env:REPOROOT\build.psm1 + Import-Module -Name $env:REPOROOT\tools\packaging + Find-DotNet + New-ILNugetPackageFromSource -FileName $FileName -PackageVersion '${{ parameters.PackageVersion }}' -PackagePath '${{ parameters.PackagePath }}' + displayName: 'Create NuGet Package for single file' diff --git a/tools/releaseBuild/azureDevOps/templates/nuget.yml b/tools/releaseBuild/azureDevOps/templates/nuget.yml index b868c9dbdf7..ea963bd3bcb 100644 --- a/tools/releaseBuild/azureDevOps/templates/nuget.yml +++ b/tools/releaseBuild/azureDevOps/templates/nuget.yml @@ -118,12 +118,14 @@ jobs: - task: NuGetToolInstaller@1 displayName: 'Install NuGet.exe' - - pwsh: | - Import-Module $env:REPOROOT\build.psm1 - Import-Module $env:REPOROOT\tools\packaging - Find-Dotnet - New-ILNugetPackage -PackagePath "$(PackagePath)" -PackageVersion "$(Version)" -WinFxdBinPath '$(winFxdPath)' -LinuxFxdBinPath '$(linuxFxdPath)' -GenAPIToolPath "$(GenAPIToolPath)" - displayName: 'Create Nuget Package Folders' + # Create nuget packages along with SBOM manifests. + - template: nuget-pkg-sbom.yml + parameters: + PackageVersion: $(Version) + PackagePath: $(PackagePath) + WinFxdPath: $(winFxdPath) + LinuxFxdPath: $(linuxFxdPath) + GenAPIToolPath: $(GenAPIToolPath) - pwsh: | Get-ChildItem $(linuxFxdPath) @@ -253,4 +255,4 @@ jobs: - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 displayName: 'Component Detection' inputs: - sourceScanPath: '$(repoRoot)\tools' + sourceScanPath: '$(PackagePath)'