dcsimg
 

Targeting Specific Angular Dependencies with WhiteSource Renovate

Tuesday Apr 20th 2021 by Rob Gravelle

We dive into the second part of our series on on Angular dependencies in Whitesource Renovate and how to to target specific dependencies to configure.

Targeting Specific Angular Dependencies with WhiteSource Renovate

Targeting Specific Angular Dependencies with WhiteSource Renovate

Renovate by WhiteSource is a free tool that manages dependency updates automatically. It's a bot that keeps project dependencies up-to-date using Pull Requests (PRs) and/or branches. It scans repositories for dependencies inside package manager files such as package.json (npm/yarn) and submits PRs with updated versions whenever they are found.

This series is divided into two parts: in part 1, we covered how to target GitHub branches dynamically. This installment describes how to configure Renovate to target specific dependencies.

Note: this series assumes that you have a basic working knowledge of Renovate, so we'll be skipping over the installation procedure and other steps for getting started.

Update Rules Summary

Our task here today will replicate the update rules that I recently implemented at my workplace. We only had three requirements:

  1. On the default (master) branch, take all updates to minor and patch versions for internal libraries.
  2. On release and sprint branches, update the patch number for common-assets library only.
  3. Third party dependencies should not be updated on any branch.

On the surface, these rules might seem trivial to configure. Not so! As it turns out, Renovate requires a very specific approach for limiting its scope.

Disabling Updates for All Dependencies in Angular

It's not actually possible to have Renovate only target certain libraries, so instead, we must begin by disabling everything on all base branches:

"packageRules": [
  {
    "description": "Disable all updates on all base branches to begin with",
    "matchPackagePatterns": ["*"],
    "enabled": false
  }
]

We can let some packages through by including one of the exclude attributes such as excludePackageNames, excludePackagePatterns, and excludePackagePrefixes. Here's how to allow updates on our internal dependencies, which start with "@acme":

"packageRules": [
  {
    "description": "Disable all updates on all base branches to begin with",
    "matchPackagePatterns": ["*"],
    "excludePackagePatterns": ["^@acme"],
    "enabled": false
  }
]

Pattern attributes accept Regular Expressions for fine-grained matching. The caret (^) character is an anchor symbol for matching at the start of a string.

Configuring Per-branch Package Rules in Angular

The downside of the above configuration is that it applies to all branches. Since we require branch-specific actions, we need to define separate package rules for each. Here are some package rules that enable "@acme" packages on master, but limit updates to the "@acme/common-assets" library on sprint and release branches:

"packageRules": [
  {
    "description": "Disable all updates on all base branches to begin with",
    "matchPackagePatterns": ["*"],
    "enabled": false
  },
  {
    "description": "Enable @acme packages on master",
    "matchBaseBranches": ["master"],
    "matchPackagePatterns": ["^@acme"],
    "enabled": true
  },
  {
    "description": "Enable @acme/common-assets on sprint and release branches",
    "matchBaseBranches": ["sprint", "release"],
    "matchPackageNames": ["@acme/common-assets"],
    "enabled": true
  }
]

Specifying Which Semantic Version (Major, Minor, Patch) To Update

It is not uncommon to disable automatic updates on the major version number because of the amount of changes that may entail. For our purposes, we need to disable major updates on the master branch, as well as disable both major and minor updates on sprint and release branches.

Just as we did for branches, we must disable updates for the version type(s) that we wish to prevent. Here are the rules for that:

"packageRules": [
  // ...
  {
    "description": "Disable @acme major updates on master",
    "matchBaseBranches": ["master"],
    "matchPackagePatterns": ["^@acme"],
    "matchUpdateTypes": ["major"],
    "enabled": false
  },
  {
    "description": "Disable @acme/common-assets minor and major updates on sprint and release branches",
    "matchBaseBranches": ["sprint", "release"],
    "matchPackageNames": ["@acme/common-assets"],
    "matchUpdateTypes": ["major", "minor"],
    "enabled": false
  }
]

Automerging Updates

In addition to updating dependencies, Renovate can also automerge the PRs that it raises, so that no human intervention is required at all. We can see if automerge is enabled on the PR:

Renovate-Config-Javascript

Like other configuration options, automerge may be enabled at the branch, package, and even version level. Here's a package rule that turns on automerge across the board:

"packageRules": [
  // ...
  {
    "description": "automerge every PR",
    "matchPackagePatterns": ["*"],
    "automerge": true
  }
]

We plan on eventually enabling automerge on all of our internal dependencies, but not for third-party ones. In that case, we can just change the matchPackagePatterns value to ["@acme"] to target our own libraries.

Automerge Caveats

By default, Renovate will not automerge until it sees passing status checks and test runs for the branch. If you have no tests but still want Renovate to automerge, you need to add "requiredStatusChecks": null to your configuration.

Moreover, if you have protected your base branch with a list of allowed committers, and Renovate is not on that list, then naturally automerge can't work. If you are running the hosted WhiteSource Renovate App on github.com, you can also install the helper apps renovate-approve and renovate-approve-2 and they will mark all automerging PRs by Renovate as approved.

Conclusion

As the list of application dependencies grows, using an automatic version updating bot like WhiteSource Renovate only makes sense. In practice, I found Renovate to be quite difficult to configure and test. Not only were the rules for targeting specific dependencies somewhat unintuitive, but Renovate never seemed to work in a consistent manner across projects. For those reasons, getting it up and running proved to be a far more time-consuming endeavor that we expected it to be. Not to discourage anyone from trying it, but be prepared for a substantial learning curve as well as some bumps along the way.


Rob Gravelle resides in Ottawa, Canada, and has been an IT guru for over 20 years. In that time, Rob has built systems for intelligence-related organizations such as Canada Border Services and various commercial businesses. In his spare time, Rob has become an accomplished music artist with several CDs and digital releases to his credit.

Home
Mobile Site | Full Site