How to Maintain Package Versions
Sometimes, typically when proposing a change (e.g., modifying the Backend
↔ Frontend protocol, or adding new methods into the
python3-copr-common package that other packages depend on), we need to
specify version constraints between our components to avoid
misinstallations. Below are a few documented scenarios.
Package Update Time a.k.a. TL;DR
Most dependency checks are enforced by Requires in package versions. When
updating the system, you generally do not need to worry about these, as the
package manager prevents invalid configurations. However, some checks occur at
runtime.
The runtime protection hierarchy follows a frontend -> backend <- rpmbuild
pattern. In this model, the backend drives critical runtime checks; if the
frontend or the builder is too old for a specific backend version, the backend
will “hang” and wait for them to be updated.
In practice, this means that whenever you update the system with a backward- incompatible change in the inter-component API, you must follow a “shutdown -> upgrade -> restart” workflow targeting the backend component first.
Changing the Frontend ↔ Backend Protocol
There are two relevant values: MIN_FE_BE_API (backend side) and
Copr-FE-BE-API-Version (frontend side).
Whenever the backend detects that the Frontend counterpart is older than expected, it delays processing. Please bump the value anytime you think it’s warranted, there’s no risk in doing so, but forgetting to update it is risky (backend would process incompatible requests).
To ensure smooth upgrades, always update the copr-backend machine
first, so it is ready (after re-deployment) and waiting for the updated &&
fully-compatible Frontend.
Changes in Backend ↔ Builder Protocol
Whenever the Backend attempts to hand over a task to a Builder machine, it
verifies the “remote” copr-builder RPM (sub)package version. If the version
is lower than MIN_BUILDER_VERSION (as defined in
backend/copr_backend/background_worker_build.py), the Backend marks the
builder machine as unusable, and allocates a new one instead.
Changes in Frontend ↔ Builder Protocol
Typically, this involves updating certain /backend/ routes on the Frontend.
This process must be performed in two steps: the runtime dependencies for both
Frontend ↔ Backend and Backend ↔ Builder (see above) must be bumped
simultaneously.
Changes in python3-copr-common
This package is heavily used by all other components, except for
python3-copr (which is intentionally self-contained, see below). Bumping
its version is not a problem, since other components depend on it with
a >= constraint.
While we normally ship MAJOR.MINOR versions of our components, during
development we may need to add a third .PATCH version component (this
can be done arbitrarily in any pull-request — later, when making a
release, we remove the .PATCH suffix and bump to either MAJOR+1 or
MAJOR.MINOR+1).
Anytime you bump the .PATCH version, please update the corresponding
%copr_common_version macro in dependent components that you modify. Also
remember to synchronize the package version in both the
python-copr-common.spec and setup.py. See this discussion for more
information.
Handling suffixes like dev1 or 1post is tricky, because RPM and
Python (our main development language stack) compare such versions
differently.
Changes in python3-copr
This is our Python API, so we should be careful when making breaking changes.
The package lives in <gitroot>/python/python-copr.spec.
In general, when bumping versions, follow the same process described above for
python3-copr-common (bump the .PATCH version in both setup.py and the
python-copr.spec).
The only difference is that copr-cli uses a different macro, which you
should bump instead: %min_python_copr_version.