Moving from Dependabot-Preview to Dependabot Native

Dependabot native has been around for a couple years now after GitHub officially acquired it in 2019. But if I google “Dependabot” I still generally find myself at the “Dependabot.com” home-page, and up until last week found myself still using the Dependabot-Preview. In general, the difference between preview and native is a little confusing.

We introduced Dependabot-Preview into the mainstream organization at SPS Commerce as part of our standard development processes near the beginning of 2020. It is the final solution to a bit of my own journey in search of a tool to keep dependencies up to date. But it was an awkward position to begin onboarding to a set of preview functionality that was essentially being re-written and integrated directly into the GitHub ecosystem at the same time. Regardless the preview offered fantastic and stable functionality that our teams needed to claim sooner rather than later. Unfortunately, the native offering was missing the essential capability to update an ecosystem based on private registries, which was required in our development practice to ensure the effective rollout of private libraries across dozens of services and teams.

As of last week, Dependabot now has native support for private dependencies. Now is the time to migrate!

Getting Started

If you were used to configuring Dependabot-Preview via the .dependabot/config.yml, then you are going to feel right at home with the configuration of Dependabot native. The schema for configuration feels refined and straight-forward. Just remember to look for Dependabot on GitHub Docs (not dependabot.com) for your configuration reference. The titles of the documentation do not strictly call it “Dependabot” but rather use more generic supply chain terminology.

Getting past the documentation, create a simple file at .github/dependabot.yml and configure as follows:

version: 2
updates:
  - package-ecosystem: nuget
    directory: /
    schedule:
      interval: daily

The pretty self-documenting configuration enables NuGet scanning across all directories in my repo daily. Additional ecosystems can be added as necessary. Each ecosystem can configure individually allowed packages or versions to ignore.

A common scenario for configuration in the NuGet ecosystem would be to configure Dependabot to ignore updates for .NET 5 while my application is running in .NET Core 3.1 (which is LTS at the time of writing this). I would have no intention of updating to .NET 5 for my current development path. I can configure this as follows:

version: 2
updates:
  - package-ecosystem: nuget
    directory: /
    schedule:
      interval: daily
    ignore:
    - dependency-name: "Microsoft.Extensions.*"
      versions: ">= 5.0.0"
    - dependency-name: "Microsoft.AspNetCore.*"
      versions: ">= 5.0.0"

At the point of committing the above file to your repository in your default branch, you may start to receive Pull Request notifications about incoming version upgrade requests. Great! We know Dependabot is working. That being said, it was necessary at times to double-check some of the scanning output in the old Dependabot UI if you were unsure about the accuracy or syntax of your configuration file, etc. Moving to Dependabot native, you get native integration so you don’t have to leave the GitHub experience to review and debug your Dependabot integration.

Dependabot GitHub Integration

Directly inside your “Insights -> Dependency graph -> Dependabot” tab on your repository you’ll find the ability to see the individual output per ecosystem and the ability to manually “Check for updates” (similar to the old “bump” feature). Very excited about this developer experience enhancement and looking forward to using it paired with the “Dependency graph -> Dependencies” tab as well.

Dependabot Native Logs

Migrating from Dependabot-Preview

If your migrating from the Dependabot-Preview, you have the option of accessing the old Dependabot UI at: https://app.dependabot.com/accounts/{your-github-organization}/ and reviewing the list of repositories with a config.yml you want to upgrade. Selecting the “Update config file” option will automatically materialize the updated schema version for your dependabot.yml. Bonus, it can also automatically submit a pull request for the update.

Migrating config.yml to dependabot.yml

You’ll notice that there are some key differences between the versions that we have not discussed:

  • Schedule – gone from the capability is the possibility for “live” updates. It was a nice feature and in theory, seemed powerful. But in actuality I often found myself moving to weekly updates to avoid some of the onslaughts of live updates, and additionally to avoid pulling in packages that were just released (because I’m lazy and want other teams to do a bit of testing on it before I look at a super fresh new version of a package).
  • Open Pull Request Limit – the limit by default before was 10 for the preview. The default now is 5. The migration conversion above takes that into account which is nice and can be specified via the open-pull-requests-limit. I often found that if this was set too low I would do 5 merges to quickly discover 5 more updates that were needed. Increasing this helps me understand the complete scope of version updates coming in (somewhere between 10-20 has worked well for me.

Additionally, if you had private registries configured in Dependabot-Preview, they are automatically included in the new YAML above, but we have a bit more work to do to enable those.

Configuring Private Registries

An absolutely required feature for our organization, I am very excited to have private registry capability. Previously you configured Private Registries directly inside the Dependabot.com UI under your organization “Config variables”. It worked really well that we could set and add registries for any ecosystem with proper credentials and those registries would be automatically consulted for all Dependabot scans using that ecosystem. It was simple and very low maintenance when registries came and went. Unfortunately, this capability is not provided using Dependabot native.

Dependabot-Preview Private Registry Configuration

Using Dependabot native there is no organizational level configuration or capability, EXCEPT for storage of Dependabot consumed secrets (we’ll come back to this). So straight away the ability to configure private registries is going to have leaked into EVERY repository you want to use it. At SPS Commerce we worked hard to standardize Private Registry usage so our teams could align easily on the consumption of packages. It feels unfortunate that we’ll need every repository to indicate the private registry URLs they intend to consume.

That aside we can easily configure our NuGet feed with a private registry as follows:

version: 2
registries:
  your-nuget-feed:
    type: nuget-feed
    url: https://your-feed/nuget/v3/index.json
    token: ${{secrets.NUGET_AZP_TOKEN_V1}} 
updates:
  - package-ecosystem: nuget
    directory: /
    registries:
    - your-nuget-feed
    schedule:
      interval: daily

Notice the usage of the tokenized “${{secret.*}}” syntax after “token” enables us to include token or user/pass credentials to authorize to our registry. You can access a newly scoped secret capability under “Settings -> Secrets -> Dependabot” in your GitHub repository, where you can define key/value pairs accessible only by Dependabot. Additionally, one of the saving graces, is that you do have the ability as an organizational owner in GitHub to define org-wide Dependabot secrets that can default to being inherited by ALL repositories. As such, we have set up the necessary tokens and credentials with versioned secret names that we apply for all our standard feeds across the organization.

Dependabot Organizational Scoped Secrets

If you are following me to this point you are thinking that you could just add the private registry URL as a secret and make that key/value available to all Dependabot configurations in the organization. Theoretically, that would allow you to change the feed across all repositories very easily. Unfortunately, based on some trial/error it would seem that the “URL” field is not capable of using any configured secrets (very disappointing).

Looking Forward

Using Dependabot provides a great deal of value and plays a vital role in encouraging teams to stay updated in a typically tedious manual task. While setup and configuration organizationally of Dependabot native has not rolled out as simply as I had hoped for private registries, I am excited to put that behind us so we can move ahead with the new features in Dependabot on the GitHub Roadmap.

Migrating is essential so we can stay up to date with the latest ecosystem versions and enhancements, and glad to see that GitHub has planned to keep up with those changes.

In my original onboarding of Dependabot-Preview, I had explored other tooling that offered some fantastic features. Features that are just a clearly obvious win for the next step in the experience of using Dependabot.

The most notable was the ability for Grouped Updates. Having version updates materialize each in an individual Pull Request can cause a lot of noise. Additionally, each PR may result in individual status check builds against CI/CD. I often run into issues where a Pull Request will fail as a result of requiring a group of updates in sync with each other (you cannot just change one version of a package). It is great to see combined notification emails is already released, but looking forward to Grouped Updates as a pivotal enhancement.

Finally, the one feature I do sincerely miss a lot in Dependabot is the ability to specify that a package is older than a given specified age. I found this to be invaluable in reducing Pull Requests for bug fixes that have just launched in a package only to have a subsequent fix come out the next hour or day again. I prefer to allow for a small “hardening” period of public packages before automatically upgrading. Unfortunately, there is nothing yet on the roadmap for this one.