Skip to content

.NET Core tools version check in build.psm1 blocks the build #5260

Closed

Description

@anmenaga

Condition in build.psm1 seems to be looking for exact match with "2.0.0", while the tools are of "2.0.2". This blocks the build.

$dotnetCLIRequiredVersion = "2.0.0"
...
    # Verify if the dotnet in-use is the required version
    $dotnetCLIInstalledVersion = (dotnet --version)
    If ($dotnetCLIInstalledVersion -ne $dotnetCLIRequiredVersion) {
        Write-Warning @"
The currently installed .NET Command Line Tools is not the required version.
...

Expected behavior:

Build succeeds.

Actual behavior

Build stops at warning:

versions

Steps to reproduce

git clone --recursive https://github.com/PowerShell/PowerShell.git
Import-Module ./build.psm1
Start-PSBootstrap
Start-PSBuild

Environment data

Name                           Value
----                           -----
PSVersion                      5.1.17025.1001
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17025.1001
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Activity

  1. rkeithhill commented on Oct 27, 2017

    @rkeithhill
    Collaborator

    Do you have a global.json file in the root of the repo? It's contents should specify that PowerShell currently uses the 2.0.0 version of the SDK. The gist is that the presence of this file should cause dotnet --version to return 2.0.0 if that command is run within the repo dir structure. From that code snippet, I can't tell which dir the command is run from. I suspect the dir isn't being set to the repo path which would cause this problem.

    Try this, cd into your local PowerShell repo and run dotnet --version. What version do you get?

  2. anmenaga commented on Oct 27, 2017

    @anmenaga
    Author

    All commands are run from PowerShell repo root C:\github\PowerShell

    PS C:\github\PowerShell> dir global.json
    
    
        Directory: C:\github\PowerShell
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----       10/27/2017   1:34 PM             47 global.json
    
    
    PS C:\github\PowerShell> gc .\global.json
    {
      "sdk": {
        "version": "2.0.0"
      }
    }
    PS C:\github\PowerShell> dotnet --version
    2.0.2
    PS C:\github\PowerShell>
    
  3. rkeithhill commented on Oct 27, 2017

    @rkeithhill
    Collaborator

    Hmm, that is not what I see but I have both 2.0.0 and 2.0.2 installed. Which versions do you have in your C:\Program Files\dotnet\sdk and C:\Users\anmenaga\AppData\Local\Microsoft\dotnet\sdk folders?

  4. anmenaga commented on Oct 27, 2017

    @anmenaga
    Author
    PS C:\github\PowerShell> dir "C:\Program Files\dotnet\sdk"
    
    
        Directory: C:\Program Files\dotnet\sdk
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    d-----       10/11/2017   3:05 PM                2.0.2
    d-----       10/27/2017   2:38 PM                NuGetFallbackFolder
    
    
    PS C:\github\PowerShell>
    
  5. rkeithhill commented on Oct 27, 2017

    @rkeithhill
    Collaborator

    Anything in the C:\Users\anmenaga\AppData\Local\Microsoft\dotnet\sdk folder?

  6. anmenaga commented on Oct 27, 2017

    @anmenaga
    Author
    PS C:\github\PowerShell> dir C:\Users\anmenaga\AppData\Local\Microsoft\dotnet\sdk
    
    
        Directory: C:\Users\anmenaga\AppData\Local\Microsoft\dotnet\sdk
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    d-----       10/27/2017   1:36 PM                2.0.0
    d-----       10/27/2017   1:45 PM                NuGetFallbackFolder
    
  7. rkeithhill commented on Oct 27, 2017

    @rkeithhill
    Collaborator

    Hmm, I wonder why dotnet is not seeing the sdk under you AppData dir. As an experiment, would you be willing to install the .NET SDK from here, restart PowerShell and then re-run dotnet --version from the PowerShell repo folder. Does that still report 2.0.2?

  8. IISResetMe commented on Oct 28, 2017

    @IISResetMe
    Collaborator

    Can't we optimize the version check in build.psm1 to do ordinal version comparison after validating the major version of the dotnet CLI?

    PowerShell seems to compile just fine with version 2.0.2

  9. rkeithhill commented on Oct 28, 2017

    @rkeithhill
    Collaborator

    There's definitely an argument to be made to simply let global.json inform of dotnet of the desired version of the SDK and let dotnet determine compatibility.

    That said, it seems like there is a bug in dotnet because on my system with both 2.0.0 and 2.0.2, dotnet --version reports 2.0.0 in the PowerShell repo. Not sure why the OP isn't seeing the same thing given they also have both the 2.0.2 and 2.0.0 SDK installed.

  10. iSazonov commented on Oct 29, 2017

    @iSazonov
    Collaborator

    We decided to use a fixed version after a number of compatibility problems.
    We now expect 2.0.3 version with important patches.

  11. iSazonov commented on Oct 29, 2017

    @iSazonov
    Collaborator
  12. rkeithhill commented on Oct 30, 2017

    @rkeithhill
    Collaborator

    It appears that perhaps the PowerShell build is installing the .NET Core SDK into a place that isn't ideal. https://github.com/dotnet/cli/issues/7928#issuecomment-340522972

    'dotnet' does not consider versions that were installed to the user's AppData folder; this is by design.
    "That will install .NET Core 2.0.0 into the user's AppData folder" - consider changing this installation location.

    Andrew (@anmenaga) This answers the question as to why you're seeing this error. Installing the .NET Core 2.0 SDK from https://www.microsoft.com/net/download/core will get you around this issue.

    Question for PowerShellTeam, why does the build system install into the user's AppData folder instead of the normal program files location? Because of the need to elevate? As it stands now, the global.json file apparently will not help unless the user has installed .NET Core SDK ahead of time.

  13. anmenaga commented on Nov 1, 2017

    @anmenaga
    Author

    Thanks Keith Hill (@rkeithhill)

    An interesting observation...
    On my machine "Program Files\dotnet" location (with version 2.0.2) was in %PATH% system-wide env var. Looks like it was added there when I recently installed Visual Studio 2017 (I've confirmed on a clean machine that VS2017 adds to the %PATH% system-wide env var).
    When I changed %PATH% env var to have AppData|2.0.0 location instead - things started working again.

  14. iSazonov commented on Nov 1, 2017

    @iSazonov
    Collaborator

    Should we document this and/or add a check in Start-PSBootStrap?

  15. daxian-dbw commented on Nov 2, 2017

    @daxian-dbw
    Member

    We use the dotnet-install.ps1 script from 'dotnet/cli' repo to install dotnet sdk, and it installs dontet to AppData folder by default.

    The global.json file did resolve the same build issue in our AppVeyor CI about 2 weeks ago. It seemed there was an update to the "Server 2016+VS2107" image we are using in AppVeyor. The new image has dotnet installed in Program Files, and caused Start-PSBuild to stop working. Then we merged the PR #5118 and the CI started to work again. I guess that was because the dotnet installed at Program Files has both 2.0.2 and 2.0.0 installed (need to verify it myself).

  16. daxian-dbw commented on Nov 2, 2017

    @daxian-dbw
    Member

    Just verified on an AppVeyor builder. The dotnet SDK installed at C:\Program Files\dotnet has the following versions installed. That's why global.json fixed the CI runs.

    PS C:\Program Files\dotnet\sdk> dir
    
    
        Directory: C:\Program Files\dotnet\sdk
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    da----         4/8/2017   1:00 PM                1.0.1
    da----         4/7/2017  10:10 PM                1.0.2
    da----        4/10/2017  12:06 PM                1.0.3
    d-----        5/28/2017  12:02 PM                1.0.4
    d-----        8/15/2017   3:26 PM                1.1.0
    d-----        8/15/2017  12:36 PM                2.0.0
    d-----       10/17/2017   8:47 PM                2.0.2
    d-----        11/2/2017   1:08 PM                NuGetFallbackFolder
    
  17. rkeithhill commented on Nov 4, 2017

    @rkeithhill
    Collaborator

    Got this info from the dotnet/cli folks:

    Set the environment variable MULTI_LEVEL_LOOKUP to false to disable it.
    The install script is used to download a ZIP and it puts the contents of the ZIP in the path for your current shell session. We don't make any statements regarding the dotnet host being able to find the SDK in the default location that the install script installs the SDK.
    Also note that if you use the install script, the expectation is that you will run dotnet.exe from where the script installed the SDK, and the host will find the SDK that is sitting right next to it.

    It appears to me that this is likely to work correctly the first time the user bootstraps the build env as the install-dotnet script adds the download path (user's appdata dir) to the PowerShell process's path. After that session is closed, the user is at the mercy of what they have officially installed AFAICT because the build script is executing dotnet as in dotnet --version, dotnet restore, etc. There is no attempt to use the version of dotnet that the bootstrapper installed. This seems a bit perilous.

    One option is to use the install-dotnet script to install into $env:ProgramFiles\dotnet (on Windows) but would require elevation. Another option is to configure $dotnet as a path to the executable where that path is under the user's app data folder. Finally, you could try setting $env:MULTI_LEVEL_LOOKUP="false" but I'm still a little fuzzy as to what that actually does.

  18. rkeithhill commented on Nov 4, 2017

    @rkeithhill
    Collaborator

    I've been looking at how the PowerShellEditorServices does this. It installs into a .dotnet folder at the root of the repo. You'd need to gitignore that but that is another option to consider.

  19. rkeithhill commented on Nov 4, 2017

    @rkeithhill
    Collaborator

    OK did a bit more investigating into this. I removed the 2.0.2 SDK that was in my C:\Program Files\dotnet\sdk dir and also removed the one from my app data dir. Then I bootstrapped and tried to build w/no joy:

    14:109ms> ipmo .\build.psm1
    15:88ms> Start-PSBootstrap
    Installing PowerShell build dependencies
    dotnet not present.  Installing dotnet.
    dotnet-install: Downloading link: https://dotnetcli.azureedge.net/dotnet/Sdk/2.0.2/dotnet-sdk-2.0.2-win-x64.zip
    dotnet-install: Extracting zip from https://dotnetcli.azureedge.net/dotnet/Sdk/2.0.2/dotnet-sdk-2.0.2-win-x64.zip
    dotnet-install: Adding to current process PATH: "C:\Users\Keith\AppData\Local\Microsoft\dotnet\". Note: This change will not be visible if PowerShell was run as a child process.
    dotnet-install: Installation finished
    
    17:367ms> gcm dotnet
    
    CommandType     Name                                               Version    Source
    -----------     ----                                               -------    ------
    Application     dotnet.exe                                         2.0.255... C:\Program Files\dotnet\dotnet.exe
    
    18:133ms> Start-PSBuild
    WARNING: The currently installed .NET Command Line Tools is not the required version.
    
    Installed version: 2.0.0
    Required version: 2.0.2
    
    Fix steps:
    
    1. Remove the installed version from:
        - on windows '$env:LOCALAPPDATA\Microsoft\dotnet'
        - on macOS and linux '$env:HOME/.dotnet'
    2. Run Start-PSBootstrap or Install-Dotnet
    3. Start-PSBuild -Clean
    

    The problem is that the precheck method is looking for any dotnet in the path. In this case, it finds the dotnet in C:\Program Files\dotnet which is not able to see the SDK that was just downloaded.

    This can be fixed by having Find-Dotnet first check to see if dotnet is in the current path and if so, does it have the required SDK version. If it does then we use it. Mostly likely this dotnet is the global dotnet in which case we avoided installing dotnet when it doesn't need to be installed.

    More importantly though, we don't settle on a version of dotnet (global) that doesn't have the required SDK. In the case the globally installed dotnet doesn't have the required SDK, we prepend the user's local path for dotnet. If we can't find dotnet or the required SDK in the user's local dotnet dir, this triggers a user local installation of dotnet.

    PR coming on this.

  20. added a commit that references this issue on Nov 4, 2017
    762f2e5
  21. added a commit that references this issue on Nov 10, 2017
    34600c4
  22. added a commit that references this issue on Aug 6, 2026
    b4d9d5d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions