yavsc/CONTRIBUTING.md
Paul Schneider 87e824fa63 contributing+roadmap: document smoke tests per BC, tick off Jalon 0
- CONTRIBUTING.md 'Tests' section now describes the smoke
  pattern: per-BC, in-memory TestServer, EF InMemory, asserts
  2xx/3xx or 401/403 on a representative GET.
- ROADMAP.md 'Tests d'integration smoke par BC' flips from
  open to ticked off (Yavsc.Org coverage), with a note that
  Yavsc.Api and Yavsc.Blogs smoke coverage is left for a
  future session (separate WebApplicationFactory<Program>
  targets).

With this commit, Jalon 0 'Fondations techniques' is fully
ticked off. The release criterion
  'dotnet build + dotnet test + docker compose up verts sur
   une machine vierge (apres procedure d'install)'
is met end-to-end for Yavsc.Org; the docker-compose criterion
documents the cert/HTTPS requirement for web explicitly.
2026-06-27 21:04:26 +01:00

9.3 KiB

Contribuer à Yavsc

Pré-requis

  • .NET 10 SDK
  • PostgreSQL (≥ 14) — local ou via docker compose up (cf. docker-compose.yaml)
  • Node.js (uniquement pour la toolchain Avalonia Browser/WASM)
  • Pour Android : Android SDK + workload dotnet workload install android

Premier build

git clone https://github.com/pazof/yavsc.git
cd yavsc
dotnet restore
dotnet build

Pour exécuter Yavsc.Org en local :

cp src/Yavsc.Org/appsettings-org.json src/Yavsc.Org/appsettings-org.Development.json
$EDITOR src/Yavsc.Org/appsettings-org.Development.json   # renseigner Site.Authority, ConnectionStrings.YavscConnection, …
ASPNETCORE_ENVIRONMENT=Development dotnet run --project src/Yavsc.Org

Cf. doc/Architecture.md section "Paramétrage" pour le détail des variables à renseigner.

Tests

dotnet test

Les tests sont répartis en :

  • src/Yavsc.Org.Tests/ — tests d'intégration du front web (TestWebApplicationFactory<Program> + EF InMemory). Comprend les smoke tests par BC sous Smoke/ : AccountSmokeTests (GET /signin), BlogSmokeTests (GET /BlogSpot/Index). Chaque test couvre une bounded context DDD au sens de doc/ddd-exploration-2026-06-14.md : il démarre le host en mémoire via WebApplicationFactory<Program> et vérifie qu'une route publique de la BC répond en 2xx/3xx (ou 401/403 si elle exige une authentification). Cf. ROADMAP.md item « Tests d'intégration smoke par BC ».
  • src/PostIt.Tests/ — tests unitaires du client desktop PostIt.

Conventions de code

Le repo applique .editorconfig (UTF-8, LF, indent_size = 4 en C#, 2 en Razor / XML / .axaml). Pas de formatter dédié — les EDI (Visual Studio, Rider) appliquent automatiquement les règles Roslyn

  • EditorConfig.

Quelques règles non capturées par .editorconfig :

  • using triés par groupe (System, puis packages, puis local). Pas de séparation visuelle entre groupes (cf. dotnet_separate_import_directive_groups = false).
  • Préférer les types BCL (int, string) aux types framework (Int32, String).
  • Préférer les expressions de pattern matching aux casts explicites.

Branches & commits

  • Trunk-based sur main. Pas de branche longue durée pour le moment ; on lande directement sur main via PR (quand le projet attire de l'attention) ou push direct (mode solo).

  • Un commit = un changement logique. Regrouper les fichiers qui touchent au même flux dans un seul commit (login + tests + doc = un commit), mais séparer les commits de reformulation d'historique (« refactor », « typo ») des commits de feature dans la mesure du possible.

  • Messages de commit en anglais, format :

    <scope>: <imperative summary>
    
    <body — what changed and why, not how>
    

    Le scope est le nom du sous-projet (postit, doc, readme, yavsc.org, yavsc.api, …). Pour les commits qui touchent plusieurs sous-projets, préférer un scope générique (readme:, doc:).

Découpage des projets

Cf. doc/architecture/decoupage-organisation.md.

qui couvre à la fois le build, la publication et les images runtime, plus un second Dockerfile minimal (Dockerfile.backend) utilisé uniquement par le workflow de publication de l'image de production.

Dockerfile Stages Construit par
Dockerfile build-env (default), publish-org/api/blogs, web-runtime, api-runtime, blogs-runtime docker compose build + .github/workflows/docker-publish-android.yml
Dockerfile.backend Idem limité à build-env + publish-org (suffisant pour publier l'image pazof/yavsc) .github/workflows/docker-publish-backend.yml

L'image de base est construite depuis le dépôt sibling dotnet-android-build-image (Debian 12 + .NET 10 SDK + Android SDK 36 + workload .NET Android). Elle est poussée sur Docker Hub sous le tag pazof/yavsc-build-env:debian12-dotnet10-android36-v1. Le tag est déclaré comme ARG BUILD_ENV_TAG au début du Dockerfile (et de Dockerfile.backend) — il faut le bumper en lockstep dans les deux fichiers et dans docker-compose.yaml (chaque bloc build.args.BUILD_ENV_TAG) quand l'image de base est reconstruite.

docker compose up

sudo docker compose up --build

Démarre 4 services : db (PostgreSQL 16), web (Yavsc.Org), api (Yavsc.Api), blogs (Yavsc.Blogs). Chaque service runtime pointe sur le stage correspondant du Dockerfile multi-stage via build.target. Les services runtime attendent le healthcheck pg_isready de db avant de démarrer.

Sur une machine vierge, db, api et blogs démarrent. Le service web (Yavsc.Org) échoue avec :

Production IdentityServer requires a signing certificate. Configure Kestrel:Endpoints:Https:Certificate:{Path,KeyPath}.

C'est attendu : IdentityServer8 en mode Production exige un cert HTTPS pour signer les tokens (cf. src/Yavsc.Org/Extensions/HostingExtensions.cs:374). Le critère de sortie Jalon 0 « docker compose up vert sur machine vierge » n'est donc pas « tout démarre sans rien » — c'est « tout démarre après la procédure d'installation qui monte un cert HTTPS valide, cf. HTTPS en production ci-dessous ». Le montage de /etc/letsencrypt (volume commenté par défaut dans docker-compose.yaml) est l'étape qui distingue une machine configurée d'une machine vierge.

appsettings-org.json

Le fichier de configuration de prod (src/Yavsc.Org/appsettings-org.json) n'est pas commité. Il est injecté dans chaque image runtime via un BuildKit secret mount — le fichier reste sur l'hôte, n'apparaît dans aucun layer :

secrets:
  yavsc_appsettings:
    file: ./src/Yavsc.Org/appsettings-org.json

Compose le passe automatiquement à docker build via le bloc build.secrets de chaque service runtime.

HTTPS en production

En dev local les services runtime sont forcés à HTTP seul par un bloc environment explicite dans docker-compose.yaml :

environment:
  ASPNETCORE_URLS: "http://+:5000"
  ASPNETCORE_HTTPS_PORT: ""

C'est nécessaire parce que appsettings-org.Development.json positionne Site.Authority = https://localhost:5001, ce qui pousse Kestrel à essayer de binder HTTPS même sans certificat disponible — et échoue proprement avec « Unable to configure HTTPS endpoint. No server certificate was specified ».

En production, sur chaque service runtime de docker-compose.yaml :

  1. Remplacer l'environment.ASPNETCORE_URLS par la forme double-bind http://+:5000;https://+:5001 (ou équivalent pour Api / Blogs).

  2. Décommenter le port HTTPS correspondant (5001 pour Org, 5003 pour Api, 5005 pour Blogs).

  3. Décommenter le volume /etc/letsencrypt:/etc/letsencrypt:ro — monter le répertoire Let's Encrypt de l'hôte en lecture seule pour que Kestrel accède aux fichiers .pem.

  4. Dans appsettings-org.json, ajouter un bloc Kestrel:Endpoints pointant vers les chemins du volume monté. Exemple :

    "Kestrel": {
      "Endpoints": {
        "Https": {
          "Url": "https://+:5001",
          "Certificate": {
            "Path": "/etc/letsencrypt/live/yavsc.example/fullchain.pem",
            "KeyPath": "/etc/letsencrypt/live/yavsc.example/privkey.pem"
          }
        }
      }
    }
    
  5. Régénérer l'image runtime (les appsettings sont baked dans l'image via BuildKit secret mount — cf. section appsettings-org.json).

Bumper l'image de build

Quand on bumpe Debian, .NET SDK ou Android SDK, reconstruire l'image de base :

cd ../dotnet-android-build-image
docker build -t pazof/yavsc-build-env:debian12-dotnet10-android36-v2 .
docker push pazof/yavsc-build-env:debian12-dotnet10-android36-v2

Puis bumper en lockstep dans :

  • Dockerfile (ARG BUILD_ENV_TAG en tête de fichier)
  • Dockerfile.backend (idem)
  • docker-compose.yaml (chaque bloc build.args.BUILD_ENV_TAG).

Vérifier un build isolé d'un stage runtime

docker build \
  --secret id=yavsc_appsettings,src=src/Yavsc.Org/appsettings-org.json \
  --target web-runtime \
  -t yavsc-org:dev .
docker run --rm -p 5000:5000 yavsc-org:dev

et une roadmap à jour dans ROADMAP.md. Toute modification de modèle doit être précédée d'une note DDD ; les BC (Conciliation, etc.) listés dans ces docs sont les cibles de conception.

Sessions DDD

Le repo tient un journal de design DDD sous doc/ddd-exploration-*.md et une roadmap à jour dans ROADMAP.md. Toute modification de modèle doit être précédée d'une note DDD ; les BC (Conciliation, etc.) listés dans ces docs sont les cibles de conception.

Sécurité

Cf. la section "🔒 Hygiène transverse (à tous les jalons)" de ROADMAP.md. En particulier : ne jamais committer de secret, utiliser dotnet user-secrets en développement et les variables d'environnement ASPNETCORE_* en production.

Questions

Ouvrir une issue GitHub, ou — pour les questions de design — démarrer une session DDD et la consigner dans doc/.