This is a short guide on how to find, debug and fix reproducibility issues in openSUSE OBS package build results. Some of it will also apply to other subjects. 0. Fetch this git repo, follow the setup instructions in the README.md file. 1. find (detect) issues 1.1. run 'rbk' 1.2. for noarch packages run 'noarchcheck' 1.3. run 'nachbau' once the above is all good all of them will store their outcome in dot files in the current dir for later use. A result of '0' usually indicates 'success' or 'reproducible' in UNIX fashion. 2. debug (track down) issues This section assumes you found a package that produced diffs in rbk 2.1. run autoclassify this script will need a while and report a bitmask of what non-deterministic influences had to be disabled to produce reproducible results. If it is "1 1 1 1 1 1 1 1 1 1 1 1 99" it remained unreproducible even with all tweaks applied. Debugging the remaining diff can still be easier and once that is fixed, autoclassify can be rerun. If there are multiple bits left, you can debug one of them at a time by running 'rbkt' with fewer bits set. See rbkt source for the meaning of bits. 2.2. run autoprovenance $unreproduciblefile this script will tell you what command produced the file along with a call trace. Requires 'stracebuild' to be run before once. 2.3 other ways to find provenance 2.3.1 review diffs in .rb.buildroot.diff - e.g. .c .h .a configure Makefile and track down their provenance 2.3.2 check build log (might need to use make V=1 VERB=1) 2.3.3 grep source for strings next to diff (e.g. grep "This file was autogenerated at") 2.3.4 grep source for known troublemakers (`date, $(date, %Y, year, strftime, ctime, asctime, stat (mtime,inode,dev) readdir, os.listdir, os.walk, glob.glob, find, random, fprofile-use, -march=native, -mtune=native) 2.3.5 use difflog to see if something interesting happens related to indeterministic files 2.3.6 review relevant files (configure{,.ac}, Makefile{,.in,.am}, CMakeLists.txt, setup.py) 2.3.7 manually add strace -f 3. fix issues Once you know exactly which code line introduced non-determinism, fixing it can be pretty straightforward. https://salsa.debian.org/reproducible-builds/reproducible-website/tree/master/_blog/posts numbers 100+ has 2 years worth of links to a large collection of Bernhard's patches along with short summaries like "date" or "readdir" or "ASLR" that map to one of the entries in https://github.com/bmwiedemann/theunreproduciblepackage The workflow for fixing issues usually involves: source $path_to_reproducibleopensuse/helperfuncs qs # shorthand for quilt setup + cd + apply old patches quilt new reproducible.patch quilt edit $file quilt diff # optional quilt refresh cd .. /usr/lib/build/spec_add_patch reproducible.patch rbk # retest For patches that can not be upstreamed: bcocd cp -a ../../*.{patch,spec} . osc vc -m "Add reproducible.patch to make package build reproducible" osc addremove osc status # optional osc checkin --noservice osc submitrequest 3.1 drop unreproducible elements sometimes this is the simplest to get upstream because it can reduce the overall complexity of the build system 3.2 normalize unreproducible elements sort lists (that usually varied from filesystem readdir order or ASLR) replace build date with fixed date (e.g. SOURCE_DATE_EPOCH or ChangeLog file mtime) 3.3 fix bugs sometimes unreproducible output is the result of actual bugs and then actual upstream bugfixes rather than downstream distribution workarounds are recommended. https://github.com/bmwiedemann/theunreproduciblepackage/tree/master/race has several examples https://github.com/projectM-visualizer/projectm/pull/176 4. Do upstream patches, if possible sometimes non-determinism will be introduced by .spec files or downstream-only patches - then a osc submitrequest is enough. 4.1 locate the upstream git repo, bug tracker or website 4.1.1 grep -e ^Url -e ^Source *.spec 4.1.2 google $package git OR contribute OR bugtracker 4.2 check if the project had activity in the last 12 months if not, it may have moved or been orphaned. You can still submit a downstream patch. 4.3 make the patch git clone $URL patch -p1 < $path_to/reproducible.patch # or edit $file git checkout -b $topic # possibly check other contribution guidelines about "Signed-off-By" lines or where/how to submit fixes git commit -a # use good commit messages, that can include phrases like Do $SOMEFIX to make builds reproducible. See https://reproducible-builds.org/ for why this is good. Without this patch, build results varied in `$file` with this diff: ```diff $DIFF_EXAMPLE ``` 4.4 submit the patch 4.4.1 For projects hosted on github this can use the `hub` package: hub fork git push $yourfork hub pull-request 4.4.2 For projects doing reviews on gerrit, use 'git-review' package git review -s git commit --amend # to add a ChangeID git review 4.4.3 For projects using phabricator use the 'arcanist' package arc diff # FIXME this is incomplete 4.4.4 For projects using mercurial, use hg or https://github.com/felipec/git-remote-hg 4.4.5 For projects using mailing lists for patches: if only members can post, subscribe to ML git send-email --to "$ML_ADDR" HEAD^ check ML archive 10-30 minutes later unsubscribe from ML once patch discussion is over 4.4.6 If projects do not specify how to contribute, but you have a git repo, try git log $changedfile git send-email --to "$mainauthor" HEAD^ 4.5 Tell the world about your fix using https://salsa.debian.org/reproducible-builds/reproducible-website monthly draft blog post entries to link to your fix and become famous - one patch at a time. 4.6 Track fixes for yourself Often it takes maintainers some days or weeks to review and merge your fix, but sometimes fixes fall through cracks and then it helps to try and remind them. Also when doing your next fix, you can re-use patches and submit message from previous submissions. 4.6.1 re-check after a day if there is work left for you to do like signing a CLA, adding ChangeLog/NEWS entries, addressing outstanding concerns (either with comments or code changes) 4.6.2 after a month, ping in your submission, especially if git history shows other patches going in Can include polite helpful phrases like: Is there anything I can do to help get this simple patch merged? 4.6.3 try alternative routes of communication (not all at the same time): IRC, email, ... 4.6.4 after 6 months, if project appears orphaned: 4.6.4.1 look for active forks in github -> Insights -> Network and ask there 4.6.4.2 propose the package for inclusion in https://github.com/distropatches/ 4.6.4.3 adopt it: fork it and collect patches from others and contact previous authors and downstreams 4.6.4.4 submit the patch downstream in a distribution