FerrFlow treats a repository as a monorepo when the config defines more than one package. Each package is versioned independently based on its own git history.
Package isolation
FerrFlow uses path prefixes to determine which commits belong to which package. Only commits that touch files under path (or sharedPaths) trigger a release for that package.
JSON
{
"package": [
{
"name": "api",
"path": "packages/api"
},
{
"name": "site",
"path": "packages/site"
}
]
}
TOML
[[package]] name = "api" path = "packages/api"
[[package]] name = "site" path = "packages/site"
JSON5
{
package: [
{
name: "api",
path: "packages/api",
},
{
name: "site",
path: "packages/site",
},
],
}
YAML
package:
- name: api
path: packages/api
- name: site
path: packages/site
Shared dependencies
If you have code shared between packages (e.g., a packages/shared/ library), declare it as a sharedPaths entry. A change to any shared path triggers a release for every package that lists it:
JSON
{
"package": [
{
"name": "api",
"path": "packages/api",
"sharedPaths": ["packages/shared/"]
},
{
"name": "site",
"path": "packages/site",
"sharedPaths": ["packages/shared/"]
}
]
}
TOML
[[package]] name = "api" path = "packages/api" shared_paths = ["packages/shared/"]
[[package]] name = "site" path = "packages/site" shared_paths = ["packages/shared/"]
JSON5
{
package: [
{
name: "api",
path: "packages/api",
sharedPaths: ["packages/shared/"],
},
{
name: "site",
path: "packages/site",
sharedPaths: ["packages/shared/"],
},
],
}
YAML
package:
- name: api
path: packages/api
sharedPaths:
- packages/shared/
- name: site
path: packages/site
sharedPaths:
- packages/shared/
Package dependencies
Use dependsOn to declare that a package depends on another. When a dependency is released, the dependent package automatically receives a patch bump — even if none of its own files changed. This cascades transitively: if app depends on cli and cli depends on core, bumping core bumps both cli and app.
JSON
{
"package": [
{
"name": "core",
"path": "packages/core"
},
{
"name": "cli",
"path": "packages/cli",
"dependsOn": ["core"]
},
{
"name": "app",
"path": "packages/app",
"dependsOn": ["cli"]
}
]
}
TOML
[[package]] name = "core" path = "packages/core"[[package]] name = "cli" path = "packages/cli" depends_on = ["core"]
[[package]] name = "app" path = "packages/app" depends_on = ["cli"]
JSON5
{
package: [
{
name: "core",
path: "packages/core",
},
{
name: "cli",
path: "packages/cli",
dependsOn: ["core"],
},
{
name: "app",
path: "packages/app",
dependsOn: ["cli"],
},
],
}
YAML
package:
- name: core
path: packages/core
- name: cli
path: packages/cli
dependsOn:
- core
- name: app
path: packages/app
dependsOn:
- cli
Git tag format
By default, monorepo tags use the {name}@v{version} format:
api@v1.2.0
site@v0.4.1
Configure this with the tagTemplate field:
JSON
{
"workspace": {
"tagTemplate": "{name}@v{version}"
}
}
TOML
[workspace]
tag_template = "{name}@v{version}"
JSON5
{
workspace: {
tagTemplate: "{name}@v{version}",
},
}
YAML
workspace:
tagTemplate: "{name}@v{version}"
For a single-package repo, the default is v{version} (no name prefix).
FerrFlow looks for the most recent tag matching the template to determine what commits are new.
Independent cadences
Packages release independently. In a single ferrflow release run:
apimay bump from1.2.0→1.3.0(newfeat:commit)sitemay bump from0.4.0→0.4.1(onlyfix:commits)sharedmay not release at all (onlychore:commits)
Per-package overrides
Each package can override the workspace-level versioning strategy and tagTemplate:
JSON
{
"workspace": {
"versioning": "semver",
"tagTemplate": "{name}@v{version}"
},
"package": [
{
"name": "api",
"path": "packages/api",
"versioning": "calver"
},
{
"name": "site",
"path": "packages/site",
"tagTemplate": "site-v{version}"
}
]
}
TOML
[workspace] versioning = "semver" tag_template = "{name}@v{version}"[[package]] name = "api" path = "packages/api" versioning = "calver"
[[package]] name = "site" path = "packages/site" tag_template = "site-v{version}"
JSON5
{
workspace: {
versioning: "semver",
tagTemplate: "{name}@v{version}",
},
package: [
{
name: "api",
path: "packages/api",
versioning: "calver",
},
{
name: "site",
path: "packages/site",
tagTemplate: "site-v{version}",
},
],
}
YAML
workspace:
versioning: semver
tagTemplate: "{name}@v{version}"
package:
- name: api path: packages/api versioning: calver
name: site path: packages/site tagTemplate: "site-v{version}"