Problem
`BranchChannelConfig` (`src/config/types.rs:48`) maps a branch to a prerelease channel, but there is no way to express maintenance branches: a long-lived `1.x` branch that bumps within the 1.x line and never touches the `latest` tag.
Without this, security fixes on a deprecated major can't be released from the dedicated maintenance branch without manual tag manipulation.
Comparison
```js
// semantic-release config
branches: [
'main',
'+([0-9])?(.{x,x}).x', // 1.x, 2.x, 1.5.x → maintenance
{ name: 'beta', prerelease: true },
{ name: 'alpha', prerelease: 'alpha' },
]
```
semantic-release enforces:
- Maintenance branches can only emit versions `<= main`'s major.minor
- They write to the corresponding npm dist-tag (`1.x` → `release-1.x`, not `latest`)
Proposal
Extend `BranchChannelConfig`:
```toml
[[workspace.branches]]
name = "1.x"
range = "1.x" # or "1.5.x"
dist_tag = "release-1.x" # forge metadata / npm dist-tag
```
In `src/monorepo/run/mod.rs`:
- When releasing from a branch with `range`, validate computed bumps don't exceed the range (`1.x` rejects a 2.0.0 bump; `feat!` becomes minor instead, or hard error).
- Floating tag handling (`1` / `1.5`) needs to consider the maintenance branch lineage — only the maintenance branch's tip moves `1.5`, never main.
Out of scope
- Auto-creating maintenance branches when a major lands on main. File separately if useful.
Test plan
- Fixture: `1.x` branch + `feat!` commit → asserts FerrFlow emits 1.X+1.0 (or errors out, depending on `range_overflow` policy), never 2.0.0
- Fixture: maintenance release pushes a non-`latest` floating tag
Problem
`BranchChannelConfig` (`src/config/types.rs:48`) maps a branch to a prerelease channel, but there is no way to express maintenance branches: a long-lived `1.x` branch that bumps within the 1.x line and never touches the `latest` tag.
Without this, security fixes on a deprecated major can't be released from the dedicated maintenance branch without manual tag manipulation.
Comparison
```js
// semantic-release config
branches: [
'main',
'+([0-9])?(.{x,x}).x', // 1.x, 2.x, 1.5.x → maintenance
{ name: 'beta', prerelease: true },
{ name: 'alpha', prerelease: 'alpha' },
]
```
semantic-release enforces:
Proposal
Extend `BranchChannelConfig`:
```toml
[[workspace.branches]]
name = "1.x"
range = "1.x" # or "1.5.x"
dist_tag = "release-1.x" # forge metadata / npm dist-tag
```
In `src/monorepo/run/mod.rs`:
Out of scope
Test plan