Search code examples
.netcachingcontinuous-integrationgithub-actions

How to cache dotnet installation in GitHub Actions


I have two steps in my CI pipeline. one is to cache the installation path of dotnet and the other is dotnet installation. and using windows-2019 image. but the system never recognizes that .net 7 is available it always has .net 6.0 installed. The cache also shows that 200MB is cached but maybe some PATH variable needs tweaking. Can someone help me with this?

    runs-on: windows-2019

    env:
      DOTNET_INSTALL_DIR: '.\.dotnet'
      DOTNET_ROOT: '.\.dotnet'

My cache step is:

      - name: Cache dotnet
        id: cache-dotnet-core # id used in cache-hit condition
        uses: actions/cache@v3
        with:
          path: '.\.dotnet' #~/.dotnet
          key: ${{ runner.os }}-dotnet-${{ hashFiles('**/project.assets.json') }}
          restore-keys: ${{ runner.os }}-dotnet-${{ hashFiles('**/project.assets.json') }}

and my dotnet installation step is

      - name: Install Dotnet
        #if: steps.cache-dotnet-core.outputs.cache-hit != 'true' # condition to check if old installation is available in cache
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: 7.0.x

Remember once the cache is saved the 2nd run of the job will show you that .net 6.0 is installed whereas 7.0 should be there.

Here's the complete workflow:

name: dotnet-pipeline
on: [push]

jobs:
  build:
    name: check-dotnet-version
    runs-on: windows-2019 # Win 10 IoT En is not available on github actions

    env:
      DOTNET_INSTALL_DIR: '.\.dotnet'
      DOTNET_ROOT: '.\.dotnet'

    steps:      
      # maintain cache of dotnet installation
      - name: Cache dotnet
        id: cache-dotnet-core
        uses: actions/cache@v3
        with:
          path: '.\.dotnet'
          key: ${{ runner.os }}-dotnet-7
          restore-keys: ${{ runner.os }}-dotnet-7

      # dotnet will only be installed if the files are not found in cache
      - name: Install Dotnet
        if: steps.cache-dotnet-core.outputs.cache-hit != 'true' 
        uses: actions/setup-dotnet@v3
        with:
          dotnet-version: 7.0.x
          
      # validate version number
      - name: validate dotnet version
        run: 'dotnet --version'

Solution

  • One solution could be to use the absolute path to the dotnet executable where it is installed and cached i.e. by using the prefix DOTNET_INSTALL_DIR throughout for installation, caching, and wherever the dotnet command is invoked.

    Alternatively, for using it without the prefix, DOTNET_INSTALL_DIR could be added to GITHUB_PATH before using the dotnet command i.e.:

    echo "${{ env.DOTNET_INSTALL_DIR }}" | Out-File -FilePath $ENV:GITHUB_PATH -Encoding utf8 -Append
    

    Here's the complete workflow with GITHUB_PATH (tested):

    name: cache_dotnet
    
    on:
      workflow_dispatch:
    
    jobs:
      build:
        runs-on: windows-2019
    
        env:
          DOTNET_INSTALL_DIR: '.\.dotnet'
    
        steps:
          - name: Cache dotnet
            id: cache-dotnet
            uses: actions/cache@v3
            with:
              path: ${{ env.DOTNET_INSTALL_DIR }}
              key: ${{ runner.os }}-dotnet-7
              restore-keys: ${{ runner.os }}-dotnet-7
    
          - name: Install dotnet
            if: ${{ steps.cache-dotnet.outputs.cache-hit != 'true' }}
            uses: actions/setup-dotnet@v3
            with:
              dotnet-version: 7.0.x
    
          - name: Check default dotnet version
            run: dotnet --version
    
          - name: Set installed/cached dotnet path [${{ env.DOTNET_INSTALL_DIR }}]
            run: echo "${{ env.DOTNET_INSTALL_DIR }}" | Out-File -FilePath $ENV:GITHUB_PATH -Encoding utf8 -Append
    
          - name: Check installed/cached dotnet version
            run: dotnet --version
    

    Output

    Run

    See Environment variables of the actions/setup-dotnet for more details.


    Apart from that, from this issue, it looks like there was caching in the https://github.com/actions/setup-dotnet action itself, and then it was disabled. You might want to keep track of this, just in case.