@ferrflow/doc 7.21.2 → 7.21.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -254,13 +254,15 @@ jobs:
254
254
 
255
255
  ## Concurrency safety
256
256
 
257
- Since v5.2, `ferrflow release` acquires `.git/ferrflow.lock` atomically (`O_CREAT|O_EXCL`) at the start of every mutating run. A second concurrent invocation on the same repo fails fast with a clear error rather than racing on git refs: the classic failure mode is a manually-triggered release firing at the same time as a cron-driven `auto-release`, producing half-pushed tag sets, non-fast-forward rejects, or duplicate draft releases.
257
+ Since v5.2, `ferrflow release` acquires `ferrflow.lock` atomically (`O_CREAT|O_EXCL`) at the start of every mutating run. The lockfile lives in the repository's common git dir, which is `.git/` in an ordinary checkout and the main checkout's `.git/` when you run from a linked worktree, so all the worktrees of one repository share a single lock. That is what you want: they push to the same remote and compete on the same refs, so a per-worktree lock would not prevent anything. A second concurrent invocation on the same repo fails fast with a clear error rather than racing on git refs: the classic failure mode is a manually-triggered release firing at the same time as a cron-driven `auto-release`, producing half-pushed tag sets, non-fast-forward rejects, or duplicate draft releases.
258
258
 
259
259
  You don't need to wire anything up. The lock is automatic on every `release` invocation. Read-only commands (`check`, `status`, `version`, `tag`) skip it.
260
260
 
261
- If a previous run crashed without releasing the lock, the next invocation takes it over automatically after 30 minutes (the host + PID stamped inside the lockfile lets FerrFlow detect stale locks). To take it over sooner, delete `.git/ferrflow.lock` manually.
261
+ If a previous run crashed without releasing the lock, the next invocation reads the host and PID stamped inside the lockfile and takes it over as soon as it can see that the owner is gone. On the machine that wrote the lock that is immediate, with no waiting: a crashed CI job does not leave the next one blocked. By the same token a release that is still running keeps its lock however long it takes, so a large monorepo publishing for hours is never interrupted by a timeout.
262
262
 
263
- <aside class="ferr-aside ferr-aside--note"><div class="ferr-aside__body"><p>The lock is per-repo, scoped to <code>.git/</code>. It does not protect across separate clones of the same repo: if you run releases concurrently from two different runners against two different checkouts of the same remote, the lock won&#39;t see the other side. Use a single release runner, or serialize at the CI level (<code>concurrency:</code> in GitHub Actions, <code>interruptible: false</code> in GitLab).</p>
263
+ The 6 hour staleness timeout is only the fallback for a lock this machine cannot ask about, meaning one written by a different host on a shared filesystem, or a lockfile too damaged to read. To take a lock over sooner in that case, run `ferrflow release --force-unlock`, or delete `ferrflow.lock` from the git dir manually.
264
+
265
+ <aside class="ferr-aside ferr-aside--note"><div class="ferr-aside__body"><p>The lock is per-repo, scoped to the common git dir. It covers every linked worktree, but it does not protect across separate clones of the same repo: if you run releases concurrently from two different runners against two different checkouts of the same remote, the lock won&#39;t see the other side. Use a single release runner, or serialize at the CI level (<code>concurrency:</code> in GitHub Actions, <code>interruptible: false</code> in GitLab).</p>
264
266
  </div></aside>
265
267
 
266
268
  ## Crash-resume
@@ -121,6 +121,26 @@ More than one config file was found in the project root (e.g. both `ferrflow.jso
121
121
 
122
122
  Running `ferrflow init` when a config file already exists.
123
123
 
124
+ ### E1024: Versioned file does not exist
125
+
126
+ <span id="e1024"></span>
127
+
128
+ A package that this run would release lists a `versionedFiles` entry whose file is not on disk. The run stops at plan time rather than at write time, where the same problem surfaces as a bare read error.
129
+
130
+ The usual cause is a path written relative to the package instead of the repository root. `package.path` is not a prefix that FerrFlow adds for you:
131
+
132
+ ```toml
133
+ [[package]]
134
+ name = "api"
135
+ path = "packages/api"
136
+
137
+ [[package.versioned_files]]
138
+ path = "Cargo.toml" # wrong, looked up at the repository root
139
+ # path = "packages/api/Cargo.toml" # right
140
+ ```
141
+
142
+ The error names the path it probably meant. `ferrflow validate` reports the same problem for every configured package, including ones this run would not touch.
143
+
124
144
  ## Validation Errors
125
145
 
126
146
  ### E1100: Invalid repo spec
@@ -205,13 +205,15 @@ jobs:
205
205
 
206
206
  ## Securite de concurrence
207
207
 
208
- Depuis la v5.2, `ferrflow release` acquiert `.git/ferrflow.lock` de maniere atomique (`O_CREAT|O_EXCL`) au debut de chaque execution mutante. Une seconde invocation concurrente sur le meme depot echoue immediatement avec une erreur claire au lieu de courir contre les refs git. Le scenario classique est une release declenchee manuellement qui demarre en meme temps qu'un `auto-release` planifie en cron, ce qui produit des jeux de tags poussés à moitié, des refus non fast-forward ou des draft releases dupliquees.
208
+ Depuis la v5.2, `ferrflow release` acquiert `ferrflow.lock` de maniere atomique (`O_CREAT|O_EXCL`) au debut de chaque execution mutante. Le lockfile se trouve dans le git dir commun du depot, c'est-a-dire `.git/` dans un checkout ordinaire et le `.git/` du checkout principal quand vous lancez depuis un worktree lie, si bien que tous les worktrees d'un depot partagent un seul verrou. C'est le comportement voulu : ils poussent vers le meme remote et se disputent les memes refs, donc un verrou par worktree n'empecherait rien. Une seconde invocation concurrente sur le meme depot echoue immediatement avec une erreur claire au lieu de courir contre les refs git. Le scenario classique est une release declenchee manuellement qui demarre en meme temps qu'un `auto-release` planifie en cron, ce qui produit des jeux de tags poussés à moitié, des refus non fast-forward ou des draft releases dupliquees.
209
209
 
210
210
  Rien à brancher. Le verrou est automatique sur chaque invocation `release`. Les commandes en lecture seule (`check`, `status`, `version`, `tag`) ne le prennent pas.
211
211
 
212
- Si une execution précédente a planté sans relacher le verrou, l'invocation suivante le reprend automatiquement apres 30 minutes (l'hote + le PID inscrits dans le lockfile permettent à FerrFlow de detecter les verrous orphelins). Pour le reprendre plus tot, supprimez `.git/ferrflow.lock` à la main.
212
+ Si une execution precedente a plante sans relacher le verrou, l'invocation suivante lit l'hote et le PID inscrits dans le lockfile et le reprend des qu'elle constate que le proprietaire a disparu. Sur la machine qui a ecrit le verrou, c'est immediat, sans attente : un job CI qui a plante ne bloque pas le suivant. Symetriquement, une release toujours en cours garde son verrou aussi longtemps qu'il faut, donc un gros monorepo qui publie pendant des heures n'est jamais interrompu par un delai d'expiration.
213
213
 
214
- <aside class="ferr-aside ferr-aside--note"><div class="ferr-aside__body"><p>Le verrou est par-depot, scope a <code>.git/</code>. Il ne protege pas entre des clones separes du meme depot : si vous lancez des releases simultanees depuis deux runners differents contre deux checkouts du meme remote, le verrou ne voit pas l&#39;autre cote. Utilisez un seul runner de release, ou serialisez au niveau CI (<code>concurrency:</code> dans GitHub Actions, <code>interruptible: false</code> dans GitLab).</p>
214
+ Le delai de peremption de 6 heures ne sert que de repli pour un verrou sur lequel cette machine ne peut rien savoir, c'est-a-dire ecrit par un autre hote sur un systeme de fichiers partage, ou dans un lockfile trop abime pour etre lu. Pour reprendre un tel verrou plus tot, lancez `ferrflow release --force-unlock`, ou supprimez `ferrflow.lock` du git dir a la main.
215
+
216
+ <aside class="ferr-aside ferr-aside--note"><div class="ferr-aside__body"><p>Le verrou est par-depot, scope au git dir commun. Il couvre tous les worktrees lies, mais il ne protege pas entre des clones separes du meme depot : si vous lancez des releases simultanees depuis deux runners differents contre deux checkouts du meme remote, le verrou ne voit pas l&#39;autre cote. Utilisez un seul runner de release, ou serialisez au niveau CI (<code>concurrency:</code> dans GitHub Actions, <code>interruptible: false</code> dans GitLab).</p>
215
217
  </div></aside>
216
218
 
217
219
  ## Reprise apres crash
@@ -121,6 +121,26 @@ Plusieurs fichiers de config trouv\u00e9s dans le r\u00e9pertoire.
121
121
 
122
122
  `ferrflow init` lanc\u00e9 alors qu'un fichier de config existe d\u00e9j\u00e0.
123
123
 
124
+ ### E1024 : Fichier versionne introuvable
125
+
126
+ <span id="e1024"></span>
127
+
128
+ Un package que cette execution allait publier declare une entree `versionedFiles` dont le fichier n'est pas sur le disque. L'execution s'arrete au moment du plan plutot qu'au moment de l'ecriture, ou le meme probleme apparait sous la forme d'une simple erreur de lecture.
129
+
130
+ La cause habituelle est un chemin ecrit relativement au package plutot qu'a la racine du depot. `package.path` n'est pas un prefixe que FerrFlow ajoute pour vous :
131
+
132
+ ```toml
133
+ [[package]]
134
+ name = "api"
135
+ path = "packages/api"
136
+
137
+ [[package.versioned_files]]
138
+ path = "Cargo.toml" # faux, cherche a la racine du depot
139
+ # path = "packages/api/Cargo.toml" # correct
140
+ ```
141
+
142
+ L'erreur indique le chemin qu'elle suppose correct. `ferrflow validate` signale le meme probleme pour tous les packages configures, y compris ceux que cette execution n'aurait pas touches.
143
+
124
144
  ## Erreurs de validation
125
145
 
126
146
  ### E1100 : Spec de repo invalide
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ferrflow/doc",
3
- "version": "7.21.2",
3
+ "version": "7.21.4",
4
4
  "description": "Documentation for FerrFlow, the universal semantic versioning CLI. Rendered at ferrflow.com/docs.",
5
5
  "license": "MIT",
6
6
  "repository": {