DEV Community 👩‍💻👨‍💻

Cover image for Using GitHub Actions to Update .NET Dependencies Automatically
Stephen Walsh
Stephen Walsh

Posted on • Updated on • Originally published at stphnwlsh.Medium

Using GitHub Actions to Update .NET Dependencies Automatically

It’s a tale as old as time, as a software engineer, you write some code, you’re happy with it and then you deliver it. End of story, right? No more work to be done! As usual there’s many more layers to deal with and one of those many layers is maintenance……boooooo!!!!!

I know this isn’t the most amazing topic to write about, but it solves a real-world problem for me and I’m hoping for some of you too.

I’m a backend engineer and write a lot of C#, which means I end up with solutions relying on NuGet packages. These do need to be updated all the time because there are other engineers out there doing amazing work keeping their packages up to date and I like to keep my dependencies up to date. This is where I find myself, with the problem of having to create a branch, update the packages, commit it, then seek PR approval, just to get some minor updates through. It’s annoying and I want to solve this.

Before we get underway, are these instructions for me?

  1. You have a solution written in .NET…these instructions only work for code in .NET.
  2. The code already is, or you are about to host this solution in Github….so you can use Actions.
  3. You want to update your NuGet packages, engineers have valid reasons for doing or not doing things, no pressure here. I like to keep my packages up to date or at the very least alert me to when I need to make changes because of dependency updates.

If you are in, it’s time to work with me here, Actions can be used to trigger many workflows. The most common being build and release pipelines for you project. The answer to our problem also lives in an Action. The time has come to create a new one.

  1. Navigate to your GitHub Repository of choice
  2. Select the Actions tab
  3. Click that New Workflow button
  4. Ignore all the templates and select “Set up a Workflow Yourself”
  5. Delete all the sample code and we are good to go

Create a New Black GitHub Action

Step 1: Create a schedule action

This is the easiest part, this action will run once a week. You can change the schedule to anything you want. GitHub Action don’t run perfectly on time, but the do run. For more on scheduled jobs and setting the schedules, read the GitHub Documentation and checkout the examples at Crontab Guru.

name: Automated Dependency Updates
        - cron:  '0 0 * * 0'
Enter fullscreen mode Exit fullscreen mode

Step 2: Setup the Job

Next up we set up the job. This is where we define what steps we want to run. We’re running this job on the latest version of Ubuntu. Next, we setup the default actions/checkout step as well as actions/setup-dotnet to install the version of the .NET SDK we need for our solution. I need .NET 6 for this job. You must that notice the changed token for the checkout AUTOMATED_DEPENDENCY_UPDATES_TOKEN, this comes in handy in Step 5, I’ll explain what’s up down there.

        name: Update Dependencies
        runs-on: ubuntu-latest
    - name: Checkout
      id: checkout
      uses: actions/checkout@v2
          token: ${{ secrets.AUTOMATED_DEPENDENCY_UPDATES_TOKEN }}
    - name: Setup
      uses: actions/setup-dotnet@v1
          dotnet-version: 6.0.x
Enter fullscreen mode Exit fullscreen mode

Step 3: Update those Dependencies

These are the base steps of updating our NuGet packages. First, we need to install the dotnet-outdated tool and then validate if we need to take any further action. If we run dotnet outdated and there are not packages to update we should cancel the rest of the steps in this job.
This is done but setting an output variable on the validate step that can be used by every other step in the job to determine if it should run or not. If there are no updates to be made, then we set the output variable to false.
If we have updates to make them, we run dotnet outdated -u to force the NuGet updates. If this is successful, then we set the output variable to true to allow the following steps to run.

- name: Tools
  id: tools      
  run: dotnet tool install --global dotnet-outdated-tool     
- name: Update      
  id: update      
  run: |        
      OUTPUT=$(dotnet outdated)        
      if [[ $OUTPUT =~ "No outdated dependencies" ]]; then
          echo "::set-output name=updated::false"        
          dotnet outdated -u                    
          echo "::set-output name=updated::true"        
  shell: bash
Enter fullscreen mode Exit fullscreen mode

Step 4: Run your Tests

After you’ve updated the NuGet packages you need to validate that the changes haven’t broken your code. The best way to do that is to build and test your solution. It’s a simple dotnet test command to run all the tests on the solution. You can update this statement to suit your needs, the default should be to run all your tests.

- name: Test
  id: test
  if: ${{ steps.update.outputs.updated == 'true' }}
  run: dotnet test -c Release -v minimal
Enter fullscreen mode Exit fullscreen mode

Step 5: Commit and Push

The final step is to commit and then push the NuGet package updates, if the tests pass then this step runs and your automated package update is complete. When we used the AUTOMATED_DEPENDENCY_UPDATES_TOKEN in the checkout step, that was to step around the fact that the inbuilt GITHUB_TOKEN will not trigger a follow-on workflow. If you generate a specific Personal Access Token to use when checking the code out then after the code is pushed, if you have another automated workflow, it will trigger.
Finally, we set the commit message and author. This will register the commit to the GitHub Action user and not the user who setup the job.

- name: Push
  id: push
  if: ${{ steps.update.outputs.updated == 'true' }}
  uses: stefanzweifel/git-auto-commit-action@v4
      commit_author: github-actions[bot] <41898282+github-actions[bot]>
      commit_user_name: github-actions[bot]
      commit_user_email: 41898282+github-actions[bot]
      commit_message: Automated Dependency Updates
Enter fullscreen mode Exit fullscreen mode

We’re Done!

Now let’s put all the steps together in one easy Gist to use in any other repository. Hope this helps you automate that boring task too. This can work for any other CI/CD tool that allows for scheduled jobs. The concepts are the same just follow the Checkout, Update, Test and Push process.


If you like this, checkout my other examples on GitHub and consider supporting me at Buy Me a Coffee.

"Buy Me A Coffee"

Top comments (0)

Join us at DEV
Yes, this is technically an “ad”, but really we just want to ask if you want to join DEV. We have 900k+ developers reading, posting, and enjoying community, and would love to have you.   Create an account and continue your coding journey.