Update reproducible build script to reflect build process

This commit is contained in:
ayumi-signal 2024-08-05 13:37:53 -07:00
parent d9baaa358a
commit ec36ae7f26
5 changed files with 148 additions and 21 deletions

View file

@ -5,12 +5,19 @@ FROM ubuntu:jammy-20230624@sha256:b060fffe8e1561c9c3e6dea6db487b900100fc26830b9e
# UNIX timestamp will be generated at the time of the build, and is non-deterministic.
#
# Read https://reproducible-builds.org/specs/source-date-epoch/ for more info
ENV SOURCE_DATE_EPOCH=1
ENV SOURCE_DATE_EPOCH=0
# Due to some issues with NVM reading .nvmrc, we define the version
# as an environment variable and use that instead.
ARG NODE_VERSION
# User for building. electron-builder works better when not running as root.
ARG USERNAME=signaluser
ARG USER_UID=1000
ARG USER_GID=$USER_UID
ENV SIGNAL_ENV=production
# ---
# This portion of the code is identical to the Signal Android's
# reproducible build system. https://github.com/signalapp/Signal-Android/blob/main/reproducible-builds/Dockerfile
@ -19,18 +26,21 @@ ARG NODE_VERSION
COPY docker/ docker/
COPY docker/apt.conf docker/sources.list /etc/apt/
# Ubuntu needs the ca-certificates package before it'll trust our mirror.
# But we can't install it because it doesn't trust our mirror!
# Temporarily disables APT's certificate signature checking
# to download the certificates. See
# to download the certificates.
RUN apt update -oAcquire::https::Verify-Peer=false
RUN apt install -oAcquire::https::Verify-Peer=false -y ca-certificates
# Back to normal, verification back on
RUN apt update
RUN apt install -y git curl g++ gcc make python3 tar
# ---
# Install nvm
ENV NVM_VERSION=0.40.0
ENV NVM_DIR=/usr/local/nvm
ENV NVM_VERSION=0.39.7
RUN mkdir $NVM_DIR
RUN curl -o- "https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh" | bash \
@ -43,3 +53,18 @@ ENV NODE_PATH=$NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH=$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN git config --global --add safe.directory /project
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Use non-root user for build.
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME
USER $USERNAME
ENTRYPOINT ["docker-entrypoint.sh"]
# Specify build type using CMD, which affects the app version and name of the resulting package.
# For more information see build.sh and docker-entrypoint.sh
CMD ["dev"]

View file

@ -1,6 +1,9 @@
<!-- Copyright 2024 Signal Messenger, LLC -->
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# Reproducible builds
In order to verify that Signal's official apps are correctly built from the open source code, we need *reproducible builds*.
In order to verify that Signal's official apps are correctly built from the open source code, we need _reproducible builds_.
Reproducible builds help ensure that anyone, including you, can build Signal Desktop in a way that is completely identical to the official downloads available to all users.
@ -12,6 +15,12 @@ Reproducible builds for macOS and Windows are not available yet.
## Reproduce and verify the Linux build
### Experimental notice
We are in the process of rolling out and verifying reproducible builds. As such, reproducibility is still
experimental and may not work on public releases yet. If you notice any inconsistencies then please file an issue [on the Github Issues page](https://github.com/signalapp/Signal-Desktop/issues).
Thanks for your patience while we set it up!
### Pre-requisites
- Docker Engine is installed and running on your computer
@ -26,26 +35,28 @@ First, grab the source code by using `git`:
$ git clone https://github.com/signalapp/Signal-Desktop.git
```
This will download Signal Desktop's source code under the `Signal-Desktop` file. Once the download is complete, go inside the file and make sure you are selecting the branch used in official builds. For instance, if you are trying to build `7.18.0`, then do:
This will download Signal Desktop's source code under the `Signal-Desktop` directory. Once the download is complete, go inside the directory and make sure you are on the branch used in official builds. For instance, if you are trying to build `7.18.0`, then do:
```bash
$ cd Signal-Desktop/
Signal-Desktop$ git checkout tags/7.16.0
$ git checkout tags/7.18.0
```
You are now on the version of the source code used for `7.16.0`. Then, make sure your shell is in the `reproducible-builds` directory first:
You are now on the version of the source code used for `7.18.0`. Then, make sure your shell is in the `reproducible-builds` directory:
```bash
Signal-Desktop$ cd reproducible-builds/
Signal-Desktop/reproducible-builds$ pwd
$ cd reproducible-builds/
$ pwd
[...]/Signal-Desktop/reproducible-builds
```
Last step is to run the `./build.sh` script. (If your user is not in Docker's `docker` group, then you may need to run the script as `sudo`).
The last step is to run the `./build.sh` script, passing the "public" arg because you are verifying
a public production or beta build.
(If your user is not in Docker's `docker` group, then you may need to run the script as `sudo`).
```bash
Signal-Desktop/reproducible-builds$ chmod +x ./build.sh
Signal-Desktop/reproducible-builds$ ./build.sh
$ chmod +x ./build.sh public
$ ./build.sh public
```
This bash script will do two things. First, it will create the Docker container where Signal Desktop will be built. Second, it will build Signal Desktop inside the container.

View file

@ -1,5 +1,36 @@
#!/bin/sh
# Copyright 2024 Signal Messenger, LLC
# SPDX-License-Identifier: AGPL-3.0-only
docker build -t signal-desktop --build-arg NODE_VERSION=$(cat ../.nvmrc) .
# Usage:
# ./build.sh [ dev (default) | public (prod and beta builds) | alpha | test | staging ] [ Build timestamp override. Defaults to latest git commit or 0. ]
# First we prepare the docker container in which our build scripts will run. This container includes
# all build dependencies at specific versions.
# We set SOURCE_DATE_EPOCH to make system build timestamps deterministic.
docker build -t signal-desktop --build-arg SOURCE_DATE_EPOCH=0 --build-arg NODE_VERSION=$(cat ../.nvmrc) .
# Before performing the actual build, go to the project root.
cd ..
docker run --rm -v "$(pwd)":/project -w /project --user "$(id -u):$(id -g)" signal-desktop sh -c "npm install; npm run generate; npm run build-release"
# Prepare the timestamp of the actual build based on the latest git commit.
source_date_epoch=0
if [ "$2" != "" ]; then
echo "Using override timestamp for SOURCE_DATE_EPOCH."
source_date_epoch=$(($2))
else
git_timestamp=$(git log -1 --pretty=%ct)
if [ "${git_timestamp}" != "" ]; then
echo "At commit: $(git log -1 --oneline)"
echo "Setting SOURCE_DATE_EPOCH to latest commit's timestamp."
source_date_epoch=$((git_timestamp))
else
echo "Can't get latest commit timestamp. Defaulting to 0."
source_date_epoch=0
fi
fi
# Perform the build by mounting the project into the container and passing in the 1st command line
# arg to select the build type (e.g. "public"). The container runs docker-entrypoint.sh.
# After the process is finished, the resulting package is located in the ./release/ directory.
docker run --rm -v "$(pwd)":/project -w /project --user "$(id -u):$(id -g)" -e SOURCE_DATE_EPOCH=$source_date_epoch signal-desktop $1

View file

@ -0,0 +1,60 @@
#!/usr/bin/env bash
# Copyright 2024 Signal Messenger, LLC
# SPDX-License-Identifier: AGPL-3.0-only
trap '[[ $pid ]] && kill $pid; exit' EXIT
# This is the default entrypoint for the when running the build container.
# Usage: docker-entrypoint.sh [BUILD_TYPE]
# BUILD_TYPE affects the package name and version.
# dev (default):
# - name: signal-desktop
# - version: package.json version
# public:
# - name: signal-desktop or signal-desktop-beta, depending on package.json version
# - version: package.json version
# alpha:
# - name: signal-desktop-alpha
# - version: package.json version + commit sha
# test: Same as alpha
# staging:
# - name: signal-desktop-staging
# - version: package.json version + commit sha; replaces "alpha" with "staging"
if [ "$1" != "" ]; then
BUILD_TYPE="$1"
fi
echo "BUILD_TYPE: ${BUILD_TYPE}"
# SOURCE_DATE_EPOCH allows package builders like FPM (used for creating the .deb
# package on linux) to make their build timestamps determistic. Otherwise, a fresh
# UNIX timestamp will be generated at the time of the build, and is non-deterministic.
echo "SOURCE_DATE_EPOCH: ${SOURCE_DATE_EPOCH}"
npm install
npm run clean-transpile
cd sticker-creator
npm install
npm run build
cd ..
npm run generate
if [ "${BUILD_TYPE}" = "public" ]; then
npm run prepare-beta-build
elif [ "${BUILD_TYPE}" = "alpha" ]; then
npm run prepare-alpha-version
npm run prepare-alpha-build
elif [ "${BUILD_TYPE}" = "staging" ]; then
npm run prepare-alpha-version
npm run prepare-staging-build
elif [ "${BUILD_TYPE}" = "test" ]; then
npm run prepare-alpha-version
npm run prepare-alpha-build
elif [ "${BUILD_TYPE}" = "dev" ]; then
echo "dev build, using package.json as is"
else
echo "Unknown build type ${BUILD_TYPE}"
exit 1
fi
npm run build-linux

View file

@ -60,7 +60,7 @@ async function main() {
const outPath = join(__dirname, '../../build/dns-fallback.json');
//await writeFile(outPath, `${JSON.stringify(config, null, 2)}\n`);
await writeFile(outPath, `${JSON.stringify(config, null, 2)}\n`);
}
main().catch(error => {