Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# ADR-0069 | Consommer JustDummies depuis son propre dépôt

🌍 🇫🇷 Français (ce fichier) · 🇬🇧 [English](0069-consume-justdummies-from-its-own-repository.md)

**Statut :** Proposé
**Proposé :** 2026-07-31
**Décideurs :** Reefact
**Supersède :** [ADR-0011](0011-host-dummies-as-a-standalone-package.fr.md) (son volet colocation), ainsi que
le contournement d'embarquement accepté par [ADR-0026](0026-rebase-testing-arbitrary-values-on-dummies.fr.md)

## Contexte

L'[ADR-0011](0011-host-dummies-as-a-standalone-package.fr.md) décidait que JustDummies est un package
indépendant qui ne doit jamais référencer un projet FirstClassErrors, **et** qu'il vit dans ce dépôt, pour
réutiliser son infrastructure CI, packaging, release, SBOM, SourceLink et gouvernance. Il actait que la règle
de non-référence existe pour qu'« une extraction ultérieure reste mécanique plutôt qu'architecturale », et il
écartait un dépôt séparé immédiat pour des raisons de coût, non de principe.

Cette extraction a eu lieu. Le produit — la bibliothèque, ses 28 analyseurs, son adaptateur xUnit v3, ses deux
suites de tests, sa documentation, ses ADR et son scaffolder `dum` spécifié — a été filtré hors de
l'historique de ce dépôt vers **`Reefact/just-dummies`** au
`fbf523b86acebdd34ba0bbfd437683864be3cb9c`, en préservant auteurs, dates, messages et le renommage de
`Dummies` en `JustDummies`. Rien n'a été supprimé ici.

Ce dépôt dépend encore de JustDummies en quatre points, et l'un d'eux le **livre** :

| Projet | Nature de la dépendance |
| --- | --- |
| `FirstClassErrors.Testing` | `ProjectReference` privé **plus** une cible de pack qui embarque `JustDummies.dll` dans son propre `lib/` |
| `FirstClassErrors.UnitTests` | `ProjectReference`, tests uniquement |
| `FirstClassErrors.RequestBinder.UnitTests` | `ProjectReference`, tests uniquement |
| `FirstClassErrors.Testing.UnitTests` | `ProjectReference`, tests uniquement |

Tous les projets du dépôt chargent en outre les analyseurs JustDummies au build (ADR-0061).

L'[ADR-0026](0026-rebase-testing-arbitrary-values-on-dummies.fr.md) acceptait l'embarquement comme
explicitement temporaire : JustDummies « n'est pas encore sur NuGet (ADR-0011), donc le référencer en privé et
embarquer son assembly dans ce package […] ; basculer vers un `PackageReference` NuGet une fois JustDummies
publié ».

**JustDummies n'a jamais été publié.** Aucun tag `dum-v*` n'a jamais été poussé depuis ce dépôt, et
`Reefact/just-dummies` n'a pas publié non plus — sa politique de *trusted publishing* nuget.org n'existe pas
encore.

## Décision

Ce dépôt devient **consommateur** des packages `JustDummies` et de ses analyseurs publiés depuis
`Reefact/just-dummies`, et cesse d'en être la source.

La bascule est **conditionnée à la première publication** et n'est délibérément pas exécutée par
l'extraction. Tant qu'aucun package `JustDummies` restaurable n'existe sur nuget.org, la source reste ici
telle quelle : remplacer un `ProjectReference` par un `PackageReference` vers une version que personne ne peut
restaurer casserait le build pour chaque contributeur et chaque exécution CI, sans bénéfice.

Lorsque cette version existera, en une seule pull request :

1. ajouter `<PackageVersion Include="JustDummies" Version="X.Y.Z" />` à `Directory.Packages.props` ;
2. remplacer les quatre `ProjectReference` vers `JustDummies` par des `PackageReference` ;
3. remplacer les `ProjectReference` vers les analyseurs — ils sont livrés dans le package de la bibliothèque
sous `analyzers/dotnet/cs`, donc un simple `PackageReference` les délivre et la plomberie
`OutputItemType="Analyzer"` disparaît ;
4. supprimer la cible `IncludeJustDummiesInPackage` et son accroche `TargetsForTfmSpecificBuildOutput` de
`FirstClassErrors.Testing.csproj`, et retirer `PrivateAssets="all"` pour que le package déclare une
dépendance `JustDummies` honnête ;
5. retirer les sept projets `JustDummies.*` de `FirstClassErrors.sln`, le train `dum` de `tools/trains.sh`,
`pack.sh` et `release.yml`, le scope `justdummies` de `tools/commit-lint/lint-commit-message.sh`, les
trois configurations `build/stryker/justdummies*.json`, et les workflows
`.github/workflows/justdummies.yml` et `justdummies-mutation.yml` ;
6. supprimer les répertoires source et `tools/justdummies-check/` en dernier, une fois que plus rien ne les
référence ;
7. exécuter le build et la suite de tests complets.

L'ordre compte : supprimer les répertoires en premier transforme chaque autre étape en séance de débogage de
build cassé.

## Conséquences

### `FirstClassErrors.Testing` acquiert une vraie dépendance

Aujourd'hui le package embarque silencieusement une copie de `JustDummies.dll` sans entrée `<dependency>` :
un consommateur qui référence aussi `JustDummies` directement peut se retrouver avec deux copies à des
versions différentes, sans aucun diagnostic. Après la bascule, le package déclare sa dépendance, NuGet résout
un seul assembly, et la version devient visible et relisible. C'est l'objet du changement, pas un effet de
bord.

### La documentation qui reste change de sujet, pas de propriétaire

Les ADR-0011, ADR-0026 et ADR-0061 ne sont **pas** supprimés, ni l'ADR-0006. Ils actent des décisions que ce
dépôt a réellement prises, et la forme actuelle de `FirstClassErrors.Testing` est illisible sans eux. Les
ADR-0011 et ADR-0022 existent aussi dans `Reefact/just-dummies`, car ils lient les deux produits.

`doc/handwritten/for-users/ArbitraryTestValues.{en,fr}.md` documente le package de test de ce dépôt et
mentionne JustDummies comme son moteur ; il reste, et gagne un lien vers le nouveau dépôt.

### Les références d'issues ne fonctionnent que dans un sens

Les messages de commit de `Reefact/just-dummies` antérieurs au 2026-07-31 citent des numéros d'issues et de
pull requests de **ce** dépôt. Rien là-bas ne peut être renuméroté : ces références se résolvent ici et
doivent continuer de se résoudre. Les issues de ce dépôt ne doivent donc pas être supprimées, seulement
fermées.

### Jusqu'à la publication, les deux dépôts portent la source

Cette duplication est réelle et constitue le prix de ne pas livrer un build cassé. Elle prend fin à la
première release de `JustDummies`. Le risque de divergence entre-temps est faible — ce dépôt doit traiter sa
copie comme gelée et faire atterrir les changements JustDummies dans `Reefact/just-dummies` — mais il n'est
pas nul, et c'est la raison pour laquelle la bascule ne doit pas trop attendre.

## Alternatives considérées

### Faire la bascule maintenant, contre une version non publiée

Rejetée : `dotnet restore` échouerait en NU1102 pour chaque contributeur et chaque exécution CI tant qu'aucun
package n'existe. Un dépôt qui ne construit pas est pire qu'un dépôt qui porte un doublon temporaire.

### Continuer de consommer JustDummies via un sous-module Git, ou par URL Git

Rejetée. Les deux réintroduisent le couplage que l'extraction a supprimé, sous une forme plus difficile à
raisonner que le `ProjectReference` actuel : un sous-module épingle un commit et non une version, et ni l'un
ni l'autre n'est exprimable dans le graphe de dépendances du package publié — `FirstClassErrors.Testing`
devrait donc toujours embarquer l'assembly qu'il ne peut pas déclarer.

### Publier JustDummies depuis ce dépôt une dernière fois, puis basculer

Considérée parce qu'elle débloquerait la bascule immédiatement. Rejetée parce que la première version publiée
d'un package fixe l'endroit d'où il est publié : la politique de *trusted publishing*, l'URL de dépôt dans ses
métadonnées et les commits SourceLink pointeraient tous ici, et la release suivante devrait les contredire.
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# ADR-0069 | Consume JustDummies from its own repository

🌍 🇬🇧 English (this file) · 🇫🇷 [Français](0069-consume-justdummies-from-its-own-repository.fr.md)

**Status:** Proposed
**Proposed:** 2026-07-31
**Decision Makers:** Reefact
**Supersedes:** [ADR-0011](0011-host-dummies-as-a-standalone-package.md) (its colocation half), and the
embedding workaround accepted by [ADR-0026](0026-rebase-testing-arbitrary-values-on-dummies.md)

## Context

[ADR-0011](0011-host-dummies-as-a-standalone-package.md) decided that JustDummies is an independent package
that must never reference a FirstClassErrors project, **and** that it lives in this repository, to reuse this
repository's CI, packaging, release, SBOM, SourceLink and governance infrastructure. It recorded that the
no-reference rule exists so that "a later repository extraction [stays] mechanical rather than architectural",
and it rejected an immediate separate repository on cost grounds rather than on principle.

That extraction has now happened. The product — the library, its 28 analyzers, its xUnit v3 adapter, its two
test suites, its documentation, its ADRs and its specified `dum` scaffolder — was filtered out of this
repository's history into **`Reefact/just-dummies`** at
`fbf523b86acebdd34ba0bbfd437683864be3cb9c`, preserving authors, dates, messages and the rename from `Dummies`
to `JustDummies`. Nothing was deleted here.

This repository still depends on JustDummies in four places, and one of them ships it:

| Project | How it depends |
| --- | --- |
| `FirstClassErrors.Testing` | private `ProjectReference` **plus** a pack target that embeds `JustDummies.dll` inside its own `lib/` |
| `FirstClassErrors.UnitTests` | `ProjectReference`, test-only |
| `FirstClassErrors.RequestBinder.UnitTests` | `ProjectReference`, test-only |
| `FirstClassErrors.Testing.UnitTests` | `ProjectReference`, test-only |

Every project in the repository also loads the JustDummies analyzers at build time (ADR-0061).

[ADR-0026](0026-rebase-testing-arbitrary-values-on-dummies.md) accepted the embedding as explicitly temporary:
JustDummies "is not yet on NuGet (ADR-0011), so reference it privately and embed its assembly in this
package […]; switch to a NuGet PackageReference once JustDummies is published."

**JustDummies has never been published.** No `dum-v*` tag was ever pushed from this repository, and
`Reefact/just-dummies` has not released either — its nuget.org trusted-publishing policy does not exist yet.

## Decision

This repository becomes a **consumer** of the `JustDummies` and `JustDummies.Analyzers` packages published
from `Reefact/just-dummies`, and stops being their source.

The cutover is **gated on the first publication** and is deliberately not performed by the extraction. Until a
restorable `JustDummies` package exists on nuget.org, the source stays here exactly as it is: replacing a
`ProjectReference` with a `PackageReference` to a version nobody can restore would break the build for every
contributor and every CI run, to no benefit.

When that version exists, in one pull request:

1. add `<PackageVersion Include="JustDummies" Version="X.Y.Z" />` to `Directory.Packages.props`;
2. replace the four `ProjectReference`s on `JustDummies` with `PackageReference`s;
3. replace the analyzer `ProjectReference`s — the analyzers ship inside the library package under
`analyzers/dotnet/cs`, so a plain `PackageReference` delivers them and the `OutputItemType="Analyzer"`
plumbing goes away;
4. delete the `IncludeJustDummiesInPackage` target and its `TargetsForTfmSpecificBuildOutput` hook from
`FirstClassErrors.Testing.csproj`, and drop `PrivateAssets="all"` so the package declares an honest
`JustDummies` dependency;
5. remove the seven `JustDummies.*` projects from `FirstClassErrors.sln`, the `dum` train from
`tools/trains.sh`, `pack.sh` and `release.yml`, the `justdummies` scope from
`tools/commit-lint/lint-commit-message.sh`, the three `build/stryker/justdummies*.json` configurations,
and `.github/workflows/justdummies.yml` and `justdummies-mutation.yml`;
6. delete the source directories and `tools/justdummies-check/` last, once nothing references them;
7. run the full build and test suite.

The order matters: deleting the directories first turns every other step into a broken-build debugging
session.

## Consequences

### `FirstClassErrors.Testing` gains a real dependency

Today the package silently carries a copy of `JustDummies.dll` with no `<dependency>` entry, so a consumer
who also references `JustDummies` directly can end up with two copies at different versions and no diagnostic.
After the cutover the package declares its dependency, NuGet resolves one assembly, and the version becomes
visible and reviewable. This is the point of the change, not a side effect.

### The documentation that stays here changes subject, not owner

ADR-0011, ADR-0026 and ADR-0061 are **not** deleted, and neither is ADR-0006. They record decisions this
repository genuinely made, and the reasoning behind `FirstClassErrors.Testing`'s current shape is unreadable
without them. ADR-0011 and ADR-0022 also exist in `Reefact/just-dummies`, because they bind both products.

`doc/handwritten/for-users/ArbitraryTestValues.{en,fr}.md` documents this repository's testing package and
mentions JustDummies as its engine; it stays, and gains a link to the new repository.

### Issue references keep working in one direction only

Commit messages in `Reefact/just-dummies` older than 2026-07-31 cite issue and pull-request numbers of **this**
repository. Nothing there can be renumbered, so those references resolve here and must keep resolving:
this repository's issues must not be deleted, only closed.

### Until publication, both repositories carry the source

That duplication is real and is the cost of not shipping a broken build. It ends with the first
`JustDummies` release. Divergence risk in the interim is low — this repository should treat its copy as
frozen and land JustDummies changes in `Reefact/just-dummies` — but it is not zero, and it is the reason the
cutover should not wait long.

## Alternatives Considered

### Do the cutover now, against an unpublished version

Rejected: `dotnet restore` would fail with NU1102 for every contributor and every CI run until a package
exists. A repository that cannot build is worse than one that carries a temporary duplicate.

### Keep consuming JustDummies as a Git submodule, or by Git URL

Rejected. Both reintroduce the coupling the extraction removed, in a form that is harder to reason about than
the current `ProjectReference`: a submodule pins a commit rather than a version, and neither is expressible in
the published package's dependency graph — so `FirstClassErrors.Testing` would still have to embed the
assembly it cannot declare.

### Publish JustDummies from this repository one last time, then cut over

Considered because it would unblock the cutover immediately. Rejected because the first published version of a
package fixes where it is released from: the trusted-publishing policy, the repository URL in its metadata and
the SourceLink commits would all point here, and the very next release would have to contradict them.
2 changes: 2 additions & 0 deletions doc/handwritten/for-maintainers/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,5 @@ Optional supporting material:
| [ADR-0065](0065-carry-a-declared-constraint-as-a-value-object.md) | Carry a declared constraint as a value object, not as its rendered text | Accepted |
| [ADR-0066](0066-declare-a-value-object-and-enforce-its-identity.md) | Declare a value object with an attribute, and enforce its identity by convention | Accepted |
| [ADR-0067](0067-treat-the-cli-s-exit-codes-as-a-closed-published-contract.md) | Treat the CLI's exit codes as a closed, published contract | Accepted |
| [ADR-0068](https://github.com/Reefact/just-dummies/blob/main/doc/handwritten/for-maintainers/adr/0068-extract-justdummies-into-its-own-repository.md) | Extract JustDummies into its own repository *(recorded in `Reefact/just-dummies`)* | Proposed |
| [ADR-0069](0069-consume-justdummies-from-its-own-repository.md) | Consume JustDummies from its own repository | Proposed |
Loading