Recherche effectué dans :

Filtre actif, cliquez pour en enlever un tag :

Cliquez sur un tag pour affiner votre recherche :

Résultat de la recherche (71 notes) :

Journal du vendredi 07 février 2025 à 14:03 #DevOps, #admin-sys, #software-engineering, #paradigme, #Doctrine

Pendant l'année 2014, Athoune m'a fait découvrir les concepts DevOps "Baking" et "Frying".

Je le remercie, car ce sont des concepts que je considère très importants pour comprendre les différents paradigmes de déploiement.

Je n'ai aucune idée dans quelles conditions il avait découvert ces concepts. J'ai essayé de faire des recherches limitées à l'année 2014 et je suis tombé sur cette photo :

J'en déduis que cela devait être un sujet à la méthode dans l'écosystème DevOps de 2014.

Cet ami me l'avait très bien expliqué avec une analogie du type :

« Le baking en DevOps, c’est comme dans un restaurant où les plats sont préparés en cuisine et ensuite apportés tout prêt salle à la table du client. Le frying, c’est comme si le plat était préparé directement en salle sur la table du client. »

Bien que cette analogie ne soit pas totalement rigoureuse, elle m'a bien permis de saisir, en 2014, le paradigme Docker qui consiste à préparer des images de container en amont. Ce paradigme permet d'installer, de configurer ces images "en cuisine", donc pas sur les serveurs de production, "de goûter les plats" et de les envoyer ensuite de manière prédictible sur le serveur de production.

Ces images peuvent être construites soit sur la workstation du développeur ou mieux, sur des serveurs dédiés à cette fonction, comme Gitlab-Runner

Définitions proposées par LLaMa :

Baking (ou "Image Baking") : Il s'agit de créer une image de serveur prête à l'emploi, avec tous les logiciels et les configurations nécessaires déjà installés et configurés. Cette image est ensuite utilisée pour déployer de nouveaux serveurs, qui seront ainsi identiques et prêts à fonctionner immédiatement. L'avantage de cette approche est qu'elle permet de réduire le temps de déploiement et d'assurer la cohérence des environnements.

Frying (ou "Server Frying") : Il s'agit de déployer un serveur "nu" et de le configurer et de l'installer à la volée, en utilisant des outils d'automatisation tels que Ansible, Puppet ou Chef. Cette approche permet de personnaliser la configuration de chaque serveur en fonction des besoins spécifiques de l'application ou du service.

Exemple :

Cas d'usage Baking Frying
Docker Construire une image complète (docker build) et la stocker dans un registre Lancer un conteneur minimal et installer les dépendances au démarrage.
Machines virtuelles (VMs) Créer une image VM avec Packer et la déployer telle quelle Démarrer une VM de base et appliquer un script d’installation à la volée
CI/CD Compiler et packager une application en image prête à être déployée Construire l’application à chaque déploiement sur la machine cible

En 2014, lorsque le concept de baking m’a été présenté, j’ai immédiatement été enthousiasmé, car il répondait à trois problèmes que je cherchais à résoudre :

  • Réduire les risques d’échec d’une installation sur le serveur de production
  • Limiter la durée de l’indisponibilité (pendant la phase d’installation)
  • Éviter d'augmenter la charge du serveur durant les opérations de build lors de l’installation

Depuis, j'évite au maximum le frying et j'ai intégré le baking dans ma doctrine d'artisan développeur.

Journal du vendredi 07 février 2025 à 13:00 #Kubernetes, #Doctrine, #deployment, #DevOps, #admin-sys, #software-engineering

Début novembre un ami me posait la question :

Quand tu déploies des conteneurs en prod, sans k8s, tu fais comment ?

Après 3 mois d'attente, voici ma réponse 🙂.

Mon contexte

Tout d'abord, un peu de contexte. Cela fait 25 ans que je travaille sur des projets web, et tous les projets sur lesquels j'ai travaillé pouvaient être hébergés sur un seul et unique serveur baremetal ou une Virtual machine, sans jamais nécessiter de scalabilité horizontale.

Je n'ai jamais eu besoin de serveurs avec plus de 96Go de RAM pour faire tourner un service en production. Il convient de noter que, dans 80% des cas, 8 Go ou 16 Go étaient largement suffisants.

Cela dit, j'ai également eu à gérer des infrastructures comportant plusieurs serveurs : 10, 20, 30 serveurs. Ces serveurs étaient généralement utilisés pour héberger une infrastructure de soutien (Platform infrastructure) à destination des développeurs. Par exemple :

  • Environnements de recettage
  • Serveurs pour faire tourner Gitlab-Runner
  • Sauvegarde des données
  • Etc.

Ce contexte montre que je n'ai jamais eu à gérer le déploiement de services à très forte charge, comme ceux que l'on trouve sur des plateformes telles que Deezer, le site des impôts, Radio France, Meetic, la Fnac, Cdiscount, France Travail, Blablacar, ou encore Dicticimo. La méthode que je décris dans cette note ne concerne pas ce type d'infrastructure.

Ma méthode depuis 2015

Dans cette note, je ne vais pas retracer l'évolution complète de mes méthodes de déploiement, mais plutôt me concentrer sur deux d'entre elles : l'une que j'utilise depuis 2015, et une déclinaison adoptée en 2020.

Voici les principes que j'essaie de suivre et qui constituent le socle de ma doctrine en matière de déploiement de services :

En pratique, j'utilise Ansible pour déployer un fichier docker-compose.yml sur le serveur de production et ensuite lancer les services.

Je précise que cette note ne traite pas de la préparation préalable du serveur, de l'installation de Docker, ni d'autres aspects similaires. Afin de ne pas alourdir davantage cette note, je n'aborde pas non plus les questions de Continuous Integration ou de Continuous Delivery.

Imaginons que je souhaite déployer le lecteur RSS Miniflux connecté à un serveur PostgreSQL.
Voici les opérations effectuées par le rôle Ansible à distance sur le serveur de production :

    1. Création d'un dossier /srv/miniflux/
    1. Upload de /srv/miniflux/docker-compose.yml avec le contenu suivant :
services:
  postgres:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_DB: miniflux
      POSTGRES_USER: miniflux
      POSTGRES_PASSWORD: password
    volumes:
      - postgres:/var/lib/postgresql/data/
    healthcheck:
      test: ['CMD', 'pg_isready']
      interval: 10s
      start_period: 30s

  miniflux:
    image: miniflux/miniflux:2.2.5
    ports:
    - 8080:8080
    environment:
      DATABASE_URL: postgres://miniflux:password@postgres/miniflux?sslmode=disable
      RUN_MIGRATIONS: 1
      CREATE_ADMIN: 1
      ADMIN_USERNAME: johndoe
      ADMIN_PASSWORD: secret
    healthcheck:
      test: ["CMD", "/usr/bin/miniflux", "-healthcheck", "auto"]
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  postgres:
     name: miniflux_postgres
    1. Depuis le dossier /srv/miniflux/ lancement de la commande docker compose up -d --remove-orphans --wait --pull always

Voilà, c'est tout 🙂.

En 2020, j'enlève "une couche"

J'aime enlever des couches et en 2020, je me suis demandé si je pouvais pratiquer avec élégance la méthode Remote Execution sans Ansible.
Mon objectif était d'utiliser seulement ssh et un soupçon de Bash.

Voici le résultat de mes expérimentations.

J'ai besoin de deux fichiers.

  • _payload_deploy_miniflux.sh
  • deploy_miniflux.sh

Voici le contenu de _payload_deploy_miniflux.sh :

#!/usr/bin/env bash
set -e

PROJECT_FOLDER="/srv/miniflux/"

mkdir -p ${PROJECT_FOLDER}

cat <<EOF > ${PROJECT_FOLDER}docker-compose.yaml
services:
  postgres:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_DB: miniflux
      POSTGRES_USER: miniflux
      POSTGRES_PASSWORD: {{ .Env.MINIFLUX_POSTGRES_PASSWORD }}
    volumes:
      - postgres:/var/lib/postgresql/data/
    healthcheck:
      test: ['CMD', 'pg_isready']
      interval: 10s
      start_period: 30s

  miniflux:
    image: miniflux/miniflux:2.2.5
    ports:
    - 8080:8080
    environment:
      DATABASE_URL: postgres://miniflux:{{ .Env.MINIFLUX_POSTGRES_PASSWORD }}@postgres/miniflux?sslmode=disable
      RUN_MIGRATIONS: 1
      CREATE_ADMIN: 1
      ADMIN_USERNAME: johndoe
      ADMIN_PASSWORD: {{ .Env.MINIFLUX_ADMIN_PASSWORD }}
    healthcheck:
      test: ["CMD", "/usr/bin/miniflux", "-healthcheck", "auto"]
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  postgres:
     name: miniflux_postgres

EOF

cd ${PROJECT_FOLDER}

docker compose pull
docker compose up -d --remove-orphans --wait

Voici le contenu de deploy_miniflux.sh :

#!/usr/bin/env bash
set -e

cd "$(dirname "$0")/../"

gomplate -f _payload_deploy_miniflux.sh | ssh root@$SERVER1_IP 'bash -s'

J'utilise gomplate pour remplacer dynamiquement les secrets dans le script _payload_deploy_miniflux.sh.

En conclusion, pour déployer une nouvelle version, j'ai juste à exécuter :

$ ./deploy_miniflux.sh

Je trouve cela minimaliste et de plus, l'exécution est bien plus rapide que la solution Ansible.

Ce type de script peut ensuite être exécuté aussi bien manuellement par un développeur depuis sa workstation, que via GitLab-CI ou même Rundeck.

Pour un exemple plus détaillé, consultez ce repository : https://github.com/stephane-klein/poc-bash-ssh-docker-deployement-example


Bien entendu, si vous souhaitez déployer votre propre application que vous développez, vous devez ajouter à cela la partie baking, c'est-à-dire, le docker build qui prépare votre image, l'uploader sur un Docker registry… Généralement je réalise cela avec GitLab-CI/CD ou GitHub Actions.


Objections

Certains DevOps me disent :

  • « Mais on ne fait pas ça pour de la production ! Il faut utiliser Kubernetes ! »
  • « Comment ! Tu n'utilises pas Kubernetes ? »

Et d'autres :

  • « Il ne faut au grand jamais utiliser docker-compose en production ! »

Ne jamais utiliser docker compose en production ?

J'ai reçu cette objection en 2018. J'ai essayé de comprendre les raisons qui justifiaient que ce développeur considère l'usage de docker compose en production comme un Antipattern.

Si mes souvenirs sont bons, je me souviens que pour lui, la bonne méthode conscistait à déclarer les états des containers à déployer avec le module Ansible docker_container (le lien est vers la version de 2018, depuis ce module s'est grandement amélioré).

Je n'ai pas eu plus d'explications 🙁.

J'ai essayé d'imaginer ses motivations.

J'en ai trouvé une que je ne trouve pas très pertinente :

  • Uplodaer un fichier docker-compose.yml en production pour ensuite lancer des fonctions distantes sur celui-ci est moins performant que manipuler docker-engine à distance.

J'en ai imaginé une valable :

  • En déclarant la configuration de services Docker uniquement dans le rôle Ansible cela garantissait qu'aucun développeur n'ira modifier et manipuler directement le fichier docker-compose.yml sur le serveur de production.

Je trouve que cela est un très bon argument.

Cependant, cette méthode a à mes yeux les inconvénients suivants :

  • Je maitrise bien mieux la syntaxe de docker compose que la syntaxe du module Ansible community.docker.docker_container
  • J'utilise docker compose au quotidien sur ma workstation et je n'ai pas envie d'apprendre une syntaxe supplémentaire uniquement pour le déploiement.
  • Je pense qu'il y a plus de développeurs qui maîtrisent docker compose que le module Ansible community.docker.docker_container.
  • Je ne suis pas utilisateur maximaliste de la méthode Remote Execution. Je trouve, dans certaines circonstances, très pratique de pouvoir manipuler docker compose dans une session ssh directement sur un serveur. En période de stress ou de debug compliqué, je trouve cela pratique. J'essaie d'être assez rigoureux pour ne pas oublier de reporter mes changements effectués directement le serveur dans les scripts de déploiements (configuration as code).

Tu dois utiliser Kubernetes !

Alors oui, il y a une multitude de raisons valables d'utiliser Kubernetes. C'est une technologie très puissante, je n'ai pas le moindre doute à ce sujet.
J'ai une expérience dans ce domaine, ayant utilisé Kubernetes presque quotidiennement dans un cadre professionnel de janvier 2016 à septembre 2017. J'ai administré un petit cluster auto-managé composé de quelques nœuds et y ai déployé diverses applications.

Ceci étant dit, je rappelle mon contexte :

Les services sur lesquels je travaille depuis 25 ans sont déployables sur de simples serveurs baremetal pour Virtual machine.

Je n'ai jamais eu besoin de serveurs avec plus de 96Go de RAM pour faire tourner un service en production. J'ajoute que dans 80% des cas, 8Go ou 16Go étaient suffisants.

Je pense que faire appel à Kubernetes dans ce contexte est de l'overengineering.

Je dois avouer que j'envisage d'expérimenter un usage minimaliste de K3s pour mes déploiements. Mais je sais que Kubernetes est un rabbit hole : Helm, Kustomize, Istio, Helmfile, Grafana Tanka… J'ai peur de tomber dans un Yak!.

D'autre part, il existe déjà un pourcentage non négligeable de développeur qui ne maitrise ni Docker, ni docker compose et dans ces conditions, faire le choix de Kubernetes augmenterait encore plus la barrière à l'entrée permettant à des collègues de pouvoir comprendre et intervenir sur les serveurs d'hébergement.

C'est pour cela que ma doctrine d'artisan développeur consiste à utiliser Kubernetes seulement à partir du moment où je rencontre des besoins de forte charge, de scalabilité.

Playground qui présente comment je setup un projet Python Flask en 2025 #dev-kit, #python, #mise, #docker, #WSL, #playground, #software-engineering

Je pense que cela doit faire depuis 2015 que je n'ai pas développé une application en Python Flask !

Entre 2008 et 2015, j'ai beaucoup itéré dans mes méthodes d'installation et de setup de mes environnements de développement Python.

D'après mes souvenirs, si je devais dresser la liste des différentes étapes, ça donnerai ceci :

  • 2006 : aucune méthode, j'installe Python 🙂
  • 2007 : je me bats avec setuptools et distutils (mais ça va, c'était plus mature que ce que je pouvais trouver dans le monde PHP qui n'avait pas encore imaginé composer)
  • 2008 : je trouve la paie avec virtualenv
  • 2010 : j'ai peur d'écrire des scripts en Bash alors à la place, j'écris un script bootstrap.py dans lequel j'essaie d'automatiser au maximum l'installation du projet
  • 2012 : je me bats avec buildout pour essayer d'automatiser des éléments d'installation. Avec le recul, je réalise que je n'ai jamais rien compris à buildout
  • 2012 : j'utilise Vagrant pour fixer les éléments d'installation, je suis plutôt satisfait
  • 2015 : je suis radicale, j'enferme tout l'environnement de dev Python dans un container de développement, je monte un path volume pour exposer le code source du projet dans le container. Je bricole en entrypoint avec la commande "sleep".

Des choses ont changé depuis 2015.

Mais, une chose que je n'ai pas changée, c'est que je continue à suivre le modèle The Twelve-Factors App et je continue à déployer tous mes projets packagé dans des images Docker. Généralement avec un simple docker-compose.yml sur le serveur, ou alors Kubernetes pour des projets de plus grande envergure… mais cela ne m'arrive jamais en pratique, je travaille toujours sur des petits projets.

Choses qui ont changé : depuis fin 2018, j'ai décidé de ne plus utiliser Docker dans mes environnements de développement pour les projets codés en NodeJS, Golang, Python

Au départ, cela a commencé par uniquement les projets en NodeJS pour des raisons de performance.

J'ai ensuite découvert Asdf et plus récemment Mise. À partir de cela, tout est devenu plus facilement pour moi.
Avec Asdf, je n'ai plus besoin "d'enfermer" mes projets dans des containers Docker pour fixer l'environnement de développement, les versions…

Cette introduction est un peu longue, je n'ai pas abordé le sujet principal de cette note 🙂.

Je viens de publier un playground d'un exemple de projet minimaliste Python Flask suivant mes pratiques de 2025.

Voici son repository : mise-python-flask-playground

Ce playground est "propulsé" par Docker et Mise.

J'ai documenté la méthode d'installation pour :

Je précise que je n'ai pas eu l'occasion de tester l'installation sous Windows, hier j'ai essayé, mais je n'ai pas réussi à installer WSL2 sous Windows dans un Virtualbox lancé sous Fedora. Je suis à la recherche d'une personne pour tester si mes instructions d'installation sont valides ou non.

Briques technologiques présentes dans le playground :

Voici quelques petites subtilités.

Dans le fichier alembic.ini j'ai modifié le paramètre file_template parce que j'aime que les fichiers de migration soient classés par ordre chronologique :

[alembic]
# template used to generate migration files
file_template = %%(year)d%%(month).2d%%(day).2d_%%(hour).2d%%(minute).2d%%(second).2d_%%(slug)s

Ce qui donne par exemple :

20250205_124639_users.py
20250205_125437_add_user_lastname.py

Ici le port de PostgreSQL est généré dynamiquement par docker compose :

  postgres:
    image: postgres:17
	...
	ports:
      - 5432 # <= ici

Avec cela, fini les conflits de port quand je lance plusieurs projets en même temps sur ma workstation.

L'URL vers le serveur PostgreSQL est générée dynamiquement par le script get_postgres_url.sh qui est appelé par le fichier .envrc. Tout cela se passe de manière transparente.

J'initialise ici les extensions PostgreSQL :

def init_db():
    db.drop_all()
    db.session.execute(db.text('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"'))
    db.session.execute(db.text('CREATE EXTENSION IF NOT EXISTS "unaccent"'))
    db.session.commit()
    db.create_all()

et ici dans la première migration :

def upgrade():
    op.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";')
    op.execute('CREATE EXTENSION IF NOT EXISTS "unaccent";')
    op.create_table('users',
        sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
        sa.Column('firstname', sa.String(), nullable=False),
        sa.PrimaryKeyConstraint('id')
    )

Journal du mardi 28 janvier 2025 à 13:49 #software-engineering, #Doctrine

Alexandre me dit : « Le contenu de Speed of Code Reviews (https://google.github.io/eng-practices/review/reviewer/speed.html) ressemble à ce dont tu faisais la promotion dans notre précédente équipe ».

En effet, après lecture, les recommandations de cette documentation font partie de ma doctrine d'artisan développeur.

Note: j'ai remplacé CL qui signifie Changelist par Merge Request.

When code reviews are slow, several things happen:

  • The velocity of the team as a whole is decreased. Yes, the individual who doesn’t respond quickly to the review gets other work done. However, new features and bug fixes for the rest of the team are delayed by days, weeks, or months as each Merge Request waits for review and re-review.
  • Developers start to protest the code review process. If a reviewer only responds every few days, but requests major changes to the Merge Request each time, that can be frustrating and difficult for developers. Often, this is expressed as complaints about how “strict” the reviewer is being. If the reviewer requests the same substantial changes (changes which really do improve code health), but responds quickly every time the developer makes an update, the complaints tend to disappear. Most complaints about the code review process are actually resolved by making the process faster.
  • Code health can be impacted. When reviews are slow, there is increased pressure to allow developers to submit Merge Request that are not as good as they could be. Slow reviews also discourage code cleanups, refactorings, and further improvements to existing Merge Request.

source

J'ai fait le même constat et je trouve que cette section explique très bien les conséquences 👍️.

How Fast Should Code Reviews Be?

If you are not in the middle of a focused task, you should do a code review shortly after it comes in.

One business day is the maximum time it should take to respond to a code review request (i.e., first thing the next morning).

Following these guidelines means that a typical Merge Request should get multiple rounds of review (if needed) within a single day.

source

Je partage et recommande cette pratique 👍️.

If you are too busy to do a full review on a Merge Request when it comes in, you can still send a quick response that lets the developer know when you will get to it, suggest other reviewers who might be able to respond more quickly.

source

👍️

Large Merge Request

If somebody sends you a code review that is so large you’re not sure when you will be able to have time to review it, your typical response should be to ask the developer to split the Merge Request into several smaller Merge Requests that build on each other, instead of one huge Merge Request that has to be reviewed all at once. This is usually possible and very helpful to reviewers, even if it takes additional work from the developer.

source

Je partage très fortement cette recommandation et je pense que c'est celle que j'avais le plus de difficulté à faire accepter par les nouveaux développeurs.

Quand je code, j'essaie de garder à l'esprit que mon objectif est de faciliter au maximum le travail du reviewer plutôt que de chercher à minimiser mes propres efforts.

J'ai sans doute acquis cet état d'esprit du monde open source. En effet, l'un des principaux défis lors d'une contribution à un projet open source est de faire accepter son patch par le mainteneur. On comprend rapidement qu'un patch doit être simple à comprendre et rapide à intégrer pour maximiser ses chances d'acceptation.

Un bon patch doit remplir un objectif unique et ne contenir que les modifications strictement nécessaires pour l'atteindre.

Je suis convaincu que si une équipe de développeurs applique ces principes issus de l'open source dans leur contexte professionnel, leur efficacité collective s'en trouvera grandement améliorée.

Par ailleurs, une Merge Request de taille réduite présente plusieurs avantages concrets :

  • elle est non seulement plus simple à rebase,
  • mais elle a aussi plus de chances d'être mergée rapidement.

Cela permet à l'équipe de bénéficier plus rapidement des améliorations apportées, qu'il s'agisse de corrections de bugs ou de nouvelles fonctionnalités.

Quelle est la fonction de "/deployment-playground/" dans mes projets ? #WebDev, #software-engineering, #DevOps, #deployment

L'objectif de cette note est d'expliquer ce que sont les dossiers /deployment-playground/ et ma pratique consistant à les intégrer dans la plupart de mes projets de développement web.

Je pense me souvenir que j'ai commencé à intégrer ce type de dossier vers 2018.

Au départ, je nommais ce dossier /demo/ dont l'objectif était le suivant : permettre à un développeur de lancer localement le plus rapidement possible une instance de démo complète de l'application.

Pour cela, ce dossier contenait généralement :

  • Un docker-compose.yml qui permettait le lancer tous les services à partir des dernières images Docker déjà buildé. Soit les images de la version de l'environnement de développement, staging ou production.
  • Un script d'injection de données de fixtures ou de données spécifiques de démonstration.
  • Mise à disposition des logins / password d'un ou plusieurs comptes utilisateurs.

Cet environnement était configuré au plus proche de la configuration de production.

Avec le temps, j'ai constaté que mon utilisation de ce dossier a évolué. Petit à petit, je m'en servais pour :

  • Aider les développeurs à comprendre le processus de déploiement de l'application en production, en fournissant une représentation concrète des résultats des scripts de déploiement.
  • Permettre aux développeurs de tester localement la bonne installation de l'application, afin de reproduire les conditions de production en cas de problème.
  • Faciliter l'itération locale sur l'amélioration ou le refactoring de la méthode de déploiement.
  • Et bien d'autres usages.

J'ai finalement décidé de renommer ce dossier deployment-playground, un bac à sable pour "jouer" localement avec la configuration de production de l'application.

Je ne peux pas vous partager mes exemples beaucoup plus complets qui sont hébergés sur des dépôts privés, mais voici quelques exemples minimalistes dans mes dépôts publics :

Journal du mardi 31 décembre 2024 à 17:12 #software-engineering, #anglais, #JaiDécouvert

Dans le billet de blog d'Emmanuele Bassi "The Mirror", j'ai découvert l'expression informatique "Flag day".

Releasing GLib 3.0 today would necessitate breaking API in the entirety of the GNOME stack and further beyond; it would require either a hard to execute “flag day”, or an impossibly long transition, reverberating across downstreams for years to come.

source

L'article Wikipédia donne la définition suivante :

A flag day, as used in system administration, is a change which requires a complete restart or conversion of a sizable body of software or data. The change is large and expensive, and—in the event of failure—similarly difficult and expensive to reverse.

source

D'après ce que j'ai compris, un "Flag day" désigne un déploiement complexe où plusieurs systèmes doivent être mis à jour simultanément, sans possibilité de retour en arrière. C'est une approche risquée, car elle implique une transition brutale entre l'ancien et le nouveau système, souvent difficile à gérer dans des environnements interdépendants.

Un "Flag day" s'oppose à une migration en douceur.

C'est une situation que j'essaie d'éviter autant que possible. Des méthodes comme les Feature toggle ou l'introduction d'un système de versionnement permettent d'effectuer des migrations douces, par petites itérations, testables et sans interruption de service.

Concernant l'origine de cette expression, je lis :

This systems terminology originates from a major change in the Multics operating system's definition of ASCII, which was scheduled for the United States holiday, Flag Day, on June 14, 1966.

source

Je pense qu'à l'avenir, je vais utiliser cette expression.

Qu'est-ce qu'un "Script Helper" ? #dev-kit, #software-engineering

J'utilise souvent le terme "Script Helper". Dans cette note, je vais tenter de le définir.

Un script dit « helper » est un script qui n'est pas essentiel au cœur du projet et qui ne contient pas de code métier. Son rôle est d’automatiser des tâches courantes et réutilisables pour le développeur.

L’écriture de ces scripts permet de centraliser et de versionner leur contenu, tout en réduisant les risques d’erreurs d’exécution.

Ma définition et objectif d'un "Workspace" dans un "environnement de développement" ? #dev-kit, #software-engineering

Dans une note précédente, j'ai donné ma définition et les objectifs d'un "Development kit".
Dans cette note, je souhaite donner ma définition et les objectifs d'un workspace dans un "environnements de développement".

Un workspace est un dossier, qui contient des paramètres de configuration spécifiques — généralement sous la forme de variables d'environnements — qui permettent d'interagir sur une ou plusieurs instances de services, d'un environnement précis.
Généralement ce dossier contient des guides d'instructions pour réaliser des actions spécifiques sur le workspace et des scripts de type "helpers".

Exemple de workspaces :

  • staging/remote-workspace/ : un workspace utilisé pour effectuer des actions sur les services déployés en staging sur des serveurs distants ;
  • staging/local-workspace/ : un workspace d'installer localement des services dans les mêmes conditions que sur l'environnement staging ;
  • development/local-workspace/ : un dossier workspace, qui permet de travailler — contribuer — localement sur le ou les services.

Voir aussi :

Journal du samedi 07 décembre 2024 à 20:49 #git, #monorepo, #multirepos, #software-engineering, #iteration

Je pense être arrivé à une solution plus ou moins satisfaisante pour le Projet 19 - "Documenter une méthode pour synchroniser un monorepo vers des multirepos qui fonctionne dans les deux sens".

Voici-ci, ci-dessous, les étapes de la démonstration qui sont détaillées dans le README.md du repository poc-git-monorepo-multirepos-sync.

  • Je crée deux repositories : frontend et backend (multi repositories) ;
  • J'utilise le script tomono pour les intégrer dans un monorepo nommé monorepo ;
  • J'ajoute deux fichiers à la racine de monorepo : README.md et .mise.toml ;
  • J'effectue des changements dans le repository frontend, je commit ;
  • Je pull les changements du repository frontend vers monorepo ;
  • Dans monorepo, j'effectue des changements dans le dossier frontend/, je commit ;
  • J'utilise cd frontend/; git format-patch --relative -1 HEAD pour générer un patch qui contient les changements que j'ai effectués dans le dossier frontend/ ;
  • Je vais dans le repository frontend et j'applique les changements contenus dans ce patch avec la command git apply monpatch.patch ou avec git am monptach.patch.

Pour le moment, j'ai privilégié l'option git patch, parce que je souhaite suivre la méthode la plus "manuelle" que j'ai pu trouver lorsque je dois intervenir sur les repositories upstream, parce que je ne veux prendre aucun risque de perturber mes collègues avec mon initiative de monorepo.

Le repository GitHub suivant contient le résultat final du monorepo : https://github.com/stephane-klein/poc-git-monorepo-multirepos-sync-result-example/.

Est-ce que je suis satisfait du résultat de cette démo ?

La réponse est oui, bien que je ne sois pas satisfait de quelques éléments.
Par exemple, les fichiers de frontend présents dans ce commit ne sont pas dans le dossier frontend. J'aimerais que ces titres de commits contiennent un prefix [frontend] ... et [backend].... Je pense que cela doit être possible à implémenter en modifiant le script tomono.

Est-ce que c'est pénible à utiliser ? Pour le moment, ma réponse est « je ne sais pas ».

Je vais tester cette méthode avec deux projets. Je pense écrire une note de bilan de cette expérience d'ici à quelques semaines.

Journal du mercredi 04 décembre 2024 à 14:56 #dev-kit, #software-engineering

Alexandre a eu un breaking change avec Mise : https://github.com/jdx/mise/issues/3338.

Suite à cela, j'ai découvert que Mise va prévilégier l'utilisation du backend aqua plutôt que Asdf :

we are actively moving tools in the registry away from asdf where possible to backends like aqua and ubi which don't require plugins.

source

J'ai découvert au passage que Mise supporte de plus en plus de backend, par exemple Ubi et vfox.

Je constate qu'il commence à y avoir une profusion de "tooling version management" : Asdf,Mise, aqua, Ubi, vfox !
Je pense bien qu'ils ont chacun leurs histoires, leurs forces, leurs faiblesses… mais j'ai peur que cela me complique mon affaire : comment arriver à un consensus de choix de l'un de ces outils dans une équipe 🫣 ! Chaque développeur aura de bons arguments pour utiliser l'un ou l'autre de ces outils.

Constatant plusieurs fois que le développeur de Mise a fait des breaking changes qui font perdre du temps aux équipes, mon ami et moi nous sommes posés la question si, au final, il ne serait pas judicieux de revenir à Asdf.

D'autre part, au départ, Mise était une simple alternative plus rapide à Asdf, mais avec le temps, Mise prend en charge de plus en plus de fonctionnalités, comme une alternative à direnv , un système d'exécution de tâches, ou mise watch.
Souvent, avec des petits défauts très pénibles, voir par exemple, ma note "Le support des variables d'environments de Mise est limité, je continue à utiliser direnv".

Alexandre s'est ensuite posé la question d'utiliser un jour le projet devenv, un outil qui va encore plus loin, basé sur le système de package Nix.

Le projet devenv me fait un peu peur au premier abord, il gère "tout" :

Il fait énormément de choses et je crains que la barrière à l'entrée soit trop haute et fasse fuir beaucoup de développeurs 🤔.

Tout cela me fait un peu penser à Bazel (utilisé par Google), Pants (utilisé par Twitter), Buck (utilisé par Facebook) et Please.
Tous ces outils sont puissants, je les ai étudiés en 2018 sans arrivée à les adopter.

Pour le moment, mes development kit nécessitent les compétences suivantes :

  • Comprendre les rudiments d'un terminal Bash ;
  • Arriver à installer et à utiliser Mise et direnv ;
  • Maitriser Docker ;
  • Savoir lire et écrire des scripts Bash de niveau débutant.

Déjà, ces quatre prérequis posent quelques fois des difficultés d'adoption.

Journal du mercredi 27 novembre 2024 à 11:29 #versioning, #software-engineering, #JaiDécouvert

Il y a quelques jours, j'ai écrit une note au sujet des stratégies de versionning et aujourd'hui, #JaiDécouvert le site TrunkVer (https://trunkver.org/) (from).

We have identified a frequent source of avoidable confusion, conflict and cost in the software delivery process caused by versioning software that should not be versioned - or rather, the versioning should be automated.

source

👍️

However, we keep encountering teams and organizations that apply semantic versioning or a custom versioning scheme to software that does not need any of that - and through this, they create an astonishing amount of unnecessary work such as arguing whether or not a certain piece of software should be called “alpha”, “beta”, “rho”, “really final v4” etc, manually creating tickets listing the changes or even specialized gatekeeper roles such as “release engineer” - in the worst case a single person in the whole organization. Because this makes it harder, boring and costly to deploy, it systematically reduces the number of deployments, and through this the delivery performance of the organization.

source

👍️


Depuis 20 ans, j'ai rarement développé des librairies ou des API REST utilisées par des tiers.
Par conséquent, je n'ai pratiquement jamais eu besoin d'utiliser Semantic Versioning dans mes projets.

La plupart des projets sur lesquels je travaille suivent le modèle "Rolling release".

Je croise trop souvent des développeurs utilisant la spécification Semantic Versioning alors que leur projet suit le modèle Rolling release et je pense que TrunkVer serait bien plus adapté à leur contexte.


Cela fait plusieurs années maintenant que j'utilise la méthode suivante pour identifier "la version" de ce que je déploie.

Dans mes scripts de déploiement, je génère un fichier version.json, comme ceci (example) :

cat <<EOF > version.json
{
    "environment": "prod",
    "branch": "$(git rev-parse --abbrev-ref HEAD)",
    "gitDate": "$(git show -s --format=%ci | sed "s/ /_/g")",
    "buildStamp": "$(env TZ=Europe/Paris date '+%Y-%m-%d_%H:%M:%S-%Z')",
    "gitHash": "$(git rev-parse HEAD)"
}
EOF

Ensuite je l'insert au moment du docker build et je l'expose sur une URL http.

Ce qui donne, par exemple, ceci :

$ curl https://notes.sklein.xyz/version.json
{
    "environment": "prod",
    "branch": "main",
    "gitDate": "2024-12-03_23:43:26_+0100",
    "buildStamp": "2024-12-03_23:51:09-CET",
    "gitHash": "04c83c82a663260626e02502be1015d23b4859c2"
}

Ma méthode ne correspond pas exactement dans la forme à la méthode TrunkVer mais cela s'en rapproche.

Journal du mercredi 27 novembre 2024 à 10:52 #JeMeDemande, #naming, #software-engineering

Depuis des années, j'hésite toujours entre get et fetch lors du naming de fonctions.

Je viens de demander à ChatGPT la différence entre ces deux verbes et quand est-ce qu'il est préférable d'utiliser l'un ou l'autre.

Voici sa réponse :

Pour get :

  • Signification : Indique une opération simple pour récupérer ou accéder à des données.
  • Contexte d'utilisation :
    • Utilisé pour des accès rapides et directs à des données qui sont déjà disponibles localement (en mémoire, en cache, etc.).
    • Souvent employé dans des fonctions "getter" ou des méthodes utilitaires simples.

Pour fetch :

  • Signification : Suggère une opération potentiellement asynchrone ou coûteuse, comme récupérer des données d'une source externe.
  • Contexte d'utilisation :
    • Lorsqu'une action supplémentaire est requise pour obtenir les données, comme un appel réseau ou une requête vers une API.
    • Implique souvent un effort ou une complexité plus grande que get.

J'ai essayé d'obtenir plus de ressources concernant cette déclaration.

J'ai trouvé ceci :

Example: fetch implies that some entity needs to go and get something that is remote and bring it back. Dogs fetch a stick, and retrieve is a synonym for fetch with the added semantic that you may have had possession of the thing prior as well. get is a synonym for obtain as well which implies that you have sole possession of something and no one else can acquire it simultaneously.

source

Suite à cette étude, j'ai décidé d'utiliser fetch plutôt que get pour toutes les fonctions allant chercher des données en dehors du "processus local". Quelques exemples :

  • Utilisation de fetch pour nommer une fonction javascript frontend ou backend, qui effectue des requêtes REST ou GraphQL.
  • Utilisation de get pour nommer une fonction PL/pgSQL qui effectue uniquement des requêtes SQL sur la base de données locale (pas de requêtes vers des Foreign Data (PostgreSQL)). Ici "locale" signifie que l'instance qui exécute la fonction PL/pgSQL est la même que celle qui contient les tables requêtées (voir cet échange).

Pourquoi j'utilise direnv dans mes development kit ? #dev-kit, #software-engineering

Dans cette note, je souhaite expliquer pourquoi j'utilise et j'aime utiliser direnv.

Je suis toujours en train d'essayer de créer des development kit me permettant de travailler dans un environnements de développement toujours plus agréable.

J'ai découvert direnv en 2017 et j'ai commencé à l'utiliser dans un projet en avril 2019.

direnv s'utilise dans un shell, il charge et décharge automatiquement les variables d'environnement spécifiées dans un fichier .envrc lorsqu'on entre et quitte un répertoire.

Exemple :

Voici les use cases listées sur le site officiel de direnv :

  • Load 12factor apps environment variables
  • Create per-project isolated development environments
  • Load secrets for deployment

Voici quelques exemples concrets de mon utilisation de direnv :

source .secret

export SCW_DEFAULT_ORGANIZATION_ID="...." # Get it, in https://console.scaleway.com/organization/settings
export SCW_ACCESS_KEY="..."

# This variable environments are used by Grafana Grizzly
export GRAFANA_URL=http://grafana.$(terraform output --json | jq -r '.server3_public_ip | .value').nip.io
export GRAFANA_USER=admin
export GRAFANA_TOKEN=password
export POSTGRES_ADMIN_URL="postgres://postgres:password@localhost:5432/myapp"
export POSTGRES_URL="postgres://webapp:password@localhost:5432/myapp"
export SMTP_HOST="127.0.0.1"
export SMTP_PORT="1025"
export SECRET="secret"
export APP_HOSTNAME="localhost"
export MAIL_FROM="noreply@example.com"

Les fichiers .envrc sont des scripts shell, il est possible comme dans l'exemple au-dessus, d'utiliser source .secret pour charger un autre fichier.

Je versionne toujours le fichier .envrc, tandis que j'ignore (.gitignore) les fichiers .secret contenant des informations sensibles qui ne doivent pas être publiés dans le repository git.

Après avoir installé un development kit, j'indique à l'utilisateur les instructions à suivre pour installer les éléments de base du projet, comme Mise, Docker…, et la mise en place des secrets.

Mon objectif est ensuite de permettre à l'utilisateur de l'environnement de développement d'interagir avec des « scripts helpers » sans nécessiter de configuration préalable, simplement en entrant ou sortant des dossiers. Les dossiers sont utilisés comme « workspace contexte ».

Voir aussi : development kit skeleton d'installation de direnv

À la recherche d'un environnement de développement sans le savoir : mes années 1999-2008 #dev-kit, #software-engineering

Je pense que je m'intéresse au sujet des "development environment" ou development kit depuis 1999.

À l'époque, même si je ne connaissais pas encore ces concepts, j'en ressentais déjà le besoin.

Par exemple, lorsque j'ai voulu contribuer au projet KDE, je cherchais des solutions et des bonnes pratiques pour organiser ma station de travail de manière à pouvoir compiler et installer KDE sans risquer de casser mon environnement de bureau.
Malheureusement, je n'y suis pas parvenu 😔.

Avec le recul, je réalise que ces pratiques étaient souvent transmises de manière informelle, principalement par des échanges oraux ou via des messages sur IRC. En somme, il s'agissait d'un véritable "bouche-à-oreille" numérique.

Je pense que la majorité des développeurs devaient faire face aux mêmes difficultés. Je pense aussi qu’ils devaient prendre beaucoup de temps à trouver leur propre méthode, année après année.

J’en ai eu une fois la confirmation. En 2002, je suis allé au FOSDEM, pour rencontrer entre autres David Faure, un core développeur français de KDE.

J’ai échangé avec lui et il m’a montré de nombreuses astuces qu’il utilisait… je n’ai pas tout compris, je n’ai pas réussi à les retenir…

J’en ai conclu que les développeurs avaient sans doute chacun leurs propres méthodes de développement non documentées.

Question qui me vient alors à l’esprit : alors qu'ils contribuent à des logiciels libres et partagent leur code source, pourquoi les développeurs ne partagent-ils pas aussi leurs environnements de développement ?

Journal du mercredi 06 novembre 2024 à 14:18 #vocabulaire, #dev-kit, #WebDev, #software-engineering

Je viens de réfléchir à l'usage des termes "development environment" et "development kit".

Je pense que le dépôt gitlab-development-kit est un "development kit" qui permet d'installer et configurer un "development environment" pour travailler sur le projet GitLab.

Journal du lundi 07 octobre 2024 à 15:48 #OnMaPartagé, #JaiDécouvert, #software-engineering

Je viens de déjeuner avec un ami qui m'avait fait découvrir Team Topologies. Cette fois, il m'a fait découvrir le modèle unFIX.

First, the unFIX model is a pattern library that provides many options for describing an organization design, ways of working within a team, decision-making, goal-setting, and more.

Think of the pattern options in the unFIX model as Lego blocks. Like these building blocks, they provide the flexibility to construct and adapt your organization according to your unique needs and preferences.

-- from

Je n'ai pas encore étudié le modèle unFIX.


Un autre sujet de notre discussion a porté sur la difficulté de définir des noms d'équipe générique pour des Stream-aligned team.
Il m'a raconté : « J'ai essayé de m'opposer à l'utilisation des Avengers comme nom d'équipe, mais je n'ai pas réussi ».

Cela m'a fait sourire, car j'ai rencontré un problème similaire avec des noms de Pokémon. Finalement, j'ai cédé et accepté ces noms, à condition de les accompagner de préfixes génériques comme "Team A - ", "Team B - ", etc.

Cette approche s’inspire du pattern de nommage des versions d’Ubuntu, qui utilise un format combinant un identifiant technique et un nom plus créatif, par exemple : "Ubuntu 24.10 - Oracular Oriole".


Pour ma prospection Freelance, il m'a conseillé de regarder du côté de la communauté Tech.Rocks.

Il a confirmé mes retours au sujet de Malt : ses amis ne reçoivent pas de propositions de mission via Malt.


Il m'a partagé cet article Building Stronger, Happier Engineering Teams with Team Topologies (Docker et Team Topologies).

Stratégie de grosse mise à jour de dépendances #dette-technique, #software-engineering

Un ami m'a posé la question suivante :

Imaginez-vous face à un projet React avec des dépendances fortement obsolètes, fonctionnant sur une version de Node datant d’il y a cinq ans. En plus, il n’existe aucun test automatisé, qu'il s'agisse de tests unitaires ou d'intégration. Vous êtes contraint de réaliser cette mise à jour, car elle bloque les futurs développements et entraîne une accumulation excessive de dette technique. Quelle serait votre approche dans cette situation ?

    1. Affronter le problème de front : On prend le taureau par les cornes, on met tout à jour d’un coup, quitte à rencontrer des breaking changes ou des bugs non anticipés, que l’on corrigera rapidement (option rapide mais risquée).
    1. Prudence avant tout : On commence par ajouter des tests sur les parcours critiques, puis on met à jour les dépendances une par une, même si cela prend plus de temps (option lente mais sécurisée).
    1. Déléguer la décision : Ce n’est pas à moi de décider. Je présente ces options aux responsables et leur laisse la décision finale.

Avant de pouvoir répondre à cette question, j'ai besoin de déterminer la criticité business de cette application.

Est-ce que les décideurs acceptent que l'application puisse être en panne pendant 1 heure ? 1 jour ? 3 jours ? Ou aucune interruption n'est-elle tolérée ?

Si la réponse est "moins de 24 heures", alors je considère que l'application est critique.

Ensuite j'ai besoin de savoir si la mise à jour du projet peut être réaliser de manière iso-fonctionnelle (sans changement fonctionnel), sans changement d'User Interface et sans changement du modèle de donnée.

Si la réponse est positive, cela signifie qu'il sera facile de revenir à la version précédente en cas de problème, ce qui simplifie grandement le processus de refactoring.
Une de mes premières actions concrètes serait de "dockeriser" le projet pour faciliter son déploiement et permettre un retour rapide à une version antérieure si nécessaire.

Une autre question importante : d'autres développeurs interviendront-ils sur le projet pendant la période de refactoring ? Est-ce que des corrections de bugs ou de nouvelles fonctionnalités doivent être intégrées durant cette période ?

Si la réponse à l'une de ces questions est "oui", je recommande de dupliquer le projet dans deux dossiers distincts au sein d'un monorepo :

  1. Le premier dossier contiendra la version actuelle de l'application.
  2. Le second dossier contiendra la version en cours de refactoring.

Pendant toute la durée du refactoring, les corrections de bugs et les nouvelles fonctionnalités devront être appliquées aux deux versions.

Dans tous les cas, pour ne pas perdre pied, j'essaierai de mettre à jour l'application petit à petit.
Je commencerai par essayer de mettre à jour toutes les versions mineures des packages.
Ensuite, j'essaierai de me renseigner sur les breaking changes des mises à jour majeures des packages.

Ma réponse si l'application est critique

Si l'application est critique, alors il est inacceptable que les utilisateurs découvrent eux-mêmes les bugs et doivent contacter le support pour signaler les problèmes.

Si l'application ne comporte aucun test, je suppose qu'elle est testée manuellement et que son périmètre fonctionnel reste limité.

L'une de mes premières actions serait de définir un ou plusieurs scénarios de tests manuels prioritaires, que je ferais valider par les décideurs.

Ensuite, je proposerai aux décideurs d'envisager le développement de quelques tests fonctionnels automatisés. Une décision rationnelle à ce sujet dépendrait du temps nécessaire pour effectuer ces tests manuellement et, encore une fois, de la criticité business de l'application.

Enfin, je mettrai en place un système de déploiement progressif, de type A/B testing, permettant de déployer la nouvelle version de l'application à un nombre très restreint d'utilisateurs dans un premier temps.

Ma réponse si l'application est non critique

Si, d'un point de vue business, il est acceptable que les utilisateurs découvrent les bugs, alors je n'implémenterai pas de tests automatisés.

Je définirai tout de même quelques scénarios de tests manuels que le développeur seul exécutera.

Si cela ne demande pas trop de temps, je mettrai en place un système de déploiement progressif, tel que l'A/B testing, permettant de déployer la nouvelle version de l'application à un nombre restreint d'utilisateurs dans un premier temps.

Journal du mercredi 25 septembre 2024 à 11:50 #OnMaPartagé, #software-engineering

#OnMaPartagé la vidéo YouTube nommée Pourquoi les projets informatiques vont dans le mur ?.

Je ne connaissais pas la dérive de ce projet de migration de SAP vers ERP Oracle Fusion de la mairie de Birmingham : La 2e ville du Royaume-Uni s'est déclarée en faillite, plombée entre autres par les dérives d'un projet de migration vers l'ERP Oracle Fusion. Après des années de retards, de problèmes de contrôle, de gestion hasardeuse, la facture du projet a quintuplé pour atteindre 115 M€.

J'ai fait quelques recherches dans les commentaires Hacker News et j'ai trouvé ceci :

My state of Oregon paid Oracle something like $250M for a healthcare system that never materialized. The lawsuit that followed was settled for $100M, but most of that was “free” Oracle licenses and no less than $60M of customer support.

-- from

🙈

Actually it's the opposite. I worked for an NGO half a decade ago, and they wanted to add 2FA authentication to their login system used by ~400 staff. I created a quick demo using Google Authenticator in less than a week.

However the director of IT didn't like this solution. He insisted we use RSA keys and hire IBM to build a solution using that - I think the original estimate was a few million $ and it would take six months or so for their team (of basically new graduates) to build.

I asked my boss why the director was pushing so much for IBM to build it:

He told me that if we build it, and it doesn't work, then the director has to take the blame. If IBM build it, and it doesn't work, then IBM take the blame.

-- from

😭

Yes. There’s also the revolving door problem. The bureaucrat making the decision is often angling for a cushy role at the contractor. And the contractor is making the offer under the table to get the gig. From the decision makers perspective, it doesn’t matter if the project succeeds, they’ll be long gone. I’ve seen this with my own eyes.

-- from

😔

How do they stay in business?

Oracle's main line of competency is not providing good software services. They are in fact, specialists of acquiring government contracts.

-- from

Has anyone ever heard of an Oracle project that has ever ended well?

After 25 years in IT consulting all over the US in different businesses, Oracle is never NOT a 4 letter world, where projects involving them always over-promise, under-deliver, and project costs end up some 3-10x any initial projection. Particularly any ERP, CRM, now EMR in hospitals as well since acquiring Cerner. Anyone that does use them only do as a necessary evil of some dubious or shady circumstances, otherwise Oracle is a term almost universally reviled and hated amongst end users and organization leadership alike.

An insider at Birmingham City Council who has been closely involved in the project told Computer Weekly it went live “despite all the warnings telling them it wouldn’t work”.

Discussing how the Oracle system failure impacted the council’s ability to manage its finances, the insider said: “We were withholding thousands of supplier payments because we couldn’t make any payments. We didn’t have any direct debits for cash collection. We had no cash collection, no bank reconciliation. When you do a project of this size, you must have your financial reporting and you must have a bank reconciliation system that tells you where the money is, what’s being spent and what’s being paid.”

Since going live, the Oracle system effectively scrambled financial data, which meant the council had no clear picture of its overall finances.

The insider said that by January 2023, Birmingham City Council could not produce an accurate account of its spending and budget for the next financial year: “There’s no way that we could do our year-end accounts because the system didn’t work.”

-- from

The June 2023 Birmingham City Council report to cabinet stated that due to issues with the council’s bank reconciliation system (BRS), a significant number of transactions had to be manually allocated to accounts rather than automatically via the Oracle system. However, Computer Weekly has seen an enterprise resource planning (ERP) implementation presentation given in 2019, which shows that the council was made aware of these issues at that time, three years before the go-live date.

...

The lack of a functioning BRS has directly contributed to the council’s current financial crisis. In BCC’s April 2024 audit report, councillor Grindrod said: “We couldn’t accurately collect council tax or business rates.”

As of April 2024, it is believed the manual intervention needed for the bank reconciliation process is costing the council £250,000 per month.

-- from

Peoplesoft/Oracle ERP has had over 30 year of experience selling to local governments globally.

When dealing with procurement in countries that aren't the US, riles and regulations are much more difficult and unintuitive, and also provide marginal RoI.

This is why companies like Workday and Salesforce don't care to compete with Oracle or SAPs in these kinds of contracts - they don't have the right relationships with channel partners and systems integrators needed.

When a city council places a tender for an ERP system, they won't be doing the work in-house due to regulatory and budget allocation reasons. Instead they'll farm out the work to local contractors, MSPs, and Systems Integrators instead.

PLG driven companies like Workday and Salesforce dislike working with SIs and MSPs as much because channel partners don't care about upselling features in the products they bought - they wanna keep the customer satiated instead.

Also, the dollars spent getting the contract might not have a significant RoI when factoring the contract size itself.

-- from

J'ai trouvé ceci sur Reddit :

I work as an implementation consultant for finance software, albeit a much smaller scale one than SAP/Oracle, but I’ve been in this line of work for several years. This kind of thing is fairly common, and I think a several year long project that Lidl undertook to do the same thing went the same way, which is money down the toilet.

All of the cost is in the services. The clients are billed at an hourly or daily rate for meetings, project management, issue resolution, emails etc. The problem with huge projects like these is that institutions like councils have their own very specific processes and are unwilling to change, because more often than not the employees are set in their ways and don’t want to learn anything, but also changing one or two things could have a huge effect on other things. In finance systems there are often several integrations, both incoming and outgoing, and the client will need a tailored solution to migrate everything. It would be easy if the client accepted that some things would have to change, but SAP and Oracle are very very customisable, and depending on the company doing the implementation everything will get customised to where there are all these new moving parts, new problems, and new things to learn. People also change their minds about what they want all the time, especially if the project wasn’t scoped or managed correctly.

In short, the software may be established, but the way it is implemented never is. Templates exist, but every business is different, and the public sector is particularly messy to deal with (underpaid and undertrained staff, tend to be a bit less motivated than private sector IME).

-- from

I tried several different SaaS solutions, mostly aimed at breweries. It was infuriating watching these things fit 98% of the requirement, but the missing 2% rendered the whole system inoperable. But the choice is just take it for £50/user/month or leave it.

I tried some open source options which were better, but were still far too rigid to a point where we'd be shaping our whole operations around the way our ERP wants us to do things, and getting to that point would take a lot of development.

In the end, it was legitimately easier to do it ourselves. And by that I mean me, a distiller, to develop a system from scratch. We now have a fully integrated ERP system that works around our processes, but was built using good practices so that things are very versatile and don't inherently depend on working a certain way. Some of these systems had moronic limitations that wouldn't even allow for an output to be used as an input into another process. Apparently everything has to be made in one process! Can you imagine how many use cases that single, completely unnecessary, restriction... restricts?

-- from

Journal du vendredi 23 août 2024 à 12:35 #software-engineering, #git, #coding

Depuis des années, j'essaie de suivre avec rigueur la doctrine suivante dans les projets utilisant le workflow Trunk-Based Development.

  • La branche trunk doit toujours être stable et contenir uniquement du code fonctionnel.
  • Le code obsolète ou inutilisé doit être supprimé de la branche trunk.
  • Aucun code commenté ne doit figurer dans la branche trunk.
  • La branche trunk ne contient pas de tests qui échouent.

Pourquoi ?

  • Pour éviter qu'un développeur perde du temps à essayer de faire fonctionner quelque chose qui n'est pas en état de marche.
  • Pour éviter qu'un développeur refactore du code mort — j'ai observé à nouveau cela, il n'y a pas longtemps 😔. Quand le développeur fini par le découvrir, il est généralement très frustré.
  • Pour éviter l'installation et la mise à jour de bibliothèques qui alourdissent inutilement le projet.
  • Pour prévenir une perte de confiance dans le projet (voir l'hypothèse de la vitre brisée).

Et si j'ai besoin de ce code plus tard ?

Tout d'abord, je vous réponds "YAGNI" 🙂.

Plus sérieusement, ma réponse est que votre code ne sera pas perdu étant donné qu'il est versionné dans votre repository.

Si le code commenté est en cours de développement, alors je suggère d'extraire ce code en préparation dans une Merge Request et de la merger quand elle sera prête.

Trouvez le bon équilibre

Un morceau de code commenté ou un test qui échouent peut tout à fait rester dans trunk sur une courte période. Dans ce cas, je conseille d'ajouter en commentaire un lien vers l'issue de dette technique qui détaille l'action prévue.

Journal du mercredi 21 août 2024 à 09:39 #software-engineering, #git, #JaiDécouvert

Après avoir rédigé la note Commit Cavalier, #JaiDécouvert le concept de des projets de loi omnibus.

« Depuis les années 1980, cependant, les projets de loi omnibus sont devenus plus courants : ces projets de loi contiennent des dispositions, parfois importantes, sur un éventail de domaines politiques. »

-- from

Ceci m'a fait penser aux Merge Requests qui contiennent de nombreux petits commits, souvent de refactoring, qu'il serait fastidieux de passer en revue individuellement.

Je pense que je vais nommer ces Merge Request, des Merge Request Omnibus, ce néologisme sera une de mes marques idiosyncrasiques 😉.

J'ai donc décidé de baptiser ces Merge Requests des Merge Requests Omnibus. Ce néologisme deviendra l'une de mes marques idiosyncrasiques 😉.

Journal du mardi 20 août 2024 à 23:26 #software-engineering, #git, #coding

Je tente ici de présenter la notion de Git Commit dit "cavalier" en la reliant au concept de Cavalier Législatif.

Un cavalier législatif est un article de loi qui introduit des dispositions qui n'ont rien à voir avec le sujet traité par le projet de loi.

Ces articles sont souvent utilisés afin de faire passer des dispositions législatives sans éveiller l'attention de ceux qui pourraient s'y opposer.

-- from

Dans le contexte de développement logiciel, un Commit Cavalier désigne un commit inséré dans une Pull Request ou Merge Request qui n’a aucun lien direct avec l’objectif principal de celle-ci.

Cette pratique pose les problèmes suivants :

Il va sans dire que cette pratique a le don de m'irriter profondément. Par respect pour mon reviewer et mon équipe, je veille scrupuleusement à ne jamais soumettre de commit cavalier.

Journal du mardi 20 août 2024 à 18:05 #software-engineering, #git, #coding

Depuis 2012, je pratique exclusivement le Git Rebase Workflow pour tous mes projets de développement.

Concrètement :

  • J'utilise git pull --rebase quand je travaille dans une branche, généralement une Pull Request ou Merge Request ;
  • Je pousse régulièrement des commits en "work in progress" au fil de l'avancée de mon travail dans ma branche de développement avec la commande git commit -m "WIP"; git push ;
  • Une fois le travail terminé, je squash mes commits à l'aide de git rebase -i HEAD~[NUMBER OF COMMITS] ;
  • Ensuite, je rédige un commit message qui contient la description du changement et le numéro de l'issue ou de la merge request git commit --amend ;
  • Enfin, j'effectue un Merge en Fast-Forward en utilisant l'interface de GitHub ou GitLab.

Pour cela, je paramètre GitLab de la façon suivante (navigation "Settings" => "General") :

Ou alors je paramètre GitHub de la façon suivante (navigation "Settings" => "General")

Les avantages de cette pratique

L'approche Rebase + Squash + Merge Fast-Forard permet de maintenir l'historique de changements linéaire, rendant celui-ci plus facile à lire et à comprendre.

L'historique ne contient aucun commit de fusion inutile.

Cela facilite la mise en place d'Intégration Continue.

Tous les problèmes, bugs, et conflits sont traités dans les branches, dans les Merge Request et jamais dans la branche main qui se doit d'être toujours stable, ce qui améliore grandement le travail en équipe.

Ce workflow est particulièrement puissant lorsque l'historique linéaire ne contient que des commit dit "atomic", c’est-à-dire : 1 issue = 1 merge request = 1 commit. Un commit est considéré comme "atomic" lorsqu'il ne contient qu'un seul type de changement cohérent, tel qu'une correction de bug, un refactoring ou l'implémentation d'une seule fonctionnalité.

À de rares exceptions près, le code source de la branche main doit rester stable et cohérent tout au long de l'historique des commits.

Cette discipline favorise un travail collaboratif de qualité, rendant plus compréhensible l'évolution du projet.

De plus, l'atomicité des commits facilite la revue des Merge Request et permet d'éviter les Commits Cavaliers.

Généralement je couple ce Git workflow au workflow nommé Trunk-Based Development.

Journal du mardi 20 août 2024 à 09:33 #software-engineering, #JaiLu

#JaiLu Software estimates have never worked and never will

Je suis en accord — depuis très longtemps — avec le contenu de cet article.

Give up on estimates, and embrace the alternative method for making software by using budgets, or appetites, as we call them in our Shape Up methodology.

Cette méthode fait parti de ma doctrine d'artisan développeur.

Journal du vendredi 16 août 2024 à 13:17 #software-engineering, #coding

J'ai relu cette note de David Larlet :

Silk = documentation et tests

Markdown based document-driven web API testing.

Silk

La rapidité d’exécution d’un outil écrit en Go est toujours surprenante, j’ai eu besoin de vérifier que les tests étaient bien passés pour être sûr de son bon fonctionnement… Mon expérience me montre qu’une documentation qui n’est pas testée/proche du code n’est jamais synchronisée et conduit à des frustrations pour les utilisateurs. Silk est un moyen de faire cela directement depuis votre markdown, ça me rappelle d’une certaine manière le couple docutils/reStructuredText. En rapide. Et je ne saurais trop insister sur l’importance d’avoir une suite de tests rapide pour qu’elle reste pertinente.

Raconter une histoire dans vos tests est plus verbeux mais assurément plus intéressant pour la personne qui cherchera à comprendre ce que vous avez implémenté. Il y a de grandes chances que ce soit vous. Le README du dépôt est un exemple de ce qui peut être réalisé.

-- 25 février 2016

Je pense que ce billet a participer à ma sensibilitasion à la notion de colocated documentation.

Journal du vendredi 16 août 2024 à 13:06 #software-engineering, #coding

Dans ma note Keep it simple, stupid le plus longtemps possible j'ai écris :

Je me souviens de la quête vers le minimaliste dans le code de David Larlet : « Est-ce qu’il est possible d'enlever des couches dans la stack ? »

Je viens d'essayer de retrouver ces articles, mais ce n'est pas facile tellement les articles de David Larlet sont nombreux.

Pour le moment j'ai retrouvé les extraits ci-dessous ceci en lien avec le sujet.

Paternité

  1. Ajouter des couches
  2. Changer des couches
  3. Enlever des couches
  4. Changer des couches
  5. Mettre des couches

J’en suis à l’étape 3 dans ma maturité en tant que développeur. La paternité change les priorités et je pense qu’elle a un grand rôle dans le fait de vouloir remettre le focus sur la valeur apportée plus que sur la technique. Me battre pour une meilleure expérience utilisateur plutôt que contre un framework, chercher à se faire plaisir davantage via ce qui est produit que par un contentement technique.

Lorsque j’expérimente aujourd’hui, ce n’est plus pour découvrir une nouvelle bibliothèque mais pour trouver de nouveaux moyens de simplifier un problème. Dans ce contexte, il est intéressant de re-questionner la page blanche (cache), de re-challenger certaines bonnes pratiques communément admises (cache).

-- 22 avril 2016

Autre extrait :

Leftpad

Every package that you use adds yet another dependency to your project. Dependencies, by their very name, are things you need in order for your code to function. The more dependencies you take on, the more points of failure you have. Not to mention the more chance for error: have you vetted any of the programmers who have written these functions that you depend on daily?

NPM & left-pad: Have We Forgotten How To Program? (cache)

J’étais en train de préparer cette intervention lorsque le fiasco leftpad est arrivé dans l’écosystème NPM. Du coup, j’ai eu immédiatement plein d’articles faisant une ode à la simplicité, à la réduction de dépendances et mettant en garde contre les couches d’abstraction. Merci Azer Koçulu, je pouvais difficilement rêver mieux :-). Je ne vais pas tirer sur l’ambulance mais ça illustre presque trop bien mon propos.

as your project progresses, your team’s productivity will drop because of all the complexity and dependencies. You’ll need more people to maintain it, and more people with specific knowledge to maintain it. If your lead developers leave, you’re dead. You should be fighting complexity and not embracing it. Every added framework, and even library, makes your project more difficult to maintain. Avoid unnecessary frameworks and libraries from day one.

Frameworks don’t make much sense (cache)

Jusqu’où aller dans cette démarche ? Par où commencer ?

-- 22 avril 2016

Autre extrait :

Burnout technique

Maybe it’s not too late for you, though. Perhaps, like me, you aren’t feeling particularly overworked. But are you feeling irritable, tired, and apathetic about the work you need to do? Are you struggling to concentrate on simple tasks?

Then maybe what you’re feeling is burnout, too.

Avoiding the Trap (cache)

J’ai travaillé pendant un an et demi avec Mozilla sur la partie paiement du Marketplace puis sur le site des extensions de Firefox. Et depuis un an avec Etalab sur la plateforme datagouv. Dans les deux situations, j’ai passé davantage de temps à lutter contre les outils plutôt qu’à les apprécier pour le travail rendu. C’est terrible car ceux-ci sont censés théoriquement faire gagner du temps mais sur le long terme cela se révèle être faux dans mon cas.

Je me demande si je ne suis pas en train de faire un burnout technique, non pas par trop de travail mais par manque de contrôle dans mes outils.

-- 22 avril 2016

Autre extrait :

The aesthetic microlith

Growth for the sake of growth is the ideology of the cancer cell.

Edward Abbey

Toutes ces raisons m’ont amené à étudier une nouvelle piste. Cette appellation est une combinaison du Majestic Monolith (cache) et des microservices. Je me persuade qu’il y a une voie différente entre ces deux extrêmes. Une voie qui limite les fuites d’abstraction (cache) afin de réduire la dette technique et de favoriser l’inclusion de nouveaux membres dans une équipe. Une voie qui ne demande pas de réécrire la moitié de l’application tous les six mois car une nouvelle montée en version majeure n’est pas rétro-compatible. Une voie où l’on ne raisonne plus en termes de features et de bugs mais d’expérience utilisateur et de satisfaction pour l’ensemble des parties prenantes. Un environnement qui permet de faire une pause dans les développements afin de prendre le temps de davantage considérer les besoins des personnes qui utilisent le produit.

We all want things to be simpler. But we may not know what to sacrifice in order to achieve that goal.

What Makes Software Good? (cache)

Dans cette recherche de simplicité, j’ai essayé de remettre en question chaque concept de programmation, chaque bonne pratique, chaque bibliothèque, chaque ligne de code. J’ai essayé de produire un prototype qui soit un peu plus conséquent que celui proposé à Confoo pour voir jusqu’où cela pouvait aller. Ce qu’il me manque c’est non pas du temps de développement mais du temps de vie du projet pour analyser les effets produits sur le moyen terme. Je devrais avoir l’occasion d’expérimenter cela avec scopyleft prochainement, ça sent la trilogie.

À court terme en tout cas, c’est extrêmement plus fun à coder et l’on arrive au résultat finalement aussi rapidement. Cela devient une matière beaucoup plus malléable, dont on connait les forces et les faiblesses car le périmètre est réduit. En contrepartie, certains cas aux limites vont être écartés et l’expérience de certains utilisateurs se dégrade plus rapidement. Ce n’est pas que le coût de prise en compte soit énorme, il s’agit davantage de le prendre en considération lorsque le besoin est réel.

-- 22 avril 2016

Autre extrait :

Maintenance

Capitalism excels at innovation but is failing at maintenance, and for most lives it is maintenance that matters more

Innovation is overvalued. Maintenance often matters more (cache)

Le problème ici c’est que je n’ai jamais rencontré de projet qui réduisent leur complexité dans le temps. Que ce soit via des itérations de retrait ou des réécritures complètes on arrive toujours à des usines à gaz si l’on ne s’est pas fixé en amont — de manière consentie par toutes les parties prenantes — les budgets évoqués plus haut. Pourtant en restant à l’échelle du microlith, la maintenance se trouverait potentiellement réduite de beaucoup.

Si l’on s’en tient à l’estimation selon laquelle la maintenance représente 67% d’un produit (cache), il devient important de trouver comment réduire ce coût.

-- 22 avril 2016

Autre extrait :

Frameworks, API et prolétarisation

La présentation 6 reasons why APIs are reshaping your business fait l’analogie du développement Web avec l’industrie automobile et le passage de l’artisanat à l’intégration de pièces toutes faites.

Si le passage aux frameworks JavaScript et CSS a entraîné la perte de savoir des développeurs front-end et leur prolétarisation, le passage aux API va avoir le même effet sur les développeurs back-end, ceux-ci devenant de simples intégrateurs de solutions existantes s’éloignant de la problématique métier et de ses données pour se perdre dans les couches du pragmatisme. N’oubliez pas qu’en facilitant le travail de la machine, on finit par être remplacé par la machine, c’est ce que nous réserve l’industrialisation du Web. Et ça me rend nostalgique.

-- 18 décembre 2012

Autre extrait :

A system where you can delete parts without rewriting others is often called loosely coupled, but it’s a lot easier to explain what one looks like rather than how to build it in the first place.

Even hardcoding a variable once can be loose coupling, or using a command line flag over a variable. Loose coupling is about being able to change your mind without changing too much code.

Write code that is easy to delete, not easy to extend (cache)

Partant de ce constat, j’ai essayé de produire une stack minimaliste qui comportent très peu de dépendances qui peuvent évoluer en fonction du besoin. De cette manière, on accède à un LEAN techniqueLEAN technique : l’ajout de complexité architecturale en fonction du besoin uniquement.

Le code produit accorde une place importante à l’esthétique et à la modularité sans endommager la compréhension de l’ensemble grâce à la documentation et aux tests.

-- 25 février 2016

Autre extrait :

Thus teams are often confronting the uncomfortable choice between a risky refactoring operation and clean amputation. The best developers can be positively gleeful about amputating a diseased piece of code (even when it’s their own baby, so to speak), recognizing that it’s often the best choice for the overall health of the project. Better a single module should die than continue to bog down the rest of the project.

The organic, evolutionary nature of code also highlights the importance of getting your APIs right. By virtue of their public visibility, APIs can exert a lot of influence on the future growth of the codebase. A good API acts like a trellis, coaxing the code to grow where you want it. A bad API is like a cancer, and it will metastasize all over your codebase.

A Codebase is an Organism (cache)

L’intérêt de partir d’un périmètre aussi restreint est de pouvoir se ré-interroger à chaque nouvel ajout sur sa pertinence, cela constitue une base itérative sans renoncer au plaisir technique. Le code est lisible et explicable en quelques heures pour des personnes ayant un faible niveau et il n’y a pas besoin de télécharger la moitié d’internet pour faire tourner une page web. Ma démarche est de renoncer à la complexité par défaut qui est prônée par tous les frameworks actuels, l’ajout de dépendances doit se faire au moment du besoin.

La durée de vie d’une composition de technologies est forcément réduite et demande de se ré-interroger à échéances régulières sur sa pertinence. Toute la difficulté actuelle est de pouvoir allonger ces échéances pour trouver le bon ratio entre focus et exploration. Plus vous bâtirez sur des concepts simples, universels et standardisés, plus vous aurez de chances de pouvoir être conservateur dans votre choix technique. Et plus vous serez inclusif auprès des potentiels contributeurs.

-- 25 février 2016

Journal du vendredi 16 août 2024 à 11:39 #software-engineering, #JaiLu

#JaiLu la note de David Larlet nommée Initiateurs et mainteneurs.

There are two roles for any project: starters and maintainers. People may play both roles in their lives, but for some reason I’ve found that for a single project it’s usually different people. Starters are good at taking a big step in a different direction, and maintainers are good at being dedicated to keeping the code alive.

I am definitely a starter. I tend to be interested in a lot of various things, instead of dedicating myself to a few concentrated areas. I’ve maintained libraries for years, but it’s always a huge source of guilt and late Friday nights to catch up on a backlog of issues.

Starters and Maintainers (cache)

Je suis également un initiateur. J’aime créer de nouvelles choses en expérimentant des usages et des techniques. Lorsque je me retrouve dans un rôle de mainteneur, j’ai tendance à complexifier l’existant et à le rendre moins stable par ma soif d’apprendre de nouvelles choses. Or l’apprentissage nait de l’échec et du test des limites. C’est assez désastreux pour les projets et je pense que l’engouement pour les microservices est un complot des initiateurs en mal d’expérimentations au sein d’applications à maintenir. À moins que la maintenance soit un vestige du passé (cache).

-- from

Ces réflexions résonnent profondément en moi 🤗, car ce sont des questions et des pensées qui m'habitent depuis de nombreuses années.

« j’ai tendance à complexifier l’existant et à le rendre moins stable par ma soif d’apprendre de nouvelles choses »

Pour éviter cette tendance à complexifier l’existant, j'utilise la stratégie suivante. Lorsque je ressens le besoin d'expérimenter ou d'apprendre quelque chose de nouveau, je le fais au travers des side projects personnels ou dans le cadre de POC (Proof of Concept) et Spike officiellement décidés en équipe. C'est entre autres pour cette raison que j'avais proposé de mettre en place les Spike and Learn Day.

Cette approche me permet de satisfaire ma curiosité et mon envie d'apprendre, tout en maintenant l'utilisation de Boring Technology pour les projets critiques ou ceux menés en équipe. Ainsi, je parviens à éviter le piège du Resume Driven Development.

J'aime bien la distinction suivante :

« There are two roles for any project: starters and maintainers »

Jusqu'à présent, j'ai tendance à utiliser le terme solo développeurs pour les "starters" et team développeurs pour les "maintainers".

Petite anecdote amusante : lors de mon expérience chez Spacefill, j'avais proposé de nommer le rôle des développeurs d'expérience au sein de l'équipe les "maintainers" 😉.

« C’est assez désastreux pour les projets et je pense que l’engouement pour les microservices est un complot des initiateurs en mal d’expérimentations au sein d’applications à maintenir. »

C'est une réflexion que j'ai moi-même eue par le passé.

Je crois en effet que les solo développeurs apprécient particulièrement les microservices et les multi repositories car cela leur permet d'éviter les contraintes d'équipes.
Cela leur permet d'explorer des nouveaux langages et frameworks et d'échaper aux revues de code.

À mes yeux, cette approche favorise davantage l'individualisme que la cohésion d'équipe.

J'ai également remarqué que c'est souvent lors des phases de storming du modèle de Tuckman que les développeurs semblent se tourner vers les microservices comme une forme d'évitement des défis collectifs. Cette stratégie peut sembler séduisante, mais elle risque de renforcer les silos et de freiner la collaboration au sein de l'équipe 🤔.

Journal du vendredi 16 août 2024 à 11:30 #complexité, #coding, #software-engineering, #JaiDécouvert

#JaiDécouvert l'expression Core-stack developer dans cet article de David Larlet :

… when in doubt, focus on the core. When in doubt, learn CSS over any sort of tooling around CSS. Learn JavaScript instead of React or Angular or whatever other library seems hot at the moment. Learn HTML. Learn how browsers work. Learn how connections are established over the network.

The reason for focusing on the core has nothing to do with the validity of any of those other frameworks, libraries or tools. On the contrary, focusing on the core helps you to recognize the strengths and limitations of these tools and abstractions. A developer with a solid understanding of vanilla JavaScript can shift fairly easily from React to Angular to Ember. More importantly, they are well equipped to understand if the shift should be made at all. You can’t necessarily say the same thing about an INSERT-NEW-HOT-FRAMEWORK-HERE developer.

Building your core understanding of the web and the underlying technologies that power it will help you to better understand when and how to utilize abstractions.

That’s part one of dealing with the rapid pace of the web.

The Fallacy of Keeping Up (cache)

À défaut d’être complet (full) en raison de l’effervescence technique difficile à suivre au quotidien, il me semble de plus en plus pertinent de miser sur le cœur (core) des technologies utilisées. Comprendre et maîtriser les bases avant tout pour pouvoir ponctuellement et rapidement se spécialiser en fonction du besoin. Connaître ES6 vous servira ces 10 prochaines années, savoir utiliser React sera obsolète l’année prochaine. Sages développeurs, investissez.

-- from

Core-stack developer me fait penser à Choose Boring Technology et à mon article nommé Sur quelles compétences j'ai décidé ou non d'investir mon temps ?. Je me rends compte rétrospectivement que j'ai listé ma core-stack 🙂.

Journal du lundi 12 août 2024 à 13:25 #coding, #software-engineering, #typescript

Quel est mon rapport aux langages typés ?

Pour bien comprendre mon approche des langages typés, il est utile de revenir sur mon parcours.

Enfant, j'ai commencé par du Locomotive Basic (non typé), j'ai ensuite fait beaucoup de Turbo Pascal (typé) et un peu de C, C++ (typé).

À cette époque, je préférais les langages typés pour des raisons de performances.

En 2000, j'ai vraiment aimé utiliser à nouveau des langages non typés, comme PHP et surtout Python qui a été pendant très longtemps mon langage de prédilection.

J'ai à nouveau beaucoup pratiqué un langage typé de 2013 à 2018 : Golang.

Aujourd'hui, je considère qu'il est souvent plus facile et plus rapide de programmer dans un langage non typé, notamment grâce au Duck Typing. Cependant, je reconnais que les langages typés offrent des avantages indéniables, notamment en matière de refactoring de code.

Je pense qu'il est préférable d'utiliser un langage typé sur un projet critique.

Je pense qu'il est préférable d'utiliser un langage typé pour les programmes qui manipule des données complexes et divers.
C'est, par exemple, pour cela que ne suis pas un utilisateur de MongoDB. Je préfère une base de données PostgreSQL où tout est bien typé.

Il ne me viendrait pas à l'esprit d'implémenter une base de données ou un moteur web dans un langage non typé.

Par contre, je suis moins convaincu par l'utilisation d'un langage typé pour les applications d'interface utilisateur lourde ou web.

Lorsqu'une équipe de développement travaillant sur un code commun atteint une certaine taille — je n'ai aucune idée de ce nombre — je suis convaincu qu'il devient préférable d'utiliser un langage typé.

Journal du vendredi 02 août 2024 à 14:11 #dette-technique, #software-engineering, #réponse

J'ai partagé la note au sujet des Quick Fixes du 31 juillet 2024 à un ami — profil Développeur sénior, Architecte informatique, plus de 20 ans d'expérience — et voici ma réponse à ses commentaires.


« Je tiens à préciser que la solution « On le fera plus tard quand on aura le temps » n'arrive jamais. » -- from

« Je confirme ... remettre à plus tard, reviens à dire que ce ne sera jamais fait. Quand t'as un ticket dans le backlog qui s'appelle "C'était pas terrible faudrait refaire mieux .." et qui n'a pas été touché depuis 6 mois, tu sais que tu peux le foutre à la benne. » -- mon ami

🙂.

« a. Durant toute la vie du projet, accorder entre 20 et 40% du temps — "de l'énergie" — au traitement de la dette technique. » -- from

« Oui, mais ça ne marche que dans les équipes en mode produit ... pas dans les équipes qui fournissent du "service" 😉 » -- mon ami

Je pense que tu as malheureusement raison.

C'est pour cela que je pense qu'il est préférable que les services de l'État internalisent les compétences informatiques plutôt que passer par des ESN.

C'est pourquoi je crois qu'il est préférable que les services de l'État internalisent les compétences informatiques plutôt que de passer par des ESN. Je pense à des projets comme Louvois (projet), SIRHEN (projet), ou ONP (projet).

Journal du vendredi 02 août 2024 à 10:40 #dette-technique, #software-engineering, #réponse

J'ai partagé la note au sujet des Quick Fixes du 31 juillet 2024 à un ami — profil Product Manager — et voici ma réponse à ses commentaires.


« Ce que je retiens principalement et qui est, à mon avis, sous-estimé, c’est l’impact psychologique de travailler dans le chaos et d’avoir l’impression d’une dette insurmontable. Pour moi, la motivation et le sens de ce qu’on fait, c’est vraiment l’enjeu clé. Je pense donc qu’il est essentiel d’avoir une gestion saine et transparente de tout ça, le quick fix est néfaste à long terme. » -- mon ami

Je trouve cela intéressant que tu soulignes "l'impact psychologique" 👍️. Je partage cet avis et cela rejoint cette partie de ma note :

« D'après mon expérience, lorsque le développement d'une application est fait en équipe, l'accumulation de Quick Fixes entraîne rapidement :

Ensuite :

« Sur la question des explorations/spikes, je suis partagé. De ma modeste expérience, ça n’a jamais été concluant. Ça ne permet pas de valider une quelconque « pain » business qu’on n’aurait pas pu valider d’une autre manière. » -- mon ami

Je comprends ton point de vue. Comme toi, autant que je me souvienne, je n'ai jamais participé à une exploration de produit réussie destinée aux utilisateurs B2B ou B2C.
Je pense qu'il y a deux raisons à cela : la première est que, de mon point de vue, ces expériences n'étaient pas réalisées avec le niveau de rigueur nécessaire.
La seconde est que ce type d'activité est intrinsèquement difficile à mener.

Cependant, j'ai réalisé des spikes produits — objectifs d'explorations de features — avec succès pour des utilisateurs internes — stakeholder.
Ces spikes m'ont permis plusieurs choses :

  • De rendre concrètes des idées pas toujours comprises par des descriptions verbales ;
  • De gagner la confiance des stakeholders, et d'éviter une longue période de vaporware ;
  • De créer un artefact facilitant la convergence d'un groupe — développeurs, product managers, stakeholders — vers un objectif commun.

« et ça n’aide pas franchement la tech à débroussailler les écueils techniques. » -- mon ami

Mon expérience concernant les spikes techniques est différente. Pour moi, c'est une méthode qui fonctionne sans hésitation.

Ce que j'observe sur moi-même et je pense chez d'autres personnes :

  • Les spikes mettent moins de pression aux développeurs sur des tâches complexes.
  • Les spikes réduisent l'Effet Ikea des développeurs. Ils savent que c'est un spike et que sa solution sera probablement abandonnée.
  • Les spikes réduisent l'entêtement, facilitant la pratique du timeboxing.
  • Les spikes indiquent clairement aux développeurs qu'on n'attend pas une fonctionnalité finie et sans bug.

(Voir aussi ma note à propos d'un risque potentiel lié à l'usage des spikes).

J’ai pas encore avancé dans ma réflexion là-dessus, mais j’ai l’impression qu’un projet, s’il est important, doit être conduit proprement dès le départ. Si on n’a pas le temps de le faire proprement, c’est que c’était pas nécessaire, et ça va ajouter de la complexité inutilement.

Je te rejoins très fortement sur cette dernière phrase 👍️.

Journal du mercredi 31 juillet 2024 à 11:11 #dette-technique, #software-engineering, #startup

Une amie m'a demandé ce que je pense de cette déclaration :

« Selon moi, la résolution de problème se déroule en deux étapes : d'abord, on traite les symptômes. Si le problème persiste, on prend plus de temps pour en identifier et résoudre la cause profonde.
Cette doctrine est particulièrement adapté aux Startup ».

Cette question de fait penser à la citation du chapitre "Quick Fixes Become Quicksand" du livre Practices of an Agile Developer :

« You don't need to really understand that piece of code; it seems, to work OK as is. Oh, but it just needs one small tweak. Just add one to the result, and it works. Go ahead and put that in; it's probably fine. »

De mon expérience — dans le domaine du software engineering —, le bon dosage de l'usage des Quick Fixes, QuickWin est une source de désacord classique au sein d'une organisation.
Et ceci arrive d'autant plus lorsqu'une équipe est dans sa période de storming.

La lecture du chapitre Quick Fixes Become Quicksand en 2007 m'a beaucoup marqué et ne m'a jamais quitté depuis, je peux dire qu'il fait parti de ma doctrine d'artisan développeur.

Voici-ci dessous les screenshot et la version texte de ce chapiter.

(cliquer ici pour voir ces screenshots en grand)

Voici la version texte de ce chapitre.

Quick Fixes Become Quicksand

You don't need to really understand that piece of code; it seems, to work OK as is. Oh, but it just needs one small tweak. Just add one to the result, and it works. Go ahead and put that in; it's probably fine.”

We've all been there. There's a bug, and there's time pressure. The quick fix seems to work— just add one or ignore that last entry in the list, and it works OK for now. But what happens next distinguishes good programmers from crude hackers.

The crude hacker leaves the code as is and quickly moves on to the next problem.

The good programmer will go to the next step and try to understand why that +1 is necessary, and—more important—what else is affected.

Now this might sound like a contrived, even silly, example, except that it really happened — on a large scale. A former client of Andy's had this very problem. None of the developers or architects understood the underlying data model of their domain, and over the course of several years the code base became littered with thousands of +1 and -1 corrections. Trying to add features or fix bugs in that mess was a hair-pulling nightmare (and indeed, many of the developers had gone bald by then).

But like most catastrophes, it didn't get like that all at once. Instead, it happened one quick fix at a time. Each quick fix — which ignored the pervasive, underlying problem — added up to a swamp-like morass of quicksand that eventually sucked the life out of the project.

« Beware of land mines »

Shallow hacks are the problem — those quick changes that you make under pressure without a deep understanding of the true problem and any possible consequences. It's easy to fall prey to this temptation: the quick fix is a very seductive proposition. With a short enough lens, it looks like it works. But in any longer view, you may as well be walking across a field strewn with land mines. You might make it halfway across — or even more — and everything seems fine. But sooner or later...

As soon as that quick hack goes in, the clarity of the code goes down. Once a number of those pile up, clarity is out the window, and opacity takes over. You've probably worked places where they say, “Whatever you do, don’t touch that module of code. The guy who wrote it is no longer here, and no one knows how it works.” There's no clarity. The code is opaque, and no one can understand it.

You can't possibly be agile with that kind of baggage. But some agile techniques can help prevent this from happening. We'll look at these in more depth in later chapters, but here's a preview.

Isolation is dangerous; don’t let your developers write code in complete isolation (see Practice 40, Practice Collective Ownership, on page 155). If team members take the time to read the code that their colleagues write, they can ensure that it's readable and understandable—and isn’t laced with arbitrary “+1s and -1s”. The more frequently you read the code, the better. These ongoing code reviews not only help make the code understandable but they are also one of the most effective ways of spotting bugs (see Practice 44, Review Code, on page 165).

The other major technique that can help prevent opaque code is unit testing. Unit testing helps you naturally layer the code into manageable pieces, which results in better designed, clearer code. Further into the project, you can go back and read the unit tests — they're a kind of executable documentation (see Practice 19, Put Angels on Your Shoulders, on page 78). Unit tests allow you to look at smaller, more comprehensible modules of code and help you get a thorough understanding by running and working with the code.

Conseil de petit ange : A Don't fall for the quick hack. Invest the energy to keep code clean and out in the open.

What It Feels Like

It feels like the code is well lit; there are no dark corners in the project. You may not know every detail of every piece of code or every step of every algorithm, but you have a good general working knowledge. No code is cordoned off with police tape or “Keep Out” signs.

Keeping Your Balance

  • You need to understand how a piece of code works, but you don't necessarily have to become an expert at it. Know enough to work with it effectively, but don't make a career of it.
  • If a team member proclaims that a piece of code is too hard for anyone else to understand, then it will be too hard for anyone (including the original author) to maintain. Simplify it.
  • Never kludge in a fix without understanding. The +1/-1 syndrome starts innocently enough but rapidly escalates into an opaque mess. Fix the problem, not the symptom.
  • Most nontrivial systems are too complex for any one person to understand entirely. You need to have a high-level understanding of most of the parts in order to understand what pieces of the system interact with each other, in addition to a deeper understanding of the particular parts on which you're working.
  • If the system has already become an opaque mess, follow the advice given in Practice 4, Damn the Torpedoes, Go Ahead, on page 23.

Andy Says : Understand Process. Too

Although we're talking about understanding code, and especially understanding code well before you make changes to it, the same argument holds for your team’s methodology or development process.

You have to understand the development methodology in use on your team. You have to understand how the methodology in place is supposed to work, why things are the way they are, and how they got that way.

Only with that understanding can you begin to make changes effectively.

Mon point de vue plus détaillé

Voici une version plus personnelle de ma philosophie — ma doctrine d'artisan développeur — à ce sujet. Je précise qu'elle est bien plus longue que ce que j'avais prévu et qu'elle dépasse la question de départ de mon ami… oui, je suis tombé dans un Yak! 🙂.

J'accepte d'utiliser des Quick Fixes — même sans bien comprendre le problème — dans les situations suivantes :

  • Dans un Proof of Concept ou un code exploratoire ;
  • Dans une application ou un composant d'application destiné à être rapidement abandonné ;
  • En cas d'urgence, si le bug impacte les clients. Dans ce cas, j'applique un Quick Fixes en production, puis, je m'efforce, dans un second temps, de comprendre et de corriger correctement le problème par la suite ;
  • Si je suis solo développeur sur l'application et que celle-ci n'est pas critique pour le client.

D'après mon expérience, lorsque le développement d'une application est fait en équipe, l'accumulation de Quick Fixes entraîne rapidement :

Je tiens à préciser que la solution « On le fera plus tard quand on aura le temps » n'arrive jamais.

En 20 ans d'expérience, j'ai toujours travaillé dans des organisations où l'urgence était la norme. L'urgence permanente est tout ce que j'ai connu. Je pense que cela reflète la nature humaine.

Ainsi, la déclaration « Oui, mais nous, c'est différent, tu comprends, on n'a pas le temps » n'a pas de sens à mes yeux, car c'est le cas pour tout le monde.

Avec le temps, j'ai construit la doctrine suivante pour gérer les Quick Fixes et donc la dette technique en équipes :

  • a. Durant toute la vie du projet, accorder entre 20 et 40% du temps — "de l'énergie" — au traitement de la dette technique.
  • b. Si une dette jugée critique ne peut pas être traitée durant ce temps imparti, je propose de l'expliquer au Product Management et éventuellement à la direction afin qu'un choix stratégique soit fait pour lui allouer plus de temps en la priorisant comme objectif de Sprint (scrum).

Par expérience, j'observe que si la règle a est appliquée, alors la situation b se produit exceptionnellement.

L'itération pour éviter de tomber dans l'overthinking et l'overengineering !

Je pense qu'un certain nombre de leaders de startup créent un climat d'urgence pour éviter que les développeurs tombent dans de l'overthinking et de l'overengineering.
Bien que cette approche soit compréhensible, j'ai personnellement une autre méthode pour éviter ces écueils sans recourir à l'urgence.

Ma solution pour éviter de tomber dans ces travers sont :

  • l'itération ;
  • le time boxing, autrement dit l'utilisation de spikes ou la définition de l'appétit d'un sprint ;
  • sensibiliser les développeurs aux Yak!.

Par itération, j'entends la livraison du plus petit Incrément (Scrum) possible et sa mise en production dès que possible.

Le choix du plus petit incrément possible doit être associé aux principes Keep it simple, stupid! (KISS) et You aren't gonna need it (YAGNI).

L'esprit marathon en meuthe plutôt que des courses de 100m !

Comme le dit la Loi de Gall, je pense que :

Un système complexe qui fonctionne se trouve invariablement avoir évolué depuis un système simple qui fonctionnait. La proposition inverse se révèle également exacte : Un système complexe développé de A à Z ne fonctionne jamais et vous n'arriverez jamais à le faire fonctionner. Vous devez recommencer depuis le début, en commençant par un système simple.

Ici j'entends par "système complexe" à la fois le logiciel et l'organisation humaine.

Je crois également à « New systems mean new problems ».

Depuis des années, j'observe de nombreuses startups en situation d'urgence vivre des cycles sans fin de reboot — une fois par an ou tous les deux ans —, accompagnés d'un turnover élevé.
Les projets sont constamment recommencés à zéro, avec de nouvelles équipes.
Je doute fortement que le pari de la vitesse — la course de 100m — soit plus efficace que celui du marathon.

Attention à bien identifier les projets et phases d'explorations !

Il m'est arrivé à plusieurs reprises de ne pas identifier correctement les signaux faibles indiquant qu'un projet dont j'avais la responsabilité devait en réalité être traité comme un projet d'exploration..

Je pense que les projets d'exploration ne doivent pas être traités comme des courses de 100 mètres, mais plutôt comme des spikes — prototypes.

J'insiste sur l'utilisation du terme Spike pour bien communiquer :

  • Aux décideurs — stakeholder — que l'implémentation de ce projet n'est pas destinée à être conservée sur le long terme. Si l'exploration est concluante, le projet sera recommencé à zéro et attribué à une équipe dédiée.
  • Aux développeurs qu'ils peuvent échouer, que le code peut contenir des bugs et être développé avec une grande dette technique.
  • Aux utilisateurs qu'il est fort probable que l'application contienne des bugs ou que l'User experience ne soit pas optimale.

Ces messages sont souvent difficiles à faire passer, et c'est sans doute pour se protéger que les développeurs choisissent souvent de traiter le projet comme un projet pérenne de long terme plutôt que comme un spike.

De plus, je constate que les décideurs pensent souvent que leur idée est valide et ne jugent pas utile de réaliser des prototypes. Ce n'est souvent qu'après 1 ou 2 ans de vie de la startup que les décideurs considèrent rétrospectivement que les premières versions étaient des prototypes. Problème : ces premières versions n'ont pas été développées comme des prototypes.

Journal du samedi 06 avril 2024 à 20:00 #software-engineering

Article publié sur https://sklein.xyz/fr/posts/2024-04-06_spike-and-learn-day/


Concept que mon équipe et moi avions nommé "Spike and Learn day"

Quand j’étais CTO chez Spacefill, en mai 2021, j’ai mis en place avec mes collègues un rituel que nous avons nommé “Spike and Learn day”.

Un vendredi sur deux — soit 10 % du temps de travail — chaque développeur pouvait librement décider de consacrer sa journée à l’apprentissage d’une nouvelle chose, tester une idée, travailler sur de la dette technique, ou implémenter en autonomie des choses qu’il pensait utiles pour la société.

Pendant cette journée, le développeur n’avait pas à suivre le sprint, ni la roadmap, c’était un espace de liberté.
Les sujets pouvaient être aussi des initiatives d’amélioration produits.

Limites : les sujets devaient être en rapport avec des stacks technologiques utilisés ou potentiellement utilisable par la société (exemple, l’étude d’un moteur de jeu vidéo n’était pas autorisé, car il y avait peu de chance que ça soit utile au business de la société).

Précision importante : l’intégration du résultat de ces journées « Spike and Learn » pouvait être refusé ou non priorisé par l’équipe produit ou non accepté lors de la phase de review par les autres développeurs. Cela faisait partie du jeu de l’expérimentation.

Si un “Spike and Learn day” tombait un jour férié ou pendant les congés d’un développeur, la journée était considérée comme perdue.

Cette idée était largement inspirée de l’initiative de Google nommée “20% Project”.

Pourquoi le mot “spike” ? J’ai puisé le concept de Spike dans le Extreme Programming — qui m’avait été souflé par Ronan —, pour en avoir une définition, je vous conseille l’article What is Spike in Scrum? (archive).

Initialement, j’avais prévu mettre à disposition des projets bootcamps dans lesquels les développeurs auraient pu puiser pour la partie “learn” de leurs journées.
J’envisageais, par exemple, des sujets DevOps, exploration de Docker, déployer un serveur de A à Z via Vagrant, ou alors de recontruire les bases de la stack web employé par la société depuis zéro…
Mais malheureusement — et Claire me l’a souvent rappelé 😉 — en 2 ans, je n’ai produit aucun bootcamp 😭 !

Ajustement au cours du temps

Avec l’expérience, nous avons décidé — quand c’était possible — de placer cette journée en fin de sprint afin de ne pas “casser” sa dynamique.

Ce qui donnait l’emploi du temps théorique suivant :

  • Travail sur les issues du Sprint Scrum du lundi de la semaine 1 au jeudi matin de la semaine 2
  • Jeudi après-midi de la semaine 2 : Sprint rétrospective et Sprint planning
  • Vendredi de la semaine 2 : “Spike and Learn day”

Quels ont été les effets de cette initiative ?

D’après ce que j’ai pu observer ou ce qui m’a été dit, je pense que cette initiative était plutôt appréciée des développeurs.

J’ai pu noter que la plupart des développeurs avaient leurs préférences :

  • Certains privilégiaient fortement des activités de dette technique
  • D’autres préfèraient terminer une issue en retard du sprint
  • Et d’autres préféraient explorer de nouvelles choses, tester des fonctionnalités

Les développeurs m’ont remonté une frustration concernant le défi que représente la réalisation d’un projet nécessitant plusieurs jours de travail avec seulement deux jours alloués par mois. De plus, le délai de quinze jours entre chaque session rend difficile la reprise du travail sur le sujet.

J’ai été agréablement surpris de voir que ce rituel ait été respecté sans difficulté majeure pendant plusieurs années. Je n’ai pas souvenir de suppression exceptionnelle de cette journée par l’équipe produit ou de management.

Si j’en ai un jour la possibilité, si je suis à nouveau en responsabilité, je pense que c’est une initiative que je proposerai à nouveau de mettre en place.

Journal du samedi 29 janvier 2022 à 15:35 #software-engineering, #monolith, #microservices, #JaiLu

#JaiLu ce thread Hacker News : Why our team cancelled our move to microservices.

There is no reason even a significantly larger org - say 40+ people in 8-10 teams cannot work effectively in a single repository and monolith architecture. Beyond that there are certain growing pains and if you don't effectively manage those then I could see how you end up going with micro-services.

source

Je partage cette opinion 👍️.

Journal du mardi 05 octobre 2021 à 14:00 #OnMaPartagé, #JaiDécouvert, #livre, #software-engineering

Je viens de déjeuner avec un ami qui m'a fait découvrir le livre Team Topologies.

Journal du vendredi 19 avril 2019 à 17:33 #dev-kit, #software-engineering, #vocabulaire, #Git

Cela fait des mois que je me demande comment nommer le repository #Git « chapeau », « umbrella » qui est le starting point d'une boite ou d'un projet.

J'ai trouvé une réponse chez GitLab, {compagny_name}-development-kit : https://gitlab.com/gitlab-org/gitlab-development-kit.

Ce repository est un "development kit".

Journal du mardi 15 janvier 2019 à 15:22 #monorepo, #multirepos, #git, #software-engineering, #JaiLu

Ce mois de janvier est riche en article au sujet des Monorepo !

#JaiLu le contre pied du l'article "Monorepos: Please don’t" : Monorepo: please do! !

As a leader, I’ll pick the monorepo every time: because tools must reinforce the culture I want, and culture comes from the tiny decisions and behaviors of a team every day.

source

👌

Son thread Hacker News : 161 commentaires.

Journal du mardi 08 janvier 2019 à 17:28 #monorepo, #git, #software-engineering, #JaiLu

#JaiLu ce thread Hacker News au sujet des Monorepo : "Monorepos and the Fallacy of Scale | Hacker News".

J'ai trouvé l'article très intéressant ainsi que les commentaires.

Journal du jeudi 03 janvier 2019 à 15:13 #git, #monorepo, #multirepos, #software-engineering, #no-silver-bullet, #JaiLu

#JaiLu ce thread Hacker News au sujet des Monorepo : "Monorepos: Please don’t".

Il contient de très bons commentaires biens argumentés qui expliquent les avantages des Monorepo, j'ai trouvé cela passionnant 🙂.

Journal du mercredi 17 octobre 2018 à 16:06 #software-engineering, #monorepo, #multirepos, #git, #JaiDécouvert

#JaiDécouvert le site "Advantages of monorepos" (https://danluu.com/monorepo/).

Avantages :

  • « Simplified organization » 👌
  • « Simplified dependency management » 👌
  • « atomic changes » 👌
  • « Extensive code sharing and reuse » 👌
  • « Unified versioning, one source of truth » 👌
  • « Code visibility and clear tree structure providing implicit team namespacing » 👌
  • « Large-scale refactoring » 👌
  • « Collaboration across teams » 👌

Journal du mardi 12 décembre 2017 à 10:29 #monorepo, #git, #software-engineering

J'ai été perturbé par le contenu des slides « Monolithic repositories vs. Many repositories » de Fabien Potencier : https://speakerdeck.com/fabpot/a-monorepo-vs-manyrepos (voir 2017-12-03_1217).

J'ai continué à étudier le sujet des Monorepo et j'ai commencé à migrer un side project vers ce pattern. Pour le moment, l'expérience est très agréable. Je pense que je vais continuer dans cette direction.

DevLog #software-engineering

(Internet, computing) A log (or blog, vlog, etc.) that updates the audience on the development progress of something, usually a video game, website or app.

source

Vous êtes sur la première page | [ Page suivante (21) >> ]