Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
UpdateDotnetRuntime.ps1371 linesDownload Raw Back to tools
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3 4[CmdletBinding()]5param (6    [Parameter()]7    [string]$SDKVersionOverride,8 9    [Parameter()]10    [switch]$UseNuGetOrg,11 12    [Parameter()]13    [string]$RuntimeSourceFeed,14 15    [Parameter()]16    [string]$RuntimeSourceFeedKey,17 18    [Parameter()]19    [switch]$InteractiveAuth,20 21    [Parameter()]22    [switch]$UseInternalFeed23)24 25<#26 .DESCRIPTION Update the global.json with the new SDK version to be used.27#>28function Update-GlobalJson([string] $Version) {29    $psGlobalJsonPath = Resolve-Path "$PSScriptRoot/../global.json"30    $psGlobalJson = Get-Content -Path $psGlobalJsonPath -Raw | ConvertFrom-Json31 32    if ($psGlobalJson.sdk.version -eq $Version) {33        throw '.NET SDK version is not updated'34    }35 36    $psGlobalJson.sdk.version = $Version37    $psGlobalJson | ConvertTo-Json | Out-File -FilePath $psGlobalJsonPath -Force38}39 40<#41 .DESCRIPTION Iterate through all the csproj to find all the packages that need to be updated42#>43function Update-PackageVersion {44 45    class PkgVer {46        [string] $Name47        [string] $Version48        [string] $NewVersion49        [string] $Path50 51        PkgVer($n, $v, $nv, $p) {52            $this.Name = $n53            $this.Version = $v54            $this.NewVersion = $nv55            $this.Path = $p56        }57    }58 59    $skipModules = @(60        "NJsonSchema"61        "Markdig.Signed"62        "PowerShellHelpFiles"63        "Newtonsoft.Json"64        "Microsoft.ApplicationInsights"65        "Microsoft.Management.Infrastructure"66        "Microsoft.PowerShell.Native"67        "Microsoft.NETCore.Windows.ApiSets"68        "Microsoft.PowerShell.MarkdownRender"69    )70 71    $packages = [System.Collections.Generic.Dictionary[[string], [PkgVer[]] ]]::new()72 73    $paths = @(74        "$PSScriptRoot/packaging/projects/reference/Microsoft.PowerShell.Commands.Utility/Microsoft.PowerShell.Commands.Utility.csproj"75        "$PSScriptRoot/packaging/projects/reference/System.Management.Automation/System.Management.Automation.csproj"76        "$PSScriptRoot/packaging/projects/reference/Microsoft.PowerShell.ConsoleHost/Microsoft.PowerShell.ConsoleHost.csproj"77        "$PSScriptRoot/../src/"78        "$PSScriptRoot/../test/tools/"79        "$PSScriptRoot/../test/perf/dotnet-tools/"80    )81 82    Get-ChildItem -Path $paths -Recurse -Filter "*.csproj" -Exclude 'PSGalleryModules.csproj', 'PSGalleryTestModules.csproj' | ForEach-Object {83        Write-Verbose -Message "Reading - $($_.FullName)" -Verbose84        $prj = [xml] (Get-Content $_.FullName -Raw)85        $pkgRef = $prj.Project.ItemGroup.PackageReference86 87        foreach ($p in $pkgRef) {88            if ($null -ne $p -and -not $skipModules.Contains($p.Include)) {89                if (-not $packages.ContainsKey($p.Include)) {90                    $packages.Add($p.Include, @([PkgVer]::new($p.Include, $p.Version, $null, $_.FullName)))91                } else {92                    $packages[$p.Include] += [PkgVer]::new($p.Include, $p.Version, $null, $_.FullName)93                }94            }95        }96    }97 98    $versionPattern = (Get-Content "$PSScriptRoot/../DotnetRuntimeMetadata.json" | ConvertFrom-Json).sdk.packageVersionPattern99 100    $source = if ($UseNuGetOrg) { 'nuget.org' } elseif ($UseInternalFeed) { 'dotnet-internal' } else { 'dotnet' }101 102    # Always add nuget.org as some packages are only found there.103    $source = if ($source -ne 'nuget.org') {104        @($source, "nuget.org")105    }106 107    $packages.GetEnumerator() | ForEach-Object {108        $pkgName = $_.Key109 110        $pkgs = [System.Collections.Generic.Dictionary[string, Microsoft.PackageManagement.Packaging.SoftwareIdentity]]::new()111 112        # We have to find packages for all sources separately as Find-Package does not return all packages when both sources are provided at the same time.113        # Since there will be a lot of duplicates we add the package to a dictionary so we only get a unique set by version.114        $source | ForEach-Object {115            Find-Package -Name $pkgName -AllVersions -AllowPrereleaseVersions -Source $_ -ErrorAction SilentlyContinue | ForEach-Object {116                if (-not $pkgs.ContainsKey($_.Version)) {117                    $pkgs.Add($_.Version, $_)118                }119            }120        }121 122        foreach ($v in $_.Value) {123            $version = $v.Version124 125            foreach ($p in $pkgs.Values) {126                # some packages are directly updated on nuget.org so need to check that too.127                if ($p.Version -like "$versionPattern*" -or $p.Source -eq 'nuget.org') {128                    try {129                        if ([System.Management.Automation.SemanticVersion] ($version) -lt [System.Management.Automation.SemanticVersion] ($p.Version)) {130                            $v.NewVersion = $p.Version131                            break132                        }133                    } catch {134                        if ($_.FullyQualifiedErrorId -ne 'InvalidCastParseTargetInvocation') {135                            throw $_136                        }137                    }138                }139            }140        }141    }142 143    # we need a ForEach-Object below to unravel each of the items in 'Values' which is an array of PkgVer144    $pkgsByPath = $packages.Values | ForEach-Object { $_ } | Group-Object -Property Path145 146    $pkgsByPath | ForEach-Object {147        Update-CsprojFile -Path $_.Name -Values $_.Group148    }149}150 151<#152 .DESCRIPTION Update package versions to the latest as per the pattern mentioned in DotnetRuntimeMetadata.json153#>154function Update-CsprojFile([string] $path, $values) {155    $fileContent = Get-Content $path -Raw156    $updated = $false157 158    foreach ($v in $values) {159        if ($v.NewVersion) {160            $stringToReplace = "<PackageReference Include=`"$($v.Name)`" Version=`"$($v.Version)`" />"161            $newString = "<PackageReference Include=`"$($v.Name)`" Version=`"$($v.NewVersion)`" />"162 163            $fileContent = $fileContent -replace $stringToReplace, $newString164            $updated = $true165        }166    }167 168    if ($updated) {169        ($fileContent).TrimEnd() | Out-File -FilePath $path -Force170    }171}172 173function Get-DotnetUpdate {174    param (175        $channel,176        $quality,177        $qualityFallback,178        $feedUrl,179        $sdkImageVersion180    )181 182    if ($SDKVersionOverride) {183        return @{184            ShouldUpdate = $true185            NewVersion   = $SDKVersionOverride186            Message      = $null187            FeedUrl      = $feedUrl188            Quality      = $quality189        }190    }191 192    try {193 194        try {195            $URL = "http://aka.ms/dotnet/$channel/$quality/productVersion.txt"196            $latestSDKVersionString = Invoke-RestMethod -Uri $URL -ErrorAction Stop | ForEach-Object { $_.Trim() }197            $selectedQuality = $quality198        } catch {199            if ($_.exception.Response.StatusCode -eq 'NotFound') {200                Write-Verbose -Verbose -Message "No build at '$URL' found!"201            } else {202                throw $_203            }204        }205        $latestSDKversion = $latestSDKVersionString -as "System.Management.Automation.SemanticVersion"206 207        if (-not $latestSDKVersion) {208            # we did not get a version number so fall back to daily209            $URL = "http://aka.ms/dotnet/$channel/$qualityFallback/productVersion.txt"210            $latestSDKVersionString = Invoke-RestMethod -Uri $URL -ErrorAction Stop | ForEach-Object { $_.Trim() }211            $selectedQuality = $qualityFallback212 213            $latestSDKversion = $latestSDKVersionString -as "System.Management.Automation.SemanticVersion"214            if (-not $latestSDKVersion) {215                throw "No build at '$URL' found!"216            }217        }218 219        $currentVersion = [System.Management.Automation.SemanticVersion] (( Get-Content -Path "$PSScriptRoot/../global.json" -Raw | ConvertFrom-Json).sdk.version)220 221        if ($latestSDKversion -gt $currentVersion -and $null -ne $latestSDKversion.PreReleaseLabel) {222            $shouldUpdate = $true223            $newVersion = $latestSDKversion224        } else {225            $shouldUpdate = $false226            $newVersion = $latestSDKVersionString227 228            $Message = $null -eq $currentVersion.PreReleaseLabel ? "$latestSDKversion is not preview, update manually." : "No update needed."229        }230    } catch {231        Write-Verbose -Verbose "Error occurred: $_.message"232        $shouldUpdate = $false233        $newVersion = $null234        Write-Error "Error while checking .NET SDK update: $($_.message)"235    }236 237    return @{238        ShouldUpdate = $shouldUpdate239        NewVersion   = $newVersion240        Message      = $Message241        FeedUrl      = $feedUrl242        Quality      = $selectedQuality243    }244}245 246function Update-DevContainer {247    $dockerFilePath = "$PSScriptRoot/../.devcontainer/Dockerfile"248    $sdkImageVersion = (Get-Content -Raw "$PSScriptRoot/../DotnetRuntimeMetadata.json" | ConvertFrom-Json).sdk.sdkImageVersion249 250    $devContainerDocker = (Get-Content $dockerFilePath) -replace 'FROM mcr\.microsoft\.com/dotnet.*', "FROM mcr.microsoft.com/dotnet/nightly/sdk:$sdkImageVersion"251 252    $devContainerDocker | Out-File -FilePath $dockerFilePath -Force253}254 255<#256 .DESCRIPTION Update the DotnetMetadata.json file with the latest version of the SDK257 #>258function Update-DotnetRuntimeMetadata {259    param (260        [string] $newSdk261    )262 263    # -replace uses regex so in order to split on `.`, we need to use `\.` to escape the dot character.264    $sdkParts = $newSdk -split '\.'265 266    # Transform SDK Version '7.0.100-preview.5.22263.22' -> '7.0.1xx-preview5'267    $newChannel = $sdkParts[0] + "." + $sdkParts[1] + "." + ($sdkParts[2] -replace '0','x') + $sdkParts[3]268    Write-Verbose -Verbose -Message "Updating DotnetRuntimeMetadata.json with channel $newChannel"269 270    # Transform SDK Version '7.0.100-preview.5.22263.22' -> '7.0.100-preview.5'271    $newPackageVersionPattern = $sdkParts[0] + "." + $sdkParts[1] + "." + '0-' + ($sdkParts[2] -split '-')[-1] + "." + $sdkParts[3]272    Write-Verbose -Verbose -Message "Updating DotnetRuntimeMetadata.json with package filter $newPackageVersionPattern"273 274    $metadata = Get-Content -Raw "$PSScriptRoot/../DotnetRuntimeMetadata.json" | ConvertFrom-Json275    $metadata.sdk.channel = $newChannel276    $metadata.sdk.packageVersionPattern = $newPackageVersionPattern277    $metadata | ConvertTo-Json | Out-File -FilePath "$PSScriptRoot/../DotnetRuntimeMetadata.json" -Force278}279 280$dotnetMetadataPath = "$PSScriptRoot/../DotnetRuntimeMetadata.json"281$dotnetMetadataJson = Get-Content $dotnetMetadataPath -Raw | ConvertFrom-Json282$channel = $dotnetMetadataJson.sdk.channel283$nextChannel = $dotnetMetadataJson.sdk.nextChannel284$quality = $dotnetMetadataJson.sdk.quality285$qualityFallback = $dotnetMetadataJson.sdk.qualityFallback286$sdkImageVersion = $dotnetMetadataJson.sdk.sdkImageVersion287$internalfeed = $dotnetMetadataJson.internalfeed.url288 289$dotnetUpdate = Get-DotnetUpdate -channel $nextChannel -quality $quality -feedUrl $internalfeed -qualityFallback $qualityFallback -sdkImageVersion $sdkImageVersion290 291if ($dotnetUpdate.ShouldUpdate) {292 293    Import-Module "$PSScriptRoot/../build.psm1" -Force294 295    Find-Dotnet296 297    $feedname = if ($UseNuGetOrg) { 'nuget.org' } elseif ($UseInternalFeed) { 'dotnet-internal' } else { 'dotnet' }298 299    $addDotnetSource = (-not (Get-PackageSource -Name $feedname -ErrorAction SilentlyContinue))300 301    if (!$UseNuGetOrg -and $addDotnetSource) {302        $nugetFileContent = Get-Content "$PSScriptRoot/../nuget.config" -Raw303        $nugetFileSources = ([xml]($nugetFileContent)).Configuration.packagesources.add304 305        if ($feedname -ne 'dotnet-internal') {306            $dotnetFeed = $nugetFileSources | Where-Object { $_.Key -eq $feedname } | Select-Object -ExpandProperty Value307            Register-PackageSource -Name $feedname -Location $dotnetFeed -ProviderName NuGet308            Write-Verbose -Message "Register new package source $feedname" -verbose309        }310 311        if ($feedname -eq 'dotnet-internal') {312            # This NuGet feed is for internal to Microsoft use only.313            $dotnetInternalFeed = $dotnetMetadataJson.internalfeed.url314 315            $updatedNugetFile = if ($nugetFileContent.Contains('dotnet-internal')) {316                $nugetFileContent -replace ".<add key=`"dotnet-internal?.*', ' <add key=`"dotnet-internal`" value=`"$dotnetInternalFeed`" />`r`n  </packageSources>"317            } else {318                $nugetFileContent -replace "</packageSources>", "  <add key=`"dotnet-internal`" value=`"$dotnetInternalFeed`" />`r`n  </packageSources>"319            }320 321            $updatedNugetFile | Out-File "$PSScriptRoot/../nuget.config" -Force322 323            Register-PackageSource -Name 'dotnet-internal' -Location $dotnetInternalFeed -ProviderName NuGet324            Write-Verbose -Message "Register new package source 'dotnet-internal'" -verbose325        }326    }327 328    ## Install latest version from the channel329 330    $sdkQuality = $dotnetUpdate.Quality331    $sdkVersion = if ($SDKVersionOverride) { $SDKVersionOverride } else { $dotnetUpdate.NewVersion }332 333    if (-not $RuntimeSourceFeed) {334        Install-Dotnet -Version $sdkVersion -Quality $sdkQuality -Channel $null335    }336    else {337        Install-Dotnet -Version $sdkVersion -Quality $sdkQuality -AzureFeed $RuntimeSourceFeed -FeedCredential $RuntimeSourceFeedKey -Channel $null338    }339 340    Write-Verbose -Message "Installing .NET SDK completed." -Verbose341 342    $environment = Get-EnvironmentInformation343 344    $dotnetPath = if ($environment.IsWindows) { "$env:LocalAppData\Microsoft\dotnet" } else { "$env:HOME/.dotnet" }345 346    $pathSep = [System.IO.Path]::PathSeparator347 348    if (-not (($ENV:PATH -split $pathSep) -contains "$dotnetPath")) {349        $env:PATH = "$dotnetPath" + $pathSep + "$ENV:PATH"350    }351 352    $latestSdkVersion = (dotnet --list-sdks | Select-Object -Last 1 ).Split() | Select-Object -First 1353 354    Write-Verbose -Message "Installing .NET SDK completed, version - $latestSdkVersion" -Verbose355 356    Update-GlobalJson -Version $latestSdkVersion357 358    Write-Verbose -Message "Updating global.json completed." -Verbose359 360    Update-DotnetRuntimeMetadata -newSdk $latestSdkVersion361 362    Update-PackageVersion363 364    Write-Verbose -Message "Updating project files completed." -Verbose365 366    Update-DevContainer367}368else {369    Write-Verbose -Verbose -Message $dotnetUpdate.Message370}371