Skip to main content

Automate dependency updates with dagger

·5 mins

Keeping project dependencies up-to-date is chore for every developer.
renovate is a multi platform tool written in Typescript that let’s you automated those update tasks.
Combine renovate with dagger and you get a full managed CI/CD pipeline that updates all your dependencies.

whats dagger #

Dagger is a “portable devkit for CI/CD pipelines”.
(for more details check the docs here https://docs.dagger.io/1200/local-dev)

It uses docker to run portable job containers and is configured with cue.

I think it is the perfect match for developer task automation and it can be used in almost every environment.

When you are used to CI/CD tools like gitlab or github actions you may be aware of the try and error commit/push loops when developing new pipelines or jobs.

Dagger can be run on your local machine and speeds up the feedback cycle when developing new stuff.

install dagger (with homebrew) #

brew tap dagger/tap
brew install dagger

whats renovate #

Renovate is a multi platform dependency update tool written in Typescript.
It is open source and provides a ton of features for many different languages.
(for more details check the docs here https://docs.renovatebot.com)

It can be run in many different ways. My preference is to use it as a docker container.
You can easily get it from https://hub.docker.com/r/renovate/renovate in the latest version.

how I use both tools together #

setup renovate #

To setup renovate we need to add a renovate configuration file to our project.

I prefer a json file named renovate.json.

touch renovate.json

A basic configuration example #

{
    "$schema": "https://docs.renovatebot.com/renovate-schema.json",
    // the projects default branch we want our updates on
    "baseBranches": ["main"],
    "extends": [
        // the basic renovate config template
        "config:base", 
        // I like semantic commits
        ":semanticCommits", 
        // I dont use the dependency dashboard
        ":disableDependencyDashboard"
    ],
    // tell renovate to ignore the dagger folder
    "ignorePaths": ["**/cue.mod/**"]
}
renovate accepts a wide range of configuration methods. Check the docs for more details https://docs.renovatebot.com/configuration-options/#configuration-options

setup dagger #

The first step is to initialize a new dagger project.

dagger project init

This command creates a cue.mod/ directory inside your project.
This is where all the dagger files can be found.

Next step is to create a custom dagger pipeline.
Create a new *.cue file - I like ci.cue for mine.
In this file we put all our custom code that describes our jobs we want to run in this project.

touch ci.cue

As said earlier, dagger uses cue (a JSON superset) to describe
what to do.

Example:

package ci

// import the required packages from dagger
import (
    "dagger.io/dagger"
)

// "Plan" contains our jobs
dagger.#Plan & {
    actions: {
        mycustomjob: {
        ... job here
        }
    }
}

This job (if complete..) can now be run with

dagger do build

Now we know how a dagger pipeline looks like,
time to add our custom renovate job.

The first thing we need to run our job is a fresh image of renovate. Dagger brings a package to handle docker commands with ease.

Lets import this package.

package ci

// import the required packages from dagger
import (
    "dagger.io/dagger"
    "universe.dagger.io/docker"
)

Now we can use docker commands like docker pull inside our pipeline.

We add a renovate job and pull the :latest image of renovate.
Save it to the _image local job variable.

...
actions: {
    renovate: {
        _image: docker.#Pull & {
            source: "renovate/renovate:latest"
        }
    }
}
...

Now we got a image of renovate, time to use it. Therefor we use docker run and hand over the _image.

To tell renovate what to do, we need to pass a few configuration values to the container before we can run it.

Dagger is able to read different types of values from the current client it is running on. This feature we can use to pass values like an authToken or other sensible data to the container.

To read client environment variables you only need to export them.

export GITLAB_TOKEN=<GITLAB_API_TOKEN>
export GITHUB_TOKEN=<GITHUB_API_TOKEN>

Once done, we can read them with dagger.

dagger.#Plan & {
    client: env: {
        GITLAB_TOKEN: dagger.#Secret
        GITHUB_TOKEN: dagger.#Secret
    }
    ...
}

Put it all together, an we got our first dagger pipeline.

package ci

import (
    "dagger.io/dagger"
    "universe.dagger.io/docker"
)

dagger.#Plan & {
    client: env: {
        GITLAB_TOKEN: dagger.#Secret
        GITHUB_TOKEN: dagger.#Secret
    }
    actions: {
        renovate: {
            _image: docker.#Pull & {
                source: "renovate/renovate:latest"
            }
            docker.#Run & {
            input:  _image.output
                env: {
                    // the access-token to access our project (gitlab project here)
                    RENOVATE_TOKEN:                 client.env.GITLAB_TOKEN
                    // a github access-token to access package updates and CHANGELOG on github
                    GITHUB_COM_TOKEN:               client.env.GITHUB_TOKEN
                    // tell renovate where your project is hostes (gitlab, github, bitbucket)
                    RENOVATE_PLATFORM:              "gitlab"
                    // the path of your project
                    RENOVATE_REPOSITORIES:          "my/gitlab/projectpath"
                }
            }
        }
    }
}

To find out more about RENOVATE_PLATFORM and RENOVATE_REPOSITORIES check out the documentation https://docs.renovatebot.com

To find out more about the docker package you can browse through the cue-files inside your project directory.
./cue.mod/pkg/universe.dagger.io/docker

run renovate the first time #

Once we are finished with our new pipeline we have to download all the dependencies we defined inside the import statements.

dagger project update

Now we can run a local instance of renovate.

dagger do renovate

used tools #