[openstack-dev] [all] Reproducible builds: please don't overwrite html_last_updated_fmt

Thomas Goirand zigo at debian.org
Thu Mar 17 23:01:13 UTC 2016

Hi there!

tl;dr: html_last_updated_fmt is already set by your buddy doing Debian
packages, please don't overwrite it in doc/conf.py, or the build becomes
not-reproducible, which is very frustrating for everyone working on
reproducible builds in Debian.

Longer version:

If you aren't aware of it, there's a cross-distro effort to make builds
reproducible. You can have info about it here:

If I'm writing about this today, it's because it's the 3rd time I'm
seeing a wrong fix leading to non-reproducibility. Such repetition is
usually the trigger for me to write a mail to this list. I'm also
convinced that this topic is not known enough, and maybe a little bit
tricky, so this is expected to see the problems I've saw.

So, let's take a practical example from today. As always, nothing
personal, the author of the patch shouldn't take it as a personal
attack. It just happens to be the last occurrence of many of the similar
issue, meaning it's a mistake that everyone does.

Earlier, I filled this bug:

about the use of "git log" in the build process, which breaks in Debian.
This has been fixed. However, the fix introduces a regression: now the
build is not reproducible anymore:

Indeed, this patch includes the build time in the conf.py, which makes
it non-reproducible (on each build, it includes a different time of
build in the docs). And that's a shame, because the debian/rules file
already populates html_last_updated_fmt with a value depending on the
debian/changelog last entry. See for example, the debian/rules of that
same python-oslo.config package:

LAST_CHANGE = $(shell dpkg-parsechangelog -S Date)
BUILD_DATE  = $(shell LC_ALL=C date -u "+%B %d, %Y" -d "$(LAST_CHANGE)")
SPHINXOPTS := -D html_last_updated_fmt="$(BUILD_DATE)"

[ ... ]

with later, calling sphinx-build with the option from above:

sphinx-build $(SPHINXOPTS) ....

so, what the conf.py should be doing here, is look if
html_last_updated_fmt is already populated by the package maintainer. If
it is, just use that, and don't attempt to override it.

So, the Python code is probably something like this:

if html_last_updated_fmt is None:

then the build continues to be reproducible (in Debian at least).

Thanks to anyone who took the time to read until here,

Thomas Goirand (zigo)

More information about the OpenStack-dev mailing list