Renovate Bot: 3 advanced tips and tricks – Part I

This is part one of a two-part series that provides tips for advanced Renovate Bot users. Part 1 explains some important, basic Renovate concepts, illustrates how Renovate creates and updates PRs as a flow chart, goes into details about Renovate’s “post-upgrade tasks” feature, and reveals how to effectively diagnose Renovate issues.

Originally posted on 2023-09-03, updated on 2026-08-13.

Introduction to Renovate

Renovate (Bot) is a CLI tool that regularly scans your Git repositories for outdated dependencies. If it finds any, it automatically creates a pull request (PR) that updates the dependency. I highly recommend my Renovate introduction article to get you started with the basics, and my cheat sheet article for the first steps to tune your configuration.

This article is for Renovate users who have already worked with Renovate for a few days or weeks, and would like to know more about some of Renovate’s capabilities. It contains several lessons I learnt over several years of using it.

Tip 1: Check your understanding of basic concepts

  • Understand which configuration options exist:
    • Global configuration options: these are configured by admins (this could be you, if you self-host Renovate). They tell Renovate what to do for every repository. See the documentation for the complete list of options. I highly recommend you use the config.js file. It is easier to read than using environment variables or CLI arguments, and it lets you set secrets from environment variables (instead of hard-coding them as plain text in a config.json file). The global configuration may also contain repository-specific configuration options (see next point).
    • Repository-specific configuration options: these are stored in the renovate.json file in the repositories visited by Renovate, documented here. Most config options listed there can be placed on the root level of the renovate.json file, or anywhere in deeper levels (for instance, you may place the description config option on any level in your JSON file, to document a configuration option). However, if the config option explicitly defines parents (exemplary: packageRules.something or hostRules.something), you may only place it within these parents.
    • For each visited Git repository, Renovate automatically merges the global and the repository-specific configuration. As one would expect, options you set in the repository-specific configuration take precedence over global options.
  • Understand the difference between managers and data sources:
    • (Package) Managers (docs) are basically file parsers that find (pinned) dependencies in your repository. Each manager knows which files to look for (e.g., requirements.txt for pip_requirements), and can parse their internal structure to identify dependencies.
    • Data sources (docs) are basically (HTTP) clients that find the newest version for a specific dependency (that a manager found) in some (remote) registry (e.g. registry.npmjs.org). A data source knows how to handle the API of that registry.
    • Most managers use one specific data source. Some managers (e.g. helmfile) may use multiple data sources. Conversely, any specific data source may be used by one or more managers.

Tip 2: Handling existing or missing PRs and branches

The following simplified pseudo-code and diagram explain what Renovate does when visiting your repository. Note that for the sake of simplicity, some advanced configuration options (e.g., scheduling) are not covered:

Renovate Bot Branch and PR handling

In more words:

  • 1) Renovate builds a list of all dependency updates it found in your repository, according to your renovate.json configuration (e.g. dropping those dependencies for which a packageRule sets the enabled: false option)
  • 2) If you configured the groupName option in one or more packageRules objects: Renovate aggregates the dependency updates found in step 1 to a smaller list of updates. The name of the dependency changes to <groupName>.
  • 3) For each dependency update:
    • If Renovate finds an exactly-matching PR and branch that Renovate created in the past, where both the dependency name and the new version match (Renovate uses simple pattern matching, e.g. PR titles have the form “update dependency <dependency name> to <new version>“):
      • If the matched PR is still open:
        • If there is just one commit (made by Renovate’s account) in the corresponding branch:
          • If you enabled automerge using a packageRule matching this dependency update, and there are CI/CD pipelines defined, which have (now) passed: Renovate merges the PR for you
          • Else: Renovate leaves the PR and branch as-is
        • If at least one commit was made by someone other than Renovate: Renovate leaves the PR and branch as-is. It assumes that you pushed commits that fix the branch, e.g., failing tests. Renovate avoids rebasing the branch to avoid discarding your commits. Even if you configured automerge for this dependency update (and tests are now successful), Renovate will not merge this PR. It hands over all responsibility for that PR and branch to you. Renovate leaves a comment in the PR, explaining that behavior.
      • Else (the matched PR was closed by you, or merged): Renovate ignores this dependency. Renovate will only create a new PR+branch if the dependency’s new version is even newer than the version of the currently-matched PR/branch
    • Else if Renovate finds a PR+branch that matches only regarding the dependency name, not the dependency version, which may be e.g. older in the PR:
      • If the matched PR is still open:
        • If there is just one commit (made by Renovate’s account): Renovate “recycles” the matched outdated PR by rebasing the corresponding branch, creating a new commit that contains the new version number of the dependency. Renovate also updates the PR’s title to contain the new version.
        • If at least one commit was made by someone other than Renovate: Renovate leaves the PR and branch as-is. It assumes that you are fixing the branch, e.g. after tests have failed, and avoids rebasing the branch to avoid discarding your commits.
      • Else (the matched PR was closed by you, or merged): Renovate creates a new PR+branch for the dependency update
    • Else (no matching PR was found): Renovate creates a new PR+branch for the dependency update
  • 4) For each open PR in the repository not matched in step 3 that Renovate identifies as one of its own (considering the Git commit identity + SCM username):
    • Renovate renames the PR title by appending the string “ – autoclosed”
    • Renovate closes the PR and deletes the corresponding branch

Typical reasons for step 4 are:

  • You changed the Renovate config since the last Renovate run. For instance, if Renovate found NPM-related updates yesterday, but then you added an object {"matchDatasources": ["npm"], “enabled”: false} to your packageRules object today, Renovate would auto-close those NPM-related PRs today. Or maybe you added a new groupName package rule that bundles multiple dependencies whose individual PRs are now obsolete.
  • A dependency is no longer found in your repository, e.g., if you removed a dependency from your package.json and yarn.lock file.
  • Renovate was unable to find the newest version of a pinned dependency, because the registry was (temporarily) unreachable (e.g. because it was down, credentials have become invalid, etc.)

Make sure to also read https://docs.renovatebot.com/key-concepts/pull-requests/ for additional details.

Tip 3: Post-upgrade tasks

If you are self-hosting your Renovate instance, you can use Renovate’s post-upgrade tasks feature. A post-upgrade task is an arbitrary shell command that Renovate runs right before creating the commit for the branch that updates the dependency. If the shell command modifies any files in your Git repository, you can (optionally) have Renovate commit them, along with the file Renovate would have committed anyway (where it updated the version number of the affected dependency).

Here are a few real-world examples where post-upgrade tasks are useful:

  • Sending a notification to some external system, e.g. via email or Slack
  • Downloading source files of the dependency. For instance, suppose you use Renovate to update third-party components installed via Helm into your Kubernetes cluster (e.g., Traefik). To increase the confidence that a new Helm chart version does not break anything, the best way is to diff the old vs. new version of the Helm chart (particularly the values.yaml and the files in the chart’s templates folder). With a post-upgrade task command such as “helm pull <chart URL or repo/chartname> --untar --untardir upstream-chart-info” you can tell Renovate to pull the Helm chart’s source and commit it into a dedicated folder (here: “upstream-chart-info“).
  • Run a templating engine that generates files: especially in larger infrastructures, a platform engineering team might no longer write all those manifests that contain pinned dependencies (e.g., YAML files) by hand, but have them generated (e.g., with Terraform’s local_file, Cue, or Dhall) from a central file, because this improves maintainability. Suppose these generated files are also committed to Git and that you have written a Regular Expression Manager to find updates in that central file (more details about regex managers in part 2 of this series). In such a scenario, it makes sense to have Renovate run the generation (templating engine) automatically in a post-upgrade task.

While you could also define and run such automation tasks via other means, e.g. in a separate CI/CD job, the downside of doing so is that if such jobs modify the Git branches created by Renovate (with a different committer identity than the one used by Renovate), Renovate would no longer update the corresponding PRs and branches, because it (incorrectly) assumes that a (human) user made some (manual) changes. A post-upgrade task avoids this problem.

Using secrets in post-upgrade tasks

Renovate runs the command of a post-upgrade task in a new sub-shell (if you configured allowShellExecutorForPostUpgradeCommands) that lacks any of the (Bash) environment variables you might have configured in the shell that runs Renovate in your self-hosted setup. If the command you define in a postUpgradeTasks object requires secrets/credentials, you need to use Renovate’s secrets feature: in your global configuration (config.js), you define a secrets object (with one or more key-value-pairs), which you then reference using the syntax {{ secrets.NAME_OF_SECRET }} inside your renovate.json in the command of your postUpgradeTasks object.

Tip 4: Diagnosing issues using Renovate debug logs

Renovate’s behavior and its configuration options are quite complex. The consequence is that both Renovate admins and users struggle with getting Renovate to behave the way they want to. Also, admins and users sometimes do not notice subtle problems that creep in over time.

Renovate offers logs (a.k.a. debug logs). But unfortunately, analyzing them is difficult for several reasons:

  1. The logs (emitted at debug level) are very verbose. Consequently, important information often occurs in debug-level lines, not warning- or error-level lines, and is thus often missed.
  2. Sometimes the logs are so large (when processing multiple repositories with many dependency updates) that the log viewer application (e.g., a text editor or web browser) is unable to process them. It simply crashes, or scrolling becomes laggy.
  3. When developers try to ask their AI (coding) agents to look for issues in a Renovate log, the agents too often miss information in large logs, or use way too many tokens for analysis.

Consequently, when users cannot find a solution, they accept a suboptimal Renovate configuration and become frustrated with Renovate.

To help users with manual (and AI-assisted) analysis, I built the renovate-log-parser CLI, which supports you graphically and in the terminal. You can find all details in this blog post.

Conclusion

I hope the tips presented in this article help you get more out of Renovate. Especially tip #2 should help everyone on your team who is wondering when Renovate creates, deletes, or updates PRs. Check out part 2 of this series, which is packed with even more tips.

Leave a Comment