Skip to content

Commit be0112a

Browse files
committed
Use strip-nondeterminism to make tarballs reproducible
1 parent f268398 commit be0112a

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ jobs:
1212
with:
1313
submodules: recursive
1414
persist-credentials: false
15+
- name: Install strip-nondeterminism
16+
run: sudo apt-get install strip-nondeterminism
1517
- name: Install Node.js
1618
uses: actions/setup-node@v4
1719
with:

release-automation/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ These are the bespoke scripts that we use to automate various aspects of releasi
66

77
This is what creates most of the downloads that are up on our website and on GitHub.
88

9+
Optional dependencies:
10+
11+
* [Git](https://git-scm.com/) (used to get the time of the most recent commit)
12+
* [strip-nondeterminism](https://salsa.debian.org/reproducible-builds/strip-nondeterminism) (Linux only, used for tarballs)
13+
914
You must specify which platform to build for:
1015

1116
```
@@ -44,6 +49,7 @@ You must specify which platform to build for:
4449
4550
--tarball
4651
Create tar.gz files for Linux.
52+
If strip-nondeterminism is installed, tarballs will be reproducible.
4753
4854
--appimage
4955
Create AppImage executables for Linux.

release-automation/build.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,30 @@ const buildDebian = () => build({
303303
const buildTarball = () => build({
304304
platformName: 'LINUX',
305305
platformType: 'tar.gz',
306-
manageUpdates: true
306+
manageUpdates: true,
307+
extraConfig: {
308+
// gzip header contains various non-deterministic fields that we would like to remove.
309+
// TODO: would be nice to reimplement this small part of strip-nondeterminism in JS to remove dependency.
310+
artifactBuildCompleted: async (artifact) => new Promise((resolve, reject) => {
311+
console.log(`Running strip-nondeterminism on ${artifact.file}`)
312+
const stripNondeterminism = childProcess.spawn('strip-nondeterminism', [artifact.file]);
313+
stripNondeterminism.on('error', (e) => {
314+
if (e.code === 'ENOENT') {
315+
console.error('strip-nondeterminism is not installed; tarball may not be reproducible.')
316+
resolve();
317+
} else {
318+
reject(e);
319+
}
320+
});
321+
stripNondeterminism.on('close', (code) => {
322+
if (code === 0) {
323+
resolve();
324+
} else {
325+
reject(new Error(`strip-nondeterminism exited with status code ${code}`));
326+
}
327+
});
328+
})
329+
}
307330
});
308331

309332
const buildAppImage = () => build({

0 commit comments

Comments
 (0)