How to update application dependencies in a CI/CD pipeline

Cloud Survey 2021

Benchmark your organization against competitors and other industries. Share your experiences and receive the free Cloud report.

In this blog I introduce the Renovate bot, a great tool to automate the update application dependencies in your source code.

In my previous blog I introduced my home-grown utility "fromage". It detects references to out-of-date container image references in Dockerfiles and updates them automatically . It was fun to write this utility in Go, but the Renovate bot is far better: It automates dependency updates for a wide variety of tools and languages. The Renovate bot detects and updates dependencies in Bazel, Docker, Golang, Java, JavaScript, Node.js, Nuget, PHP, Python, Ruby and more.

getting started

It is really simple to start with the Renovate bot. You just add the configuration file
to the main branch of the repository and you are good to go! Just run the bot at scheduled intervals and it will create pull requests whenever an update is available. In this blog I am going to use the fromage repository to demonstrate its usefulness:

clone the repository

To clone the repository, type:

$ git clone --quiet git@github.com:binxio/fromage.git

configure renovate bot

To allow the bot to renovate your repository, add a configuration as shown below:

$ cd fromage
$ cat > renovate.json <<!
{
  "\$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:base",
    ":disableRateLimiting"
  ]
}
!
$ git add renovate.json
$ git commit -m 'add renovate configuration'
[main 4944645] add renovate configuration
 1 file changed, 7 insertions(+)
 create mode 100644 renovate.json

There are tons of configuration options available. Here I used the base configuration and disabled the rate limiting to show the full effect of the bot.

push to Gitlab

To use the Renovate bot on a Gitlab repository, type:

$ GITLAB_USERNAME=$(ssh git@gitlab.com 2>&1 | \
  sed -n -e 's/Welcome to GitLab, @\(.*\)!/\1/p')

$ git remote set-url origin git@gitlab.com:$GITLAB_USERNAME/fromage.git
$ git push --quiet
remote:
remote: The private project mvanholsteijn/fromage was successfully created.
remote:
$ cd ..

Of course, the bot will work with any major git repository provider.

configure the bot

To configure the renovate bot, you create a Javascript file called config.js:

$ mkdir -p config
$ cat > config/config.js <<!
module.exports = {
  repositories: ['$GITLAB_USERNAME/fromage'],
  endpoint: 'https://gitlab.com/api/v4/',
  git_author: 'Renovate Bot <noreply@renovatebot.com>',
  platform: 'gitlab',
  onboardingConfig: {
    extends: ['config:base', ":disableRateLimiting"]
  }
};
!

setting the tokens

To run the bot, you need access tokens for both Gitlab and Github:

$ read -sp 'github token: ' GITHUB_TOKEN
github token:
$ read -sp 'gitlab token: ' GITLAB_TOKEN
gitlab token:

The Github token only needs to provide permission to read public repositories. This will add the release notes to the pull requests for updated dependencies. The Gitlab token needs api, read_user and write_repository permissions.

running the renovate bot

There are many ways to run the Renovate bot. To use the docker container image, type:

$ docker run --platform linux/amd64 \
  -v $PWD/config/:/config/ \
  -v $HOME/.ssh:/home/ubuntu/.ssh \
  -e RENOVATE_CONFIG_FILE=/config/config.js \
  -e RENOVATE_TOKEN=$GITLAB_TOKEN \
  -e GITHUB_COM_TOKEN=$GITHUB_TOKEN \
  renovate/renovate

INFO: Repository started (repository=mvanholsteijn/fromage)
      "renovateVersion": "25.21.4"
INFO: Dependency extraction complete (repository=mvanholsteijn/fromage)
      "baseBranch": "main",
      "stats": {
    "managers": {
      "cloudbuild": {"fileCount": 1, "depCount": 1},
      "dockerfile": {"fileCount": 1, "depCount": 2},
      "gomod": {"fileCount": 1, "depCount": 9}
    },
    "total": {"fileCount": 3, "depCount": 12}
      }
INFO: Branch created (repository=mvanholsteijn/fromage, branch=renovate/golang.org-x-crypto-digest)
      "commitSha": "30783c9"
INFO: PR created (repository=mvanholsteijn/fromage, branch=renovate/golang.org-x-crypto-digest)
      "pr": 1,
      "prTitle": "Update golang.org/x/crypto commit hash to c07d793"
INFO: Branch created (repository=mvanholsteijn/fromage, branch=renovate/index.docker.io-alpine-git-2.x)
      "commitSha": "75c0c25"
INFO: PR created (repository=mvanholsteijn/fromage, branch=renovate/index.docker.io-alpine-git-2.x)
      "pr": 2,
      "prTitle": "Update index.docker.io/alpine/git Docker tag to v2.30.2"
INFO: Branch created (repository=mvanholsteijn/fromage, branch=renovate/golang-1.x)
      "commitSha": "ca9a287"
INFO: PR created (repository=mvanholsteijn/fromage, branch=renovate/golang-1.x)
      "pr": 3,
      "prTitle": "Update golang Docker tag to v1.16"
INFO: Branch created (repository=mvanholsteijn/fromage, branch=renovate/github.com-google-go-containerregistry-0.x)
      "commitSha": "74648ca"
INFO: PR created (repository=mvanholsteijn/fromage, branch=renovate/github.com-google-go-containerregistry-0.x)
      "pr": 4,
      "prTitle": "Update module github.com/google/go-containerregistry to v0.5.0"
INFO: Branch created (repository=mvanholsteijn/fromage, branch=renovate/github.com-kevinburke-ssh_config-1.x)
      "commitSha": "be1e5bb"
INFO: PR created (repository=mvanholsteijn/fromage, branch=renovate/github.com-kevinburke-ssh_config-1.x)
      "pr": 5,
      "prTitle": "Update module github.com/kevinburke/ssh_config to v1"
INFO: Repository finished (repository=mvanholsteijn/fromage)
      "durationMs": 83746

As you can see, the renovate bot created five pull requests for all outdated dependencies. Each pull request is on a separate branch. All the branches start with the name renovate.

changes

To see the changes of the renovate bot, type:

$ get fetch --all
$ for b in $(git branch  --all | grep renovate); do
echo $b ; git diff --numstat main $b
done

remotes/origin/renovate/github.com-google-go-containerregistry-0.x
1       1       go.mod
30      0       go.sum
remotes/origin/renovate/github.com-kevinburke-ssh_config-1.x
1       2       go.mod
10      9       go.sum
remotes/origin/renovate/golang-1.x
1       1       Dockerfile
remotes/origin/renovate/golang.org-x-crypto-digest
1       1       go.mod
8       0       go.sum
remotes/origin/renovate/index.docker.io-alpine-git-2.x
1       1       Dockerfile

As you can see, the bot changed both Go module dependencies as well as the Dockerfile image references. You can inspect the pull requests it created and merge when appropriate to update application dependencies.

Conclusion

The renovate bot is an essential utility to keep a multitude of dependencies up-to-date. In this demonstration, I used the command line variant on my local machine. But you can use both hosted or self-hosted variants of the bot. I recommend to use the Renovate bot in any Cloud Native CI/CD build pipeline.

Photo by John Barkiple on Unsplash

Mark van Holsteijn is a senior software systems architect, and CTO of binx.io. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Share this article: Tweet this post / Post on LinkedIn