-
Notifications
You must be signed in to change notification settings - Fork 323
/
checkBuild.sh
executable file
·105 lines (86 loc) · 4.05 KB
/
checkBuild.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/bin/bash
if [[ $# -eq 0 ]] ; then
printf "No arguments supplied.\nUsage: ./checkBuild.sh FILE REVISION [RETRIES]\n\n \
FILE The apk you want to verify, without extension. mbw-prodnet-release for example\n \
REVISION The git revision, tag or branch. v2.12.0.19 for example.\n \
RETRIES The number of times compilation should be retried if differences remain."
exit 1
fi
releaseFile=$1
revision=$2
# If the build tools are slightly non-deterministic and produce randomly one of two different
# versions of each file for example, you can try to rebuild several times, to eventually verify each
# file individually. The script will maintain a list of unverified files that should get shorter
# with every iteration. Pick how many retries you want to run:
retries=${3:-0}
if [[ ! -f "./${releaseFile}.apk" ]]
then
echo "./${releaseFile}.apk not found. Put the file you want to test into this folder and reference it omitting the \".apk\"."
exit 1
fi
if [[ ! -f "apktool.jar" ]]
then
echo "apktool.jar not found. Put the file into this folder. You can get it from https://ibotpeaches.github.io/Apktool/ or https://github.com/iBotPeaches/Apktool"
exit 1
fi
workdir=/tmp/mbwDeterministicBuild/
mkdir -p $workdir
printf "Checking $releaseFile against revision $revision with $retries retries if verification fails.\n \
You can monitor progress in ${workdir}progress.log\n" | tee ${workdir}progress.log
cp -r . $workdir
cd $workdir
rm local.properties # this doesn't work in docker and shouldn't be needed outside of docker.
java -jar apktool.jar d --output original $releaseFile.apk
git config user.email "[email protected]"
git config user.name "only temporary"
git stash
git checkout $revision
sed -i 's/[email protected]:/https:\/\/github.com\//' .gitmodules
git submodule update --init --recursive
# these files are either irrelevant (apktool.yml is created by the akp extractor) or not reproducible signature/meta data (CERT, MANIFEST)
ignoreFiles="apktool.yml\|original/META-INF/CERT.RSA\|original/META-INF/CERT.SF\|original/META-INF/MANIFEST.MF"
./gradlew clean :mbw:assProdRel
cp ./mbw/build/outputs/apk/prodnet/release/mbw-prodnet-release.apk candidate.apk
if [ ! -e candidate.apk ]
then
echo "Unexpected error: candidate.apk doesn't exist. Possibly the build failed. Check and try again."
exit 1
fi
java -jar apktool.jar d candidate.apk
diff --brief --recursive original/ candidate/ > 0.diff
mv candidate/ 0/
# store the list of relevant differing files in remaining.diff
cat 0.diff | grep -v "$ignoreFiles" > remaining.diff
checkFinished() {
# if remaining.diff is empty, we are done.
if [ ! -s remaining.diff ]
then
printf "$releaseFile matches $revision!\n" >> progress.log
cat progress.log
exit 0
else
printf "$(cat remaining.diff | wc -l) files differ. Trying harder to find matches.\n \
Remaining files:\n$(cat remaining.diff)\n\n" >> progress.log
fi
}
checkFinished
for i in $( seq 1 $retries ) ; do
printf "Deterministic build failed. Attempt $i to still confirm all files individually under not totally deterministic conditions.\n" >> progress.log
./gradlew clean :mbw:assProdRel
cp ./mbw/build/outputs/apk/prodnet/release/mbw-prodnet-release.apk candidate.apk
java -jar apktool.jar d candidate.apk
# join remaining filenames to a grep filter. Only these file names are relevant.
relevantFilesFilter=$(cat remaining.diff | paste -sd "|" - | sed 's/|/\\\|/g')
# diff, only listing files that differ
diff --brief --recursive original/ candidate/ > $i.diff
mv candidate/ $i/
# diff lines that were present in all prior diffs get stored in remaining.diff
cat $i.diff | grep "$relevantFilesFilter" > remaining.diff
checkFinished
done
printf "Error: The following files could not be verified:\n \
$( cat remaining.diff ) \
Error: Giving up after $retries retries. Please manually check if the differing files are acceptable using meld or any other folder diff tool.\n \
Not every tiny diff is a red flag. Maybe this script is broken. Maybe a tool compiles in a non-deterministic way. Both happened before." \
| tee -a progress.log
exit 1