NOTRE JOB, VOUS AIDER À CHOISIR LE VÔTRE

GitLab CI/CD sur un projet python microservice Retour sur 5 ans d’évolutions Jean-Luc Tromparent Antoine Coeur-Quetin

GitLab (des débuts à nos jours) 2011 2012 Dmitriy Zaporozhets lance Sytse Sijbrandij rejoint le un projet de partage de projet code Dmitriy créé la première 2014 2015 Gitlab Inc. GitLab 8.0 version de GitLab CI https://handbook.gitlab.com/handbook/company/history/ 2018 Microsoft rachete GitHub 2023 GitLab 16.4

Un projet Python (de la préhistoire à nos jours) TARS : Totally Awesome Recommendation System 2014 2015 2017 svn > git premier algo de migration azure portage en python hellowork.com monorepo redmine > gitlab recommandation lambda architecture microservice poetry réduction de la dette infogérance stack: c#, mongodb, redis stack: eventhub, stack: python, k8s v6 des sites emploi régionsjob stack tracking: nodejs, mongodb hdfs/spark 2018 2022 2023

Get started fichier .gitlab-ci.yml configuration d’un pipeline de CI séquence de stages et de jobs https://docs.gitlab.com/ee/ci/quick_start/

Un job de test test-job: stage: test script: - poetry install - poetry run python -m pytest -v coverage: ‘/^TOTAL.\s+(\d+%)\s$/’ artifacts: paths: - htmlcov/ coverage 77.00% —cov-report html:htmlcov —cov-fail-under $COVERAGE_MINIMUM_THRESHOLD_PERCENT

Architecture type de nos projets data un sous-projet librairie métier périmètre datascientist tests fonctionnels un sous-projet API (ou worker) périmetre data-ingé gestion des erreurs scalabilité containerization

Les livrables de notre projet de recommandation → des librairies Python publish-job: stage: release script: - poetry version $CI_COMMIT_TAG - poetry publish -r papaye —build only: - tags

Les livrables de notre projet de recommandation → des images Docker publish-job: stage: release script: - docker login ${NEXUS_URI} -u ${NEXUS_USER} -p ${NEXUS_PWD} - docker pull “${CI_PROJECT_NAME}:latest” || true - docker tag “${CI_PROJECT_NAME}:latest” “${NEXUS_URI}/${CI_PROJECT_NAME}:${CI_COMMIT_TAG}” - docker push “${NEXUS_URI}/${CI_PROJECT_NAME}:${CI_COMMIT_TAG}” only: - tags

Multi-project pipelines mylib/.gitlab-ci.yml trigger-job: myapi/.gitlab-ci.yml update_lib_version: stage: .post variables: LIB_VERSION: ${CI_COMMIT_TAG} stage: .pre script: - echo “Switch to lib version $LIB_VERSION” trigger: project: DataScience/myProject/myApi

  • poetry add mylib@$LIB_VERSION —lock artifacts: branch: master strategy: depend only: - tags paths: - poetry.lock - pyproject.toml rules: - if: $LIB_VERSION

Versioning release-job: stage: release script: # bumps the patch number of the semantic version of the project - poetry version patch - export NEW_VERSION=$(poetry version —short) 🔖

pushes the commit (asks the CI not to trigger a pipeline) and the tag after the version update - git add -A && git commit -m ” Release $NEW_VERSION” - git push -o ci.skip -u origin HEAD:$CI_COMMIT_BRANCH - git tag -a $NEW_VERSION -m “Release $NEW_VERSION” - git push —tags origin $NEW_VERSION # pass version as artifact - echo $NEW_VERSION > .version artifacts: paths: - .version only: - master

Architecture du projet REKO

Déploiement environnement de production image: infra k8s dispatch: 1.3.31 packaging: 1.3.38 template helm jadexplorer: 1.0.6 déploiement depuis gitlab offer2offer: 1.3.40 offer2user: 1.3.59 user2offer: 1.3.23 distributor: 1.3.15 feedcool: 1.3.8 feedcroo: 1.3.1 feedlsq: 1.3.12 reporter: 1.3.35 shipper: 1.3.32 watchdog: 1.3.5 feedjade: 1.3.31 upgradejade: 1.3.5 newusers: 1.3.15 refreshcache: 1.3.14 batchupjade: 1.3.11 keepintouch: 1.0.22 regurgitor: 0.0.12

Bilan 2018 - 2022 🍏 Le projet scale bien 🍏 Projet modulaire 🍎 MR portant sur plusieurs projets 🍎 Onboarding compliqué 🍎 Le déploiement n’est pas vraiment continuous

Gitlab CI/CD Migration vers un monorepo Pourquoi ?

Pourquoi un monorepo 40 projets Gitlab Duplication CI Beaucoup de trigger Pas de tag commun sur plusieurs projets Pourquoi maintenant Dette technique (Python 3.7) Projets transverses en étude : Log JSON, Lint, Sonarqube Migration Poetry Impose : modifications de la CI Permet : Imports relatifs dans la codebase

Le monorepo avec python Gerben Oostra (Gitlab) https://gitlab.com/gerbenoostra/poetry-monorepo David Vujic (Poetry) https://github.com/DavidVujic/pythonpolylith

Procédure de migration 1. Récupération de la codebase avec l’historique 2. Migration Poetry 3. Variables de CI 4. Template Helm (kubernetes) 5. Déploiement en preprod 6. Mise en production

Structure du repository TARS/ ├─ common/ ├─ k8s/ ├─ worker/ │ │ │ ├─ jade/ │ ├─ app/ │ ├─ core/ │ │ │ │ ├─ README.md │ └─ pyproject.toml └─ watchdog/ ├─ .gitlab-ci.yml ├─ pyproject.toml └─ README.md [tool.poetry] name = “jade” version = “1.5.0” readme = “README.md” packages = [ { include = “jade”, from = “core/” }, ] [tool.poetry.dependencies] python = “~3.10” requests = “2.25.1” workerrq = {path=”../../common/workerrq”}

pyproject.toml root Contient le paramétrage du formatter/LINT Permet de consolider les versions de dépendance Ne permet pas d’installer tous les projets [tool.poetry.group.worker.dependencies] jade = {path=”worker/jade”} watchdog = {path=”worker/watchdog”} [tool.poetry.group.api.dependencies] dispatch = {path=”api/dispatch”} packaging = {path=”api/packaging”} [tool.poetry.group.cronjob.dependencies] refreshcache = {path=”cronjob/refreshcache”} [tool.poetry.group.dev.dependencies] isort = “5.11.5” yapf = “^0.40.1” ruff = “^0.0.275” [tool.isort] line_length = 120 multi_line_output = 5 balanced_wrapping = false 😢

Gitlab CI/CD Migration vers un monorepo Le gitlab-ci.yml

🧪 🎨 👷 - deploy preprod 🏗️ - release 🔖 stages: - test - check - build

  • deploy production 🚀 👷 .build: stage: build extends: - .docker rules: - changes: - ${PROJECT_TYPE}/${PROJECT_NAME}/**/* - k8s/${PROJECT_NAME}/**/* - common/**/* before_script: .jade: variables: PROJECT_NAME: jade PROJECT_REGEX: /^jade/./ PROJECT_TYPE: worker NEED_VARS: “REDIS_RQ MONGODB_JADE_RW API_DISPATCH_URL JO .watchdog: variables: PROJECT_NAME: watchdog PROJECT_REGEX: /^watchdog/./ PROJECT_TYPE: worker NEED_VARS: “REDIS_RQ SLACK_WEBHOOK” 👷 jade : extends: - .build 🧪
  • .jade
  • *bump-version jade : - export VERSION=$(poetry -C ${PROJECT_TYPE}/${PROJECT_N extends: .docker:
  • .test - .jade 🏗️ script: jade : - docker login -u $GITLAB_USER -p $GITLAB_PASSWORD $ACR_ extends: - docker build . —build-arg PROJECT_PATH=${PROJECT_TYPE - docker push “$DOCKER_PATH/${PROJECT_NAME}:$VERSION”
  • .preprod - .deploy - .jade

Difficultés 😭 Bien passé 😁 Fusion des projets Bonne généricité Alignement des versions de lib Fonctionnement ISO multi-repo Montée de version Python 3.8 globale Dé-duplication Mise en place de la CI RAF Revoir la fusion de certains projets Manque les projets de la datascience De la CI Des charts Des dockerfiles Merci les tests Poetry (Imports relatif, Bump2version, Tests …) Repo light (15 Mo) 15 projets déployables facilement

Merci Des questions ?

NOTRE JOB S’ARRÊTE LÀ OÙ COMMENCE LE VÔTRE