...
 
Commits (13)
......@@ -7,10 +7,12 @@ stages:
- build
- test
- release
- check
variables:
TEST_IMAGE: briar/reproducer:${CI_BUILD_REF_NAME}
RELEASE_IMAGE: briar/reproducer:latest
TAG_IMAGE: briar/reproducer:${RELEASE_TAG}
before_script:
- echo ${DOCKER_HUB_PASS} | docker login -u ${DOCKER_HUB_USER} --password-stdin
......@@ -20,18 +22,24 @@ build:
script:
- docker build -t ${TEST_IMAGE} .
- docker push $TEST_IMAGE
except:
- triggers
test_success:
stage: test
script:
# Consider adding the cap and the device directly to the CI config
# https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-docker-section
- docker run --cap-add SYS_ADMIN --device /dev/fuse ${TEST_IMAGE} ./reproduce.py release-1.0.1
- docker run --cap-add SYS_ADMIN --device /dev/fuse ${TEST_IMAGE} ./reproduce.py release-1.1.7
except:
- triggers
test_failure:
stage: test
script:
- if docker run --cap-add SYS_ADMIN --device /dev/fuse ${TEST_IMAGE} ./reproduce.py release-1.0.3; then exit 1; else exit 0; fi
- if docker run --cap-add SYS_ADMIN --device /dev/fuse ${TEST_IMAGE} ./reproduce.py release-1.0.13; then exit 1; else exit 0; fi
except:
- triggers
release:
stage: release
......@@ -42,3 +50,14 @@ release:
only:
- master
- tags
except:
- triggers
check:
stage: check
script:
- docker run --cap-add SYS_ADMIN --device /dev/fuse ${RELEASE_IMAGE} ./reproduce.py ${RELEASE_TAG}
- docker tag ${RELEASE_IMAGE} ${TAG_IMAGE}
- docker push ${TAG_IMAGE}
only:
- triggers
FROM debian:stretch
FROM debian:buster
ENV LANG=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
ENV ANDROID_HOME=/opt/android-sdk
ENV REPO_URL=https://code.briarproject.org/akwizgran/briar.git
ENV REPO_URL=https://code.briarproject.org/briar/briar.git
WORKDIR /opt/briar-reproducer
......
......@@ -88,6 +88,14 @@ You can find a list of tags in Briar's
[source code repository](https://code.briarproject.org/akwizgran/briar/tags).
The `SYS_ADMIN` capability and the `fuse` device are required,
so the container can build the app inside a `disorderfs`.
We hope to be able to drop this requirement
once this [upstream issue](https://issuetracker.google.com/issues/110237303) is fixed.
\ No newline at end of file
so the container can build the app inside a `disorderfs` which shuffles the filesystem.
If the build fails with `fuse: mount failed: Permission denied`, you may need to add the argument `--security-opt apparmor:unconfined` to the Docker command.
## Historical Changes
* Before version `1.1.7`, Briar needed a deterministic files system
to work around an [Android build system bug](https://issuetracker.google.com/issues/110237303)
which broke reproducibility.
An [old version of briar-reproducer](https://code.briarproject.org/briar/briar-reproducer/tags/pre-1.1.7)
can be used to verify these releases.
......@@ -11,7 +11,7 @@ mv tools ${ANDROID_HOME}/
# Accept all those nasty EULAs
mkdir -p ${ANDROID_HOME}/licenses/
printf "\n8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e" > ${ANDROID_HOME}/licenses/android-sdk-license
printf "\n8933bad161af4178b1185d1a37fbf41ea5269c55\nd56f5187479451eabf01fb78af6dfcb131a6481e\n24333f8a63b6825ea9c5514f83c2829b004d1fee" > ${ANDROID_HOME}/licenses/android-sdk-license
printf "\n84831b9409646a918e30573bab4c9c91346d8abd" > ${ANDROID_HOME}/licenses/android-sdk-preview-license
printf "\n79120722343a6f314e0719f863036c702b0e6b2a\n84831b9409646a918e30573bab4c9c91346d8abd" > ${ANDROID_HOME}/licenses/android-sdk-preview-license-old
......
......@@ -3,19 +3,5 @@ set -e
set -x
apt-get install -y --no-install-recommends \
enjarify \
python3-pip python3-setuptools python3-wheel \
python3-libarchive-c \
libmagic1
# Install latest diffoscope (version in Debian stable is outdated)
pip3 install diffoscope
# Install latest apktool for verification debugging
wget --no-verbose https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.3.3.jar -O /opt/apktool.jar
cat >/usr/local/bin/apktool <<EOF
#!/usr/bin/env bash
java -jar /opt/apktool.jar \$@
EOF
chmod +x /usr/local/bin/apktool
mkdir -p /root/.local/share/apktool/framework
\ No newline at end of file
diffoscope \
apktool
......@@ -4,7 +4,7 @@ set -x
apt-get install -y --no-install-recommends \
git \
default-jdk-headless \
openjdk-8-jdk-headless \
fuse \
disorderfs \
unzip \
......
......@@ -2,6 +2,9 @@
set -e
set -x
# allow OpenJDK 8 to be installed from the oldstable repo
echo 'deb http://deb.debian.org/debian/ stretch main' >> /etc/apt/sources.list
# update package sources
apt-get update
apt-get -y upgrade
......
#!/usr/bin/env python3
import os
from subprocess import call, check_call, check_output
import sys
from subprocess import call, check_call, check_output
REPO_DIR = "briar"
REFERENCE_URL = 'https://briarproject.org/apk/briar-%s.apk'
GRADLE_TASK = "briar-android:assembleRelease"
APK_PATH = "briar-android/build/outputs/apk/release/briar-android-release-unsigned.apk"
APK_PATH = "briar-android/build/outputs/apk/official/release/" + \
"briar-android-official-release-unsigned.apk"
OLD_APK_PATH = "briar-android/build/outputs/apk/release/briar-android-release-unsigned.apk"
BUILD_DIR = "briar-build"
......@@ -25,16 +27,16 @@ def main():
reference_apk = "briar-%s.apk" % version
check_call(['wget', '--no-verbose', url, '-O', reference_apk])
# use deterministic file system for building the app
# use non-deterministic file system for building the app to detect issues
if not os.path.exists(BUILD_DIR):
os.makedirs(BUILD_DIR)
check_call(['disorderfs', '--sort-dirents=yes', '--reverse-dirents=no', REPO_DIR, BUILD_DIR])
check_call(['disorderfs', '--shuffle-dirents=yes', REPO_DIR, BUILD_DIR])
# build the app
check_call(["./gradlew", "--no-daemon", GRADLE_TASK], cwd=BUILD_DIR)
# check if both APKs match
apk = os.path.join(BUILD_DIR, APK_PATH)
apk = os.path.join(BUILD_DIR, APK_PATH if version >= "1.1.0" else OLD_APK_PATH)
if call(['./verify-apk.py', reference_apk, apk]) == 0:
print("Version '%s' was built reproducible! :)" % tag)
sys.exit(0)
......@@ -80,4 +82,4 @@ def fail(msg=""):
if __name__ == "__main__":
main()
main()
......@@ -53,6 +53,9 @@ def repack_apk(zip_file, new_zip_file):
if APK_SIG_FILE.match(info.filename):
continue # ignore signatures
info.extra = b'' # reset file metadata
# reset zip versions that keep changing
info.create_version = 0
info.extract_version = 0
# add file to new zip
tmp.writestr(info, f.read(info.filename))
......