DEV Community

Lenra Developers
Lenra Developers

Posted on

Lenra's automatic management of dependencies

My Workflow

How do you manage with all versions of your dependencies between your huge projects?

My answer here.

What really is the issue?

At Lenra, we have several Git projects that often require modifying the link versions in the dependency files. But doing it manually slows down the release process and wastes too much time for our development teams who can't focus on the features.

The solution was to develop some GitHub Actions in a workflow executed at each release of a new version of a dependency to modify the file that links to it in each project using it.

How it works ?

1. Define the shape of your projects

We will start by presenting our Git projects in the following form for some evident purposes of dependencies:

Repo-A -> Repo-B, Repo-C
Repo-B -> Repo-C
Enter fullscreen mode Exit fullscreen mode

As you can see in the example directory, we have 3 Git repositories that depend on each other. In our example, repository "B" needs repository "A" to compile. And as it is quite tedious to always have to manually edit the right dependency files, this action will take care of it, if it is well configured.
If we continue our exploration, the "C" repository also requires the "A" repository in addition to the "B" repository. Projects of a certain size can have pretty complex mesh links which can be a source of errors.

2. Understanding links between each workflow

When you publish a new release on the repository "A", this action will automatically create a Pull Request on the repository "B" and "C" to update the correct files and change its own link in dependancy file(s).
And now, when you merge the PR on the repository "B", and create a new release, it will update the PR on the repository "C" to add this changes.

Now we can accept changes on the repository "C" to update its version of "A" and "B".

How to use it ?

Using the previous example, you need to trigger the action on the source repository. I'll name it .github/workflows/on_release.yml.

This file must call the Action that will populate the release on the requested repositories. To do it we need to define this step in your job :

      - name: create_pr
        uses: lenra-io/create-or-update-pr-action/utils/trigger_workflow@v1
        with:
          target_ref: ${{ steps.extract_tag.outputs.target_ref }}
          target_repository: "${{ github.repository_owner }}/repo-B","${{ github.repository_owner }}/repo-C"
          target_workflow: create_or_update_pr.yml
          params: |
            {
              "version": "${{ steps.get_version.outputs.tag }}",
              "origin": "repo_a",
              "release_notes": "${{ steps.get_version.outputs.release-notes }}"
            }
          token: ${{ secrets.WORKFLOW_GITHUB_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

I use a custom GitHub Token because action running the default GitHub secret ${{ secrets.GITHUB_TOKEN }} can't trigger any other workflow so that won't make things appends.

As you can see, this step will trigger a custom workflow defined in another repository chooses from target_repository, target_ref and target_workflow. And you can customize some information during this execution as parameters using the params field, you can add everything you need on the remote execution but that need to fit the input declaration.

This workflow must be run on each release, so be sure that you'll use the following declaration at the top of the file :

on:
  release:
    types: [published]
Enter fullscreen mode Exit fullscreen mode

Now this first step is defined, you need to create the remote workflow to receive this event and update the file you need.
So I'll call this new file .github/workflows/create_or_update_pr.yml on the remote repository.

      - name: create_pr
        uses: lenra-io/create-or-update-pr-action@v1
        with:
          name: 'Update dependencies'
          token: ${{ secrets.WORKFLOW_GITHUB_TOKEN }}
          script: |
            ${{ steps.setup-yq.outputs.yq-binary }} eval ".dependencies.${{ github.event.inputs.origin }}.git.ref = \"${{  github.event.inputs.version }}\"" -i project.yaml
            git add project.yaml

            RELEASE_NOTES="${{ github.event.inputs.release_notes }}"
            RELEASE_TYPE="${RELEASE_NOTES/:*}"

            git commit -m "${RELEASE_TYPE}: Upgrade ${{ github.event.inputs.origin }} to ${{ github.event.inputs.version }}
            ${RELEASE_NOTES}"
Enter fullscreen mode Exit fullscreen mode

On this step you need to use the create-or-update-pr GitHub Action we've already defined and make the change you want on the script field. Don't forget to commit it, but you didn't need to push it, the action will do anything else for you.

Here I update the yaml file and change the dependency version using the yq command.

And that all, you can now focus on your work.

Go deeper

This can be awesome to use in your projects with sementic-release to make releases even faster and erase errors of dependency managements.

Of course you can ask for new features on the GitHub Action repository or contribute yourself by submitting a new pull request.

Now you can test it by publishing theses 3 repositories on your own account/organization to see how it works. (Don't forget to create the WORKFLOW_GITHUB_TOKEN secret in the settings of each repository.)

Submission Category:

Maintainer Must-Haves

Yaml File or Link to Code

GitHub logo lenra-io / create-or-update-pr-action

A simple but powerful GitHub Action to link workflows and manage dependencies between projects. #actionshackathon21

Create or update PR Action

A simple but powerful GitHub Action to link workflows and manage dependencies between projects.

Usage:

To learn accurately how to use it, you must see the guide here

Quick Example:

      # Call `Create or update PR` GitHub action
      - name: create_pr
        uses: lenra-io/create-or-update-pr-action@v1
        with
          # The name of the PR to be created.
          name: 'Update dependecies'
          # The token used to create the PR. 
          # I didn't use the `secrets.GITHUB_TOKEN` here because this token can't trigger workflow event if we push something or create a PR.
          token: ${{ secrets.WORKFLOW_GITHUB_TOKEN }}
          # Write a little script called just before the PR creation or update.
          # This example will upgrade the version inside of the pubspec.yaml and publish it in a new PR
          script: |
            # Update the requested dependency version in the pubspec.yaml file
            ${{ steps.setup-yq.outputs.yq-binary }} eval
Enter fullscreen mode Exit fullscreen mode

Additional Resources / Info

Any needed resources is in the GitHub repository of the action, you can use it from the GitHub Marketplace and any contribution are welcome.

This project is under MIT Licence.

Collaborators:

Discussion (0)