[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:
https://wiki.debian.org/ReproducibleBuilds
https://wiki.debian.org/ReproducibleBuilds/About

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:
https://bugs.launchpad.net/bugs/1552251

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:
https://review.openstack.org/#/c/290255/

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,
Cheers,

Thomas Goirand (zigo)



More information about the OpenStack-dev mailing list