Webux Lab

Par Studio Webux

Lerna pour déployer seulement les changements

TG
Tommy Gingras Studio Webux S.E.N.C 2021-12-12

Utiliser Lerna avec un monorepo pour déployer seulement les changements

Introduction

Lerna est un outil pour faciliter la maintenance et les interactions avec les monorepos.

Installation

À la racine de votre projet, lancer la commande suivante:

npm install --save-dev lerna

Structure & Configuration

tree -L 2 -I node_modules -a

Résultat:

.
├── .env.test
├── .eslintrc.js
├── .github
│   └── workflows
├── .gitignore
├── .husky
│   ├── _
│   ├── commit-msg
│   ├── pre-commit
│   └── pre-push
├── .prettierrc
├── actions
│   └── lambda-ci
├── commitlint.config.js
├── config.dev.json
├── lerna.json
├── libs
│   └── apigateway
├── package-lock.json
├── package.json
└── services
    ├── lambdaA
    │   ├── .npmignore
    │   ├── __tests__
    │   ├── coverage
    │   ├── jest.config.js
    │   ├── package-lock.json
    │   ├── package.json
    │   ├── post_serviceName.json
    │   ├── reports
    │   ├── serverless.yml
    │   └── src
    └── lambdaB
        ├── .npmignore
        ├── __tests__
        ├── coverage
        ├── jest.config.js
        ├── package-lock.json
        ├── package.json
        ├── post_serviceName.json
        ├── reports
        ├── serverless.yml
        └── src

17 directories, 19 files

Les services (dans ce cas-ci les lambdas), se trouvent tous sous services/.


Maintenant pour configurer lerna,

Il faut créer un fichier lerna.json à la racine du projet:

lerna.json:

{
  "packages": ["services/**", "libs/**"],
  "version": "0.0.0"
}

Les package.json; Lerna est super bien intégré avec les package.json.

À la racine du projet, vous pouvez avoir des scripts comme suit:

{
  "scripts": {
    "test": "lerna run test --since HEAD~1 --parallel",
    "lint": "lerna run lint --since HEAD~1 --parallel",
    "audit": "lerna exec --since HEAD~1 -- npm audit --production",
    "install": "lerna exec --since HEAD~1 -- npm install",
    "prune": "lerna exec --since HEAD~1 -- npm prune --production",
    "clean": "lerna exec -- \"rm -rf node_modules && rm -f package-lock.json\"",
    "precommit": "lint-staged",
    "deploy:dev": "sls deploy --stage dev",
    "print:dev": "sls print --stage dev",
    "deploy": "lerna run deploy --since HEAD~1"
  },
  "devDependencies": {
    "@commitlint/cli": "^15.0.0",
    "@commitlint/config-conventional": "^15.0.0",
    "eslint": "^8.4.1",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-import": "^2.25.3",
    "eslint-plugin-jest": "^25.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "husky": "^7.0.4",
    "lerna": "^4.0.0",
    "lint-staged": "^12.1.2",
    "prettier": "^2.5.1"
  },
  "lint-staged": {
    "**/*.js": "eslint"
  }
}

J’ai enlevé les autres paramètres pour simplifier la lecture

La configuration ci-haut permet de lancer les commandes seulement sur les fichiers qui ont changé depuis le dernier commit. De cette façon votre CI et vos déploiements seront plus efficaces lorsqu’on travaille en monorepo.


Pour les services, vous devez avoir les commandes npm de configurées.

{
  "scripts": {
    "lint": "eslint *.js",
    "test": "jest --coverage",
    "deploy": "echo 'Deploying...'"
  },
  "devDependencies": {
    "@types/jest": "^27.0.3",
    "dotenv": "^10.0.0",
    "jest": "^27.4.4",
    "jest-junit": "^13.0.0"
  }
}

Tests

Cette structure a été testée avec des github actions et localement.

  1. Valider que le pre-commit & pre-push se lance seulement pour les services qui ont changé.
  2. Valider que le CI lance les commandes seulement pour les services qui ont changé.
  3. Valider que le déploiement s’effectue seulement sur les services qui ont changé lorsque la feature branch est mergé vers main.

Limitations


Recherche