Automatic Dependency Updates Using Renovate on Mamikos Self-hosted GitLab

Roy Margasa
mamitech
Published in
7 min readApr 17, 2024
Two people renovating a building
Illustration taken from https://unsplash.com/@thebarlemy

Background

Like the other usual frontend tech stacks, Mamikos has a lot of web applications that use Nodejs and their packages. As time goes on, a lot of our Node dependencies have security vulnerabilities and the dreadful of all: deprecated. To avoid these problems, we need to check and update each existing dependency. Without additional tools to automatically update the dependencies, that task will be very manual and will be very time consuming.

Because Mamikos is using self-hosted Gitlab, the most suitable tool for our needs is Renovate (Dependabot is still in WIP for Gitlab). Unfortunately, the tutorial for Renovate for self-hosted Gitlab is very rare and a little bit outdated. Therefore, this article was written and hopefully can provide a streamlined guide.

What are our expectations for implementing Renovate on Mamikos’ repos?

  • Check dependencies version automatically and periodically
  • Automatically assign MR assignee and reviewer
  • Detect and update based on patch, minor, and major version changes
  • Give informations if there’s package vulnerability
  • Can be limited to only frontend tech stack (or only for package.json)

The initialization for this Renovate bot is quite puzzling because Renovate’s own documentation is too verbose so it’s very difficult to learn at first and there is an example but with very short explanation on Gitlab’s Renovate runner example.

Implementation

Based on the result of our research, here are the setup steps that we need to carry out:

1. Create a new repo on Gitlab for the Renovate bot

Simple enough, create an empty project/repository. This repo will be used to run and configure Renovate. Clone this new repo to our local machine.

2. Add new CI/CD variables on the Renovate bot repo

From our new repository on GitLab, open Settings → CI/CD → Variables menu and add these 3 new variables:

  • RENOVATE_TOKEN: The value for this variable can be obtained from GitLab’s User Settings → Access Token menu. It’s advisable that this token should be generated from a specific Gitlab account that will be used for automation and that account must have access to the target repo.
  • GITHUB_COM_TOKEN: This token is used so the bot can retrieve the dependency’s changelog. The value can be obtained from Github Settings → Developer Settings → Personal access token menu.
  • RENOVATE_EXTRA_FLAGS: Filled with the name of the GitLab project that we want to check. If there’s more than one project, separate the project names with white space.
An example of project name

3. The Renovate Configurations

Create a renovate.gitlab-ci.yml on the root directory of the Renovate Bot repo. This file will be used on the Gitlab pipeline setup. Here’s the content of the file:

variables:
RENOVATE_BASE_DIR: $CI_PROJECT_DIR/renovate
RENOVATE_ENDPOINT: $CI_API_V4_URL
RENOVATE_PLATFORM: gitlab
RENOVATE_ONBOARDING_CONFIG: '{"$$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["config:recommended"] }'
RENOVATE_OPTIMIZE_FOR_DISABLED: 'true'
RENOVATE_REPOSITORY_CACHE: 'enabled'
RENOVATE_LOG_FILE: renovate-log.ndjson
RENOVATE_LOG_FILE_LEVEL: debug
CI_RENOVATE_IMAGE: ghcr.io/renovatebot/renovate:37.279.3@sha256:fc6ab8d230170fd405a02aa29f8708d3c5dbb6f543a948671446235b479d0bd3

.renovate:
cache:
key: ${CI_COMMIT_REF_SLUG}-renovate
paths:
- renovate/cache/renovate/repository/
image: ${CI_RENOVATE_IMAGE}
script:
- renovate $RENOVATE_EXTRA_FLAGS

renovate:
extends: .renovate
stage: deploy
resource_group: production
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
artifacts:
when: always
expire_in: 1d
paths:
- '$RENOVATE_LOG_FILE'

Create a default.json file and fill it with the Renovate configuration. For Mamikos' needs, we can break it down into:

"baseBranches": [
"develop"
],
"enabledManagers": [
"npm",
"nvm"
],
  • Create a “dependencies” label for merge requests created by Renovate
"labels": [
"dependencies"
],
"assignees": [
"roy"
],
"reviewers": [
"tri"
],
"vulnerabilityAlerts": {
"labels": [
"security"
]
},
  • We want to create the merge requests manually because we need to check if our application can be built or not if the package is updated
"dependencyDashboardApproval": true,

If we combine the previous config, our default.json content will be:

{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":dependencyDashboard"
],
"baseBranches": [
"develop"
],
"enabledManagers": [
"npm",
"nvm"
],
"labels": [
"dependencies"
],
"assignees": [
"roy"
],
"reviewers": [
"tri"
],
"vulnerabilityAlerts": {
"labels": [
"security"
]
},
"dependencyDashboardApproval": true,
}

4. Create a .gitlab-ci.yml file

.gitlab-ci.yml file is a configuration file that will be used to run the GitLab pipeline. The content of the file will be taken from the guide on Gitlab Renovate. The value for the project will be the name of the Renovate bot repo, and the value for the file is the previous step 3.

include:
- project: 'mamikos/renovate-runner-bot'
file: '/renovate.gitlab-ci.yml'

Finally, we have finished our configuration for the Renovate bot repository, we need to create the pipeline scheduler. (If you want to run pipeline without scheduler, you must add new rule in renovate.gitlab-ci.yml file, or the pipeline won’t run at all.)

Here’s an example of our working pipeline:

SCV good to go, sir.

Initializing Renovate on Existing Mamikos’ Projects

After the pipeline is triggered, Renovate will make a merge request on our target repository.

Renovate onboarding MR

The content of this merge request is only a renovate.json file. Because we already created and have a default.json file, we need to edit this renovate.json. We need to add a new .nvmrc file to lock the project’s Node version and let Renovate know what’s the current Node version.

Using the local presets reference, the content of renovate.json will be changed from:

{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
]
}

Into:

{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>mamikos/renovate-runner-bot"
]
}

And then, don’t forget to merge the MR.

Review the Dependency Dashboard by Renovate Bot

On the next triggered scheduled pipeline, Renovate will create an issue with “Dependency Dashboard” as the title.

It’s alive! It’s aliiiiiive!

As the title suggests, this issue will be our dashboard to decide which package we want to update, which MR(s) that Renovate already generated, and ignored MR or package.

After we checked the package checkbox that we wanted to update, we needed to wait for the Renovate bot scheduled pipeline to be triggered again.

After the pipeline is triggered, the Renovate will create an update package MR that we already checked previously:

Toasty!

What is the meaning of the Age, Adoption, Passing, and Confidence label? The explanation for these labels is on merge confidence Renovate documentation:

  • Age: The age of the package
  • Adoption: The percentage of this package’s users (within Renovate) who are using this release
  • Passing: The percentage of updates that have passed tests for this package
  • Confidence: The confidence level for this update

The confidence level is a result of the Renovate algorithm that can be used as a rough reference if the package is safe to be updated without manual checking.

Conclusion

Does the Renovate that we have set up meet the expectations that we mentioned in the background section of this article?

  • Check dependencies version automatically and periodically ✅
    Regular checking can be done using the GitLab pipeline scheduler.
  • Automatically assign MR assignee and reviewer ✅
    Using assignees and reviewers. configuration option.
  • Detect and update based on patch, minor and major version changes ✅
    Renovate dashboard has separate checkboxes for minor and major versions. Unfortunately, Renovate can’t separate between patch and minor versions.
  • Information if there’s package vulnerability ❓
    Even though there’s a configuration for vulnerability alerts, so far there’s no MR that’s related to vulnerability.
  • Can be limited to only frontend tech stack (or only for package.json) ✅
    Using enabled managers configuration. For a more comprehensive list, you can check it on the supported managers’ documentation page.

Even though we already using Renovate, there are 3 things that must be done manually:

  • Some dependencies have breaking changes update, so we must do manual checking in our local machine first.
  • Can’t detect vulnerability at the sub-dependency level, so we must depend on Trivy and resolutions in package.json.
  • Auto merge based on confidence level must use the Mend API key and it’s not free.

There are still many things that can be learned from Renovate, the configuration is so exhaustive. But for the current needs of Mamikos’ front end, it is sufficient for now.

Hopefully, this article helps those who want to set up Renovate configuration but feel overwhelmed by reading Renovate documentation. Cheers! 🍻

Mamikos’ Renovate Bot

--

--