FerrFlow supporte six formats de fichier de configuration, recherch\u00e9s dans cet ordre :
ferrflow.jsonferrflow.json5ferrflow.tomlferrflow.ts(n\u00e9cessitetsx)ferrflow.js(n\u00e9cessitenode).ferrflow(JSON)
Si aucun fichier de configuration n'est trouv\u00e9, FerrFlow d\u00e9tecte automatiquement les fichiers de version courants dans le r\u00e9pertoire actuel.
Formats de configuration
TypeScript
export default {
workspace: {
tagTemplate: "v{version}",
},
package: [
{
name: "my-app",
path: ".",
changelog: "CHANGELOG.md",
versionedFiles: [
{ path: "Cargo.toml", format: "toml" },
],
},
],
};
JSON
{
"$schema": "https://ferrflow.com/schema/ferrflow.json",
"workspace": {
"tagTemplate": "v{version}"
},
"package": [
{
"name": "my-app",
"path": ".",
"changelog": "CHANGELOG.md",
"versionedFiles": [
{ "path": "Cargo.toml", "format": "toml" }
]
}
]
}
TOML
[workspace] tag_template = "v{version}"[[package]] name = "my-app" path = "." changelog = "CHANGELOG.md"
[[package.versioned_files]] path = "Cargo.toml" format = "toml"
JSON5
{
$schema: "https://ferrflow.com/schema/ferrflow.json",
workspace: {
tagTemplate: "v{version}",
},
package: [
{
name: "my-app",
path: ".",
changelog: "CHANGELOG.md",
versionedFiles: [
{ path: "Cargo.toml", format: "toml" },
],
},
],
}
Configurations TypeScript et JavaScript
Les fichiers de config TypeScript (.ts) et JavaScript (.js) utilisent un export ESM par d\u00e9faut. L'export peut \u00eatre un objet ou une fonction asynchrone.
L'avantage principal des configs TS/JS : les hooks sous forme de fonctions. Au lieu de commandes shell, vous pouvez \u00e9crire des hooks natifs avec acc\u00e8s complet au contexte :
export default {
workspace: {
tagTemplate: "v{version}",
hooks: {
postPublish: async (ctx) => {
await fetch("https://hooks.slack.com/services/...", {
method: "POST",
body: JSON.stringify({
text: `Released ${ctx.package}@${ctx.newVersion}`,
}),
});
},
},
},
package: [
{
name: "my-app",
path: ".",
versionedFiles: [{ path: "package.json", format: "json" }],
},
],
};
Objet de contexte des hooks
Les hooks en fonction re\u00e7oivent un objet de contexte avec ces champs :
| Champ | Type | Description |
|---|---|---|
package |
string | Nom du package |
oldVersion |
string | Version avant le bump (vide pour la premi\u00e8re release) |
newVersion |
string | Version apr\u00e8s le bump |
bumpType |
string | major, minor, patch, ou none |
tag |
string | Nom complet du tag git |
dryRun |
boolean | Vrai si --dry-run est actif |
packagePath |
string | Chemin absolu vers la racine du package |
channel |
string ou null | Nom du channel de pr\u00e9-release |
isPrerelease |
boolean | Vrai si c'est une pr\u00e9-release |
Les hooks sous forme de commandes shell et de fonctions peuvent \u00eatre m\u00e9lang\u00e9s dans la m\u00eame config.
workspace
Paramètres globaux qui s'appliquent à tous les packages.
| Champ | Type | Défaut | Description |
|---|---|---|---|
remote |
string | "origin" |
Remote git vers lequel pousser |
branch |
string | auto-détecté | Branche vers laquelle pousser (détectée depuis le HEAD du remote) |
tagTemplate |
string | "v{version}" ou "{name}@v{version}" |
Modèle de nommage des tags. Utilise les placeholders {version} et {name}. Par défaut v{version} pour les repos mono-package et {name}@v{version} pour les monorepos. |
versioning |
string | "semver" |
Stratégie de versionnage par défaut pour tous les packages |
releaseCommitMode |
string | "commit" |
Gestion du commit de release : "commit", "pr" ou "none" |
releaseCommitScope |
string | "grouped" |
Dans un monorepo où plusieurs packages sont bumpés en même temps, créer un seul commit "grouped" ou un commit "per-package". N'a d'effet que quand plusieurs packages bumpent. |
forge |
string | "auto" |
Forçage du forge git : "auto" détecte depuis l'URL du remote, "github" ou "gitlab" forcent un forge (utile pour les instances auto-hébergées sur domaine personnalisé). |
skipCi |
boolean | dépend du mode | Ajouter [skip ci] aux commits de release. Par défaut true en mode "commit", false sinon. |
commitSkipMarkers |
array | ["[skip ci]", "[ci skip]", "[no ci]", "[skip actions]", "[actions skip]"] |
Marqueurs qui font ignorer un commit par FerrFlow lors du calcul de la prochaine version. Comparaison insensible à la casse, sur la ligne de sujet uniquement. |
autoMergeReleases |
boolean | true |
Activer l'auto-merge sur les PR de release (uniquement en mode "pr") |
recoverMissedReleases |
boolean | false |
Comparer les fichiers versionnés au dernier tag plutôt qu'au seul dernier commit, pour rattraper des releases manquées plus tôt dans un monorepo. |
branches |
array | [] |
Associe des branches à des canaux de pré-release (voir Canaux de pré-release). |
anonymous_telemetry |
boolean | true |
Envoyer des statistiques d'usage anonymes (détails). Aucune donnée identifiante n'est collectée. L'ancienne clé telemetry est un alias déprécié — préférez anonymous_telemetry dans les nouvelles configs. |
Modèle de tag
Le champ tagTemplate contrôle le nommage des tags git. Placeholders disponibles :
| Placeholder | Description |
|---|---|
{version} |
Le numéro de version (ex. 1.2.3) |
{name} |
Le nom du package |
JSON
{
"workspace": {
"tagTemplate": "v{version}"
}
}
TOML
[workspace]
tag_template = "v{version}"
JSON5
{
workspace: {
tagTemplate: "v{version}",
},
}
Pour les monorepos, utilisez {name} pour namespacer les tags par package :
JSON
{
"workspace": {
"tagTemplate": "{name}@v{version}"
}
}
TOML
[workspace]
tag_template = "{name}@v{version}"
JSON5
{
workspace: {
tagTemplate: "{name}@v{version}",
},
}
Mode de commit de release
Contrôle la façon dont FerrFlow gère le commit qui met à jour les fichiers de version et les changelogs.
| Mode | Comportement |
|---|---|
"commit" |
Commit directement sur la branche courante et pousse (par défaut) |
"pr" |
Crée une branche release/ et ouvre une pull request |
"none" |
Crée uniquement les tags et les releases, ne commit pas les changements de fichiers |
JSON
{
"workspace": {
"releaseCommitMode": "pr",
"autoMergeReleases": true
}
}
TOML
[workspace]
release_commit_mode = "pr"
auto_merge_releases = true
JSON5
{
workspace: {
releaseCommitMode: "pr",
autoMergeReleases: true,
},
}
Stratégies de versionnage
FerrFlow supporte plusieurs stratégies de versionnage, configurables au niveau du workspace ou du package.
| Stratégie | Format | Progression exemple |
|---|---|---|
semver |
MAJOR.MINOR.PATCH |
1.2.3 → 1.3.0 → 2.0.0 |
calver |
YYYY.MM.PATCH |
2026.03.0 → 2026.03.1 → 2026.04.0 |
calver-short |
YY.MM.PATCH |
26.03.0 → 26.03.1 |
calver-seq |
YYYY.MM.SEQ |
2026.03.1 → 2026.03.2 |
sequential |
N |
1 → 2 → 3 |
zerover |
0.MINOR.PATCH |
0.1.0 → 0.2.0 (n'atteint jamais 1.0) |
JSON
{
"workspace": {
"versioning": "calver"
}
}
TOML
[workspace]
versioning = "calver"
JSON5
{
workspace: {
versioning: "calver",
},
}
Canaux de pré-release
Le tableau branches associe des noms de branches (ou des motifs glob) à des canaux de pré-release. Quand FerrFlow s'exécute sur une branche correspondant à une entrée, il release sur ce canal — par exemple 1.4.0-beta.1 au lieu de 1.4.0. C'est cette même association que l'option --channel de ferrflow check et ferrflow release surcharge ponctuellement.
Chaque entrée comporte :
| Champ | Type | Description |
|---|---|---|
name |
string | Nom de branche ou motif glob (ex. "main", "release/*") |
channel |
string ou false |
Nom de canal ("beta", "rc", …), ou false pour une release stable |
prereleaseIdentifier |
string | Stratégie de l'identifiant ajouté après le nom du canal |
JSON
{
"workspace": {
"branches": [
{ "name": "main", "channel": false },
{ "name": "next", "channel": "beta" }
]
}
}
TOML
[[workspace.branches]] name = "main" channel = false
[[workspace.branches]] name = "next" channel = "beta"
JSON5
{
workspace: {
branches: [
{ name: "main", channel: false },
{ name: "next", channel: "beta" },
],
},
}
package
Définit un package à versionner. Vous pouvez en avoir un ou plusieurs.
| Champ | Requis | Défaut | Description |
|---|---|---|---|
name |
oui | — | Identifiant du package, utilisé dans le préfixe du tag git |
path |
oui | — | Chemin relatif vers le répertoire du package |
changelog |
non | {path}/CHANGELOG.md |
Chemin vers le fichier changelog |
sharedPaths |
non | [] |
Chemins qui déclenchent ce package lorsqu'ils sont modifiés |
versioning |
non | hérité du workspace | Surcharger la stratégie de versionnage pour ce package |
tagTemplate |
non | hérité du workspace | Surcharger le modèle de tag pour ce package |
versionedFiles
Fichiers dans lesquels le numéro de version doit être mis à jour.
JSON
{
"package": [
{
"name": "my-app",
"path": ".",
"versionedFiles": [
{ "path": "Cargo.toml", "format": "toml" },
{ "path": "npm/package.json", "format": "json" }
]
}
]
}
TOML
[[package]] name = "my-app" path = "."[[package.versioned_files]] path = "Cargo.toml" format = "toml"
[[package.versioned_files]] path = "npm/package.json" format = "json"
JSON5
{
package: [
{
name: "my-app",
path: ".",
versionedFiles: [
{ path: "Cargo.toml", format: "toml" },
{ path: "npm/package.json", format: "json" },
],
},
],
}
format |
Fichier | Champ mis à jour |
|---|---|---|
toml |
Cargo.toml, pyproject.toml |
[package].version ou [project].version |
json |
package.json |
version |
xml |
pom.xml |
Premier élément |
gradle |
build.gradle, build.gradle.kts |
version = "..." |
helm |
Chart.yaml |
version et appVersion (si présent) |
gomod |
go.mod |
Pas de mise à jour de fichier — la version vient uniquement des tags git |
txt |
VERSION, VERSION.txt |
Contenu entier du fichier remplacé |
Packages versionnés par tag uniquement
versionedFiles est optionnel. Omettez-le (ou mettez-le à []) pour les packages dont la version est communiquée entièrement via les tags git et les GitHub Releases — modules Go, images Docker, GitHub Actions, dépôts d'infrastructure.
JSON
{
"package": [
{
"name": "my-action",
"path": ".",
"versionedFiles": []
}
]
}
TOML
[[package]]
name = "my-action"
path = "."
versioned_files = []
JSON5
{
package: [
{
name: "my-action",
path: ".",
versionedFiles: [],
},
],
}
FerrFlow lit la version courante depuis le dernier tag git correspondant, calcule le prochain bump à partir des conventional commits, puis crée le tag, la GitHub Release, le changelog et les floating tags éventuels — sans toucher au moindre fichier source. Les hooks s'exécutent normalement, vous pouvez donc lancer docker build, docker push ou gh release upload depuis postPublish en utilisant FERRFLOW_NEW_VERSION.
hooks
Exécutez des commandes shell à des points clés du cycle de release. Les hooks peuvent être définis au niveau du workspace (par défaut pour tous les packages) ou par package (surcharge les hooks du workspace pour ce package).
Cycle de vie
calcul du bump
↓
pre_bump ← valider l'état, vérifier les prérequis
↓
écriture des fichiers de version
↓
post_bump ← modifier des fichiers supplémentaires avec la nouvelle version
↓
génération du changelog
↓
pre_commit ← vérifier les changements stagés, lancer les linters
↓
git commit + tag
↓
pre_publish ← lancer les tests sur le commit taggé, builder les artefacts
↓
git push + création de la release
↓
post_publish ← pousser les images Docker, notifier Slack, publier les packages
Configuration
JSON
{
"workspace": {
"hooks": {
"preBump": "cargo test",
"postBump": "node scripts/sync-deps.js",
"preCommit": "cargo fmt --check",
"prePublish": "cargo build --release",
"postPublish": "make docker-push && ./scripts/notify.sh",
"onFailure": "abort"
}
}
}
TOML
[hooks]
pre_bump = "cargo test"
post_bump = "node scripts/sync-deps.js"
pre_commit = "cargo fmt --check"
pre_publish = "cargo build --release"
post_publish = "make docker-push && ./scripts/notify.sh"
on_failure = "abort"
JSON5
{
workspace: {
hooks: {
preBump: "cargo test",
postBump: "node scripts/sync-deps.js",
preCommit: "cargo fmt --check",
prePublish: "cargo build --release",
postPublish: "make docker-push && ./scripts/notify.sh",
onFailure: "abort",
},
},
}
| Champ | Type | Défaut | Description |
|---|---|---|---|
preBump |
string | — | Exécuté après le calcul du bump, avant l'écriture des fichiers de version |
postBump |
string | — | Exécuté après l'écriture des fichiers de version |
preCommit |
string | — | Exécuté après le changelog, avant le commit git |
prePublish |
string | — | Exécuté après le commit+tag, avant le push |
postPublish |
string | — | Exécuté après le push et la création de la release |
onFailure |
string | "abort" |
"abort" annule la release en cas d'échec, "continue" affiche un avertissement |
Variables d'environnement
Chaque hook reçoit ces variables :
| Variable | Description | Exemple |
|---|---|---|
FERRFLOW_PACKAGE |
Nom du package | api |
FERRFLOW_OLD_VERSION |
Version avant le bump (vide pour la première release) | 1.2.3 |
FERRFLOW_NEW_VERSION |
Version après le bump | 1.3.0 |
FERRFLOW_BUMP_TYPE |
major, minor, patch ou none |
minor |
FERRFLOW_TAG |
Nom complet du tag git | api@v1.3.0 |
FERRFLOW_DRY_RUN |
true si --dry-run est activé |
false |
FERRFLOW_PACKAGE_PATH |
Chemin absolu vers la racine du package | /home/user/repo/packages/api |
Hooks par package
Les hooks au niveau du package remplacent les hooks du workspace pour ce package (ils ne sont pas fusionnés).
JSON
{
"workspace": {
"hooks": {
"preBump": "echo releasing $FERRFLOW_PACKAGE",
"postPublish": "make notify"
}
},
"package": [
{
"name": "api",
"path": "packages/api",
"hooks": {
"preBump": "cargo test"
}
}
]
}
TOML
[hooks] pre_bump = "echo releasing $FERRFLOW_PACKAGE" post_publish = "make notify"[[package]] name = "api" path = "packages/api"
[package.hooks] pre_bump = "cargo test"
JSON5
{
workspace: {
hooks: {
preBump: "echo releasing $FERRFLOW_PACKAGE",
postPublish: "make notify",
},
},
package: [
{
name: "api",
path: "packages/api",
hooks: {
preBump: "cargo test",
},
},
],
}
Dans cet exemple, le package api exécute cargo test pour preBump (surchargeant l'echo du workspace) mais hérite du hook postPublish du workspace.
Comportement
--dry-run: les hooks sont affichés mais non exécutés.--verbose: la sortie stdout/stderr des hooks est diffusée en direct. Sinon, la sortie n'est affichée qu'en cas d'échec.- Les fichiers modifiés par les hooks
postBumpoupreCommitsont automatiquement inclus dans le commit de release.
Exemples complets
Repo unique
JSON
{
"$schema": "https://ferrflow.com/schema/ferrflow.json",
"workspace": {
"tagTemplate": "v{version}"
},
"package": [
{
"name": "ferrflow",
"path": ".",
"changelog": "CHANGELOG.md",
"versionedFiles": [
{ "path": "Cargo.toml", "format": "toml" },
{ "path": "npm/package.json", "format": "json" }
]
}
]
}
TOML
[workspace] tag_template = "v{version}"[[package]] name = "ferrflow" path = "." changelog = "CHANGELOG.md"
[[package.versioned_files]] path = "Cargo.toml" format = "toml"
[[package.versioned_files]] path = "npm/package.json" format = "json"
JSON5
{
$schema: "https://ferrflow.com/schema/ferrflow.json",
workspace: {
tagTemplate: "v{version}",
},
package: [
{
name: "ferrflow",
path: ".",
changelog: "CHANGELOG.md",
versionedFiles: [
{ path: "Cargo.toml", format: "toml" },
{ path: "npm/package.json", format: "json" },
],
},
],
}
Monorepo
JSON
{
"$schema": "https://ferrflow.com/schema/ferrflow.json",
"workspace": {
"tagTemplate": "{name}@v{version}"
},
"package": [
{
"name": "api",
"path": "packages/api",
"changelog": "packages/api/CHANGELOG.md",
"sharedPaths": ["packages/shared/"],
"versionedFiles": [
{ "path": "packages/api/Cargo.toml", "format": "toml" }
]
},
{
"name": "site",
"path": "packages/site",
"changelog": "packages/site/CHANGELOG.md",
"sharedPaths": ["packages/shared/"],
"versionedFiles": [
{ "path": "packages/site/package.json", "format": "json" }
]
}
]
}
TOML
[workspace] tag_template = "{name}@v{version}"[[package]] name = "api" path = "packages/api" changelog = "packages/api/CHANGELOG.md" shared_paths = ["packages/shared/"]
[[package.versioned_files]] path = "packages/api/Cargo.toml" format = "toml"
[[package]] name = "site" path = "packages/site" changelog = "packages/site/CHANGELOG.md" shared_paths = ["packages/shared/"]
[[package.versioned_files]] path = "packages/site/package.json" format = "json"
JSON5
{
$schema: "https://ferrflow.com/schema/ferrflow.json",
workspace: {
tagTemplate: "{name}@v{version}",
},
package: [
{
name: "api",
path: "packages/api",
changelog: "packages/api/CHANGELOG.md",
sharedPaths: ["packages/shared/"],
versionedFiles: [
{ path: "packages/api/Cargo.toml", format: "toml" },
],
},
{
name: "site",
path: "packages/site",
changelog: "packages/site/CHANGELOG.md",
sharedPaths: ["packages/shared/"],
versionedFiles: [
{ path: "packages/site/package.json", format: "json" },
],
},
],
}