Lerna Monorepo on Azure DevOps

As an addition to the last article I want to mention what makes the publish process on Azure DevOps possible.

Coming back to the article about the Lerna monorepo we still need to see what is necessary to make this setup work from the CI/CD provider (in this case Azure DevOps). While the Lerna commands will certainly work we still need to put in a bit of work on the actual CI/CD pipeline.

Let's first see what we actually want to have. The following diagram shows our wanted process:

azuredevops-cicd

We start with a Git repository that is mirrored at GitHub. The GitHub repository contains some hooks that trigger a process at Azure DevOps. From there we need to distinguish between three potential cases:

  • We have a pull request validation (only build and test)
  • We have a change to develop (build, test, and if all goes well publish a preview of the available packages)
  • We have a change in master (build, test, and if all goes well publish the full thing, plus push back changes made to package.json files and a new Git tag)

Since we do a push back we will have another change in master. This would trigger yet another build so we need to be rather protective. Luckily, Azure DevOps allows us to batch changes during a build (i.e., not having another build at the same time). Batched changes get a special flag (i.e., reason), which can be handled with a precondition. Thus, if we have batched changes from master, we can just ignore them as push-back changes.

In order to make proper push back changes we need the Git credentials. For this we should create personal access token (short PAT) in GitHub. The PAT is really security sensitive - do only copy it once, place it in the pipeline's variables as a secret and never look back! If in doubt, generate a new PAT and replace the old value. Never reuse a PAT, otherwise you will get two problems: 1) not knowing what PAT may have been leaked and 2) not knowing what is affected when the PAT is expired / revoked.

Placing the GitHub PAT into the variables looks like the following excerpt:

variables

Finally, with this variable we can introduce a new step in our pipeline. The important part that this step is required before any push back.

This can look as follows:

build

What we do in that step is to check out the master branch (Lerna wants to see this instead of the exact commit SHA; actually, this justifies to place the given step as early as possible in the pipeline, but these are details...) and modify the repository URL (origin) to contain the PAT. We need to do this magic as Lerna does not accept an override of the remote URL (only a different remote). Additionally, we also configure Git with some user to avoid any error message and make it clear that the commit has been done by our CI system.

Make sure to replace all the placeholder names in the following snippet!

git config --global user.email "your@bot"
git config --global user.name "Your Bot"
git remote rm origin
git remote add origin https://$gt@github.com/orga/repo.git
git fetch origin
git checkout master
Created .

References

Sharing is caring!