Advanced

An LTS line for a moving product

Some consumers cannot take the newest release: a mobile client, a stored model, a third-party integration that is reviewed slowly. An LTS line is a second version series that receives only fixes, so those consumers have a floor they can stay on.

What you will see

False today. When it becomes True, consumers on the LTS line get a warning from this value, not from a person.

About 1 min of reading

Try It

Encode the LTS policy as a test

1

Declare the series

printf 'lts: 1.4.x\ncurrent: 2.0.x\nlts_end: 2027-06-30\n' > series.yml

Before you run it, say out loud what it will print. Then open the answer.

What it prints
A file both the build and the warning logic read from.
2

Assert the API surface

python -c "import pkg, inspect; print(sorted(n for n,d in inspect.getmembers(pkg, inspect.isfunction)))" > api.txt

Before you run it, say out loud what it will print. Then open the answer.

What it prints
A sorted list of public names for the current build.
3

Diff against the LTS baseline

diff --quiet api.txt api-lts-baseline.txt && echo 'LTS ok' || echo 'LTS blocked'

Before you run it, say out loud what it will print. Then open the answer.

What it prints
LTS ok only when the public surface is identical. A new function blocks the LTS release.
4

Generate the end-of-life warning

python -c "import datetime; print(datetime.date.today() > datetime.date(2027,6,30))"

Before you run it, say out loud what it will print. Then open the answer.

What it prints
False today. When it becomes True, consumers on the LTS line get a warning from this value, not from a person.
Do not backport a feature to the LTS line because it is convenient. That is the moment the two series stop being one codebase.

Data Flow

One source to two series
1 Tag the source with the series it belongs to
↓
2 Gate the change: fixes only on LTS
↓
3 Build and test each series separately
↓
4 Warn consumers past a series end date
Why this works
When an LTS line is worth the cost

When at least one consumer cannot upgrade on your schedule and would otherwise be stuck on an unsupported version. If every consumer can move, an LTS line is dead weight.

The support window

Typically one LTS line at a time, supported for a fixed period after the next major ships. Two live lines means three versions to test, which is where this discipline usually stops being worth it.

Examples

Two series, one codebase

v2.x is current, v1.4.x is LTS. Both are built from the same source; the LTS branch only accepts changes that are fixes or additive. The branch is a policy, not a fork.

The policy is checkable

A PR is allowed on the LTS line only if it adds no interface. A test that asserts the public API surface is unchanged is what enforces that, not a review comment.

End of life is a date

Each LTS series has a documented end date. Consumers on that line get a warning after it, and the warning is generated from the date, not from a human noticing.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Yanking a release that must not be used
Previous Lesson
Yanking a release that must not be used
Next Lesson
Versioning inside a monorepo
Versioning inside a monorepo →