summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <grothoff@gnunet.org>2023-12-07 16:34:07 +0900
committerChristian Grothoff <grothoff@gnunet.org>2023-12-07 16:35:55 +0900
commit4259dba37a59af1ce4ebafa842cee8a300736c40 (patch)
tree44d54d05aa748fd0118f563e32e674b0b6a2ad17
parent24933224bc54cae635d1a6096b95c7a2b5fee196 (diff)
downloaddocs-4259dba37a59af1ce4ebafa842cee8a300736c40.tar.gz
docs-4259dba37a59af1ce4ebafa842cee8a300736c40.tar.bz2
docs-4259dba37a59af1ce4ebafa842cee8a300736c40.zip
document versioning
-rw-r--r--taler-developer-manual.rst51
1 files changed, 51 insertions, 0 deletions
diff --git a/taler-developer-manual.rst b/taler-developer-manual.rst
index ecee786f..12be5335 100644
--- a/taler-developer-manual.rst
+++ b/taler-developer-manual.rst
@@ -118,6 +118,55 @@ There are other important repositories without code, including:
Fundamentals
============
+Versioning
+----------
+
+A central rule is to never break anything for any dependency. To accomplish
+this, we use versioning, of the APIs, database schema and the protocol. The
+database versioning approach is described in the :ref:`Database schema
+versioning <DatabaseVersioning>` section. Here, we will focus on API and
+protocol versioning.
+
+The key issue we need to solve with protocols and APIs (and that does not
+apply to database versioning) is being able to introduce and remove features
+without requiring a flag day where all components must update at the same
+time. For this, we use GNU libtool style versioning with MAJOR:REVISION:AGE
+and *not* semantic versioning (SEMVER). With GNU libtool style versioning,
+first the REVISION should be increased on every change to the respective code.
+Then, each time a feature is introduced or deprecated, the MAJOR and AGE
+numbers are increased. Whenever an API is actually removed the AGE number is
+reduced to match the distance since the removed API was deprecated. Thus, if
+some client implements version X of the protocol (including not using any APIs
+that have been deprecated), it is compatible for any implementation where
+MAJOR is larger or equal to X, and MAJOR minus AGE is smaller or equal to X.
+REVISION is not used for expected compatibility issues and merely serves to
+uniquely identify each version (in combination with MAJOR).
+
+To evolve any implementation, it is thus critical to first of all never
+just break an existing API or endpoint. The only acceptable modifications
+are to return additional information (being aware of binary compatibility!)
+or to accept additional optional arguments (again, in a way that does not
+break existing users). Thus, the most common way to introduce changes will
+be the addition of new endpoints. Breaking existing endpoints is only ever
+at best acceptable while in the process of introducing it and if you are
+absolutely sure that there are zero users in other components.
+
+When removing endpoints (or fields being returned), you must first deprecate
+the existing API (incrementing MAJOR and AGE) and then wait for all clients,
+including all clients in operation (e.g. Android and iOS Apps, e-commerce
+integrations, etc.) to upgrade to a protocol implementation above the
+deprecated MAJOR revision. Only then you should remove the endpoint and reduce
+AGE.
+
+To document these changes, please try to use ``@since`` annotations in the API
+specifications to explain the MAJOR revision when a feature became available,
+but most importantly use ``@deprecated X`` annotations to indicate that an API
+was deprecated and will be removed once MAJOR minus AGE is above X. When using
+an API, use the ``/config`` endpoints to check for compatibility and show a
+warning if the version(s) you support and the version(s) offered by the server
+are incompatible.
+
+
Testing Tools
-------------
@@ -583,6 +632,8 @@ prepared.
$ buildbot-worker start worker/
+.. _DatabaseVersioning:
+
Database schema versioning
--------------------------