Skip to content

Mobile Release Build (Deterministic & Code Transparency) #126

Mobile Release Build (Deterministic & Code Transparency)

Mobile Release Build (Deterministic & Code Transparency) #126

Workflow file for this run

name: Mobile Release Build (Deterministic & Code Transparency)
on:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-22.04
permissions:
contents: write
steps:
- name: Checkout Code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set SOURCE_DATE_EPOCH for Reproducible Builds
run: |
COMMIT_TIME=$(git log -1 --pretty=%ct)
echo "SOURCE_DATE_EPOCH=$COMMIT_TIME" >> $GITHUB_ENV
echo "Build Time Epoch: $COMMIT_TIME"
- name: Setup JDK 17
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'
cache-dependency-path: 'gradle/wrapper/gradle-wrapper.properties'
- name: Make scripts executable
run: chmod +x gradlew
- name: Read Version Info
run: |
VERSION_CODE=$(grep versionCode app/version.properties | cut -d= -f2 | tr -d '[:space:]')
VERSION_NAME=$(grep -o 'currentVersionName = "[^"]*"' app/build.gradle.kts | cut -d'"' -f2)
echo "VERSION_CODE=$VERSION_CODE" >> $GITHUB_ENV
echo "VERSION_NAME=$VERSION_NAME" >> $GITHUB_ENV
echo ">>> Version: $VERSION_NAME (Build $VERSION_CODE)"
- name: Inject secrets into verifyblind.properties
env:
SENTRY_DSN_ANDROID: ${{ secrets.SENTRY_DSN_ANDROID }}
run: |
# Eski SENTRY_DSN satirini sil (basit adres, replacement-escape yok), yenisini birebir ekle.
# printf degeri yorumlamadan yazar — DSN'deki ozel karakterler (sed replacement) sorun cikarmaz.
sed -i '/^SENTRY_DSN=/d' verifyblind.properties
printf 'SENTRY_DSN=%s\n' "$SENTRY_DSN_ANDROID" >> verifyblind.properties
LINE=$(grep '^SENTRY_DSN=' verifyblind.properties || true)
[ "${#LINE}" -gt 11 ] && echo "DSN inject: OK" || { echo "DSN inject: FAILED (secret empty?)"; exit 1; }
- name: Run Unit Tests
run: ./gradlew test --no-daemon
- name: Build Unsigned AAB
run: ./gradlew bundleRelease -Dorg.gradle.java.home=$JAVA_HOME_17_X64 --no-daemon
- name: Extract DEX Hashes & Generate dex-hashes.json
run: |
unzip -q app/build/outputs/bundle/release/app-release.aab "base/dex/*.dex" -d extracted_dex
cat > dex-hashes.json << EOF
{
"version_code": $VERSION_CODE,
"version_name": "$VERSION_NAME",
"git_commit": "${{ github.sha }}",
"repository": "${{ github.repository }}",
"dex_hashes": {
EOF
FIRST=1
for dex in $(ls extracted_dex/base/dex/*.dex | sort); do
HASH=$(sha256sum "$dex" | awk '{print $1}')
FILENAME=$(basename "$dex")
if [ $FIRST -eq 1 ]; then
FIRST=0
else
echo "," >> dex-hashes.json
fi
printf ' "%s": "%s"' "$FILENAME" "$HASH" >> dex-hashes.json
done
cat >> dex-hashes.json << EOF
}
}
EOF
echo ">>> dex-hashes.json:"
cat dex-hashes.json
- name: Generate Build Transparency Report
run: |
S="$GITHUB_STEP_SUMMARY"
echo "### VerifyBlind Deterministic Build Transparency Report" >> $S
echo "" >> $S
echo "| Alan | Değer |" >> $S
echo "|------|-------|" >> $S
echo "| **Versiyon** | $VERSION_NAME (Build $VERSION_CODE) |" >> $S
echo "| **Commit** | [\`${GITHUB_SHA:0:7}\`](https://github.com/${{ github.repository }}/tree/${{ github.sha }}) |" >> $S
echo "| **Tam Commit Hash** | \`${{ github.sha }}\` |" >> $S
echo "" >> $S
echo "#### DEX Hash'leri" >> $S
echo "Aşağıdaki hash'ler bu commit'ten derlenen uygulama kodunun matematiksel özetidir." >> $S
echo "\`\`\`" >> $S
for dex in $(ls extracted_dex/base/dex/*.dex | sort); do
HASH=$(sha256sum "$dex" | awk '{print $1}')
FILENAME=$(basename "$dex")
echo "$HASH $FILENAME" >> $S
done
echo "\`\`\`" >> $S
echo "" >> $S
echo "---" >> $S
echo "## Telefonunuzdaki Uygulamayı Nasıl Doğrularsınız?" >> $S
echo "" >> $S
echo "Aşağıdaki yöntemlerden birini seçin. Her ikisi de telefonun USB ile bağlı ve **USB Hata Ayıklama** açık olmasını gerektirir." >> $S
echo "> **USB Hata Ayıklama:** Telefon Ayarları → Geliştirici Seçenekleri → USB Hata Ayıklama" >> $S
echo "> Geliştirici Seçenekleri gizliyse: Ayarlar → Telefon Hakkında → Derleme Numarası'na 7 kez dokunun." >> $S
echo "" >> $S
echo "### Otomatik Doğrulama (Windows)" >> $S
echo "" >> $S
echo "**1.** Doğrulama scriptini indirin:" >> $S
echo "- [verify-windows.ps1](https://cdn.verifyblind.com/autoverifyscripts/verify-windows.ps1)" >> $S
echo "" >> $S
echo "**2.** PowerShell açın ve scripti çalıştırın:" >> $S
echo "\`\`\`powershell" >> $S
echo "./verify-windows.ps1" >> $S
echo "\`\`\`" >> $S
echo "> ADB (telefon bağlantısı için gerekli araç) sisteminizde yoksa script otomatik olarak indirip kurar — sizden bir şey yapmanız beklenmiyor." >> $S
echo "> Script ilk kez çalışmıyorsa: PowerShell'de \`Set-ExecutionPolicy -Scope CurrentUser RemoteSigned\` yazıp tekrar deneyin." >> $S
echo "" >> $S
echo "### Otomatik Doğrulama (macOS / Linux)" >> $S
echo "" >> $S
echo "**1.** ADB kurun:" >> $S
echo "\`\`\`bash" >> $S
echo "# macOS" >> $S
echo "brew install android-platform-tools" >> $S
echo "" >> $S
echo "# Ubuntu / Debian" >> $S
echo "sudo apt install adb" >> $S
echo "\`\`\`" >> $S
echo "" >> $S
echo "**2.** Doğrulama scriptini indirin ve çalıştırın:" >> $S
echo "\`\`\`bash" >> $S
echo "curl -O https://cdn.verifyblind.com/autoverifyscripts/verify-unix.sh" >> $S
echo "chmod +x verify-unix.sh" >> $S
echo "./verify-unix.sh" >> $S
echo "\`\`\`" >> $S
echo "" >> $S
echo "---" >> $S
echo "" >> $S
echo "**Ekranda gördükleriniz ne anlama geliyor ve neden güvenebilirsiniz?** Script önce uygulamanızın versiyon ve commit hash'ini doğrudan telefonun belleğinden okur — bu değerler bu sayfanın üstündekiyle aynı olmalıdır. Sonra telefondaki APK'nın içindeki her \`classes*.dex\` dosyasının SHA-256 kriptografik özetini hesaplayıp GitHub Release'inde yayınlanan beklenen hash'lerle karşılaştırır. Her satırın yanındaki **ESLESTI** yazısı, telefonunuzdaki o kod parçasının bit-bit GitHub'daki kodla aynı olduğunu kanıtlar; son ekrandaki yeşil **DOGRULAMA BASARILI** mesajı ise uygulamayı çalıştıran kodun tamamen üstte gördüğünüz commit'ten derlendiğini matematiksel olarak garanti eder." >> $S
echo "" >> $S
echo "Bu doğrulamada VerifyBlind'in iddialarına değil, matematiğin kendisine güveniyorsunuz: scriptin her satırını çalıştırmadan önce açıp okuyabilirsiniz, karşılaştırılan hash'ler GitHub Actions'ın değiştirilemez build kayıtlarından geliyor ve SHA-256 öyle bir özet fonksiyondur ki farklı bir kodun aynı hash'i üretmesi pratik olarak imkânsızdır. Aradaki herhangi bir adımda — build sunucusu, dağıtım kanalı, hatta cihazınızın depolama alanı — farklı bir kod gizlenmiş olsaydı eşleşme olmazdı." >> $S
echo "" >> $S
echo "### Manuel Doğrulama (İleri Düzey)" >> $S
echo "" >> $S
echo "**1.** ADB'yi kurun (yukarıdaki adımlara bakın)" >> $S
echo "" >> $S
echo "**2.** Telefondaki APK yolunu öğrenin:" >> $S
echo "\`\`\`bash" >> $S
echo "adb shell pm path com.verifyblind.mobile" >> $S
echo "\`\`\`" >> $S
echo "Çıktı örneği: \`package:/data/app/~~XxXx==/com.verifyblind.mobile-XxXx==/base.apk\`" >> $S
echo "" >> $S
echo "**3.** APK'yı bilgisayarınıza çekin (\`package:\` önekini kaldırarak yolu kullanın):" >> $S
echo "\`\`\`bash" >> $S
echo "adb pull /data/app/~~XxXx==/com.verifyblind.mobile-XxXx==/base.apk base.apk" >> $S
echo "\`\`\`" >> $S
echo "" >> $S
echo "**4.** DEX dosyalarını çıkarıp hash'leyin:" >> $S
echo "\`\`\`bash" >> $S
echo "# macOS / Linux" >> $S
echo "unzip -q base.apk \"*.dex\" -d dex && sha256sum dex/*.dex" >> $S
echo "\`\`\`" >> $S
echo "\`\`\`powershell" >> $S
echo "# Windows PowerShell" >> $S
echo "Expand-Archive base.apk dex" >> $S
echo "Get-ChildItem dex\\*.dex | ForEach-Object { (Get-FileHash \$_ -Algorithm SHA256).Hash.ToLower() + \" \" + \$_.Name }" >> $S
echo "\`\`\`" >> $S
echo "" >> $S
echo "**5.** Çıktıdaki hash'leri bu sayfanın üstündeki **DEX Hash'leri** tablosuyla karşılaştırın — tüm satırlar birebir eşleşmeli." >> $S
- name: Create GitHub Release
if: github.event_name == 'workflow_dispatch'
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="build-$VERSION_CODE"
TITLE="VerifyBlind v$VERSION_NAME (Build $VERSION_CODE)"
printf '**Sürüm / Version:** %s (Build %s)\n' "$VERSION_NAME" "$VERSION_CODE" > release-body.md
cat >> release-body.md <<'EOF'
**Commit:** [`${{ github.sha }}`](https://github.com/${{ github.repository }}/commit/${{ github.sha }})
Bu release'e ekli `dex-hashes.json`, bu commit'ten derlenen uygulamanın DEX kod bileşenlerinin SHA-256 özetlerini içerir. Telefonunuzdaki uygulamanın bu koddan derlendiğini aşağıdaki araçla kanıtlayabilirsiniz.
The attached `dex-hashes.json` contains the SHA-256 digests of the app's DEX code components built from this commit. You can prove the app on your phone was built from this code with the tool below.
---
### 🇹🇷 Telefonunuzdaki uygulamayı doğrulayın
**Gereken:** Telefonda USB Hata Ayıklama açık + USB bağlı. (Ayarlar → Geliştirici Seçenekleri → USB Hata Ayıklama; Geliştirici Seçenekleri gizliyse Telefon Hakkında → Derleme Numarası'na 7 kez dokunun.)
**Windows (PowerShell):**
```powershell
irm https://cdn.verifyblind.com/autoverifyscripts/verify-windows.ps1 -OutFile verify-windows.ps1
./verify-windows.ps1
```
**macOS / Linux:**
```bash
curl -O https://cdn.verifyblind.com/autoverifyscripts/verify-unix.sh
chmod +x verify-unix.sh
./verify-unix.sh
```
Araç telefondaki APK'nın DEX dosyalarını hash'leyip yukarıdaki `dex-hashes.json` ile karşılaştırır; yeşil **DOĞRULAMA BAŞARILI** = kod birebir eşleşiyor. Tam açıklama + manuel yöntem: [README](https://github.com/${{ github.repository }}#readme).
### 🇬🇧 Verify the app on your phone
**Requires:** USB debugging enabled + phone connected via USB.
**Windows (PowerShell):**
```powershell
irm https://cdn.verifyblind.com/autoverifyscripts/verify-windows.ps1 -OutFile verify-windows.ps1
./verify-windows.ps1
```
**macOS / Linux:**
```bash
curl -O https://cdn.verifyblind.com/autoverifyscripts/verify-unix.sh
chmod +x verify-unix.sh
./verify-unix.sh
```
The tool hashes the DEX files in the APK on your phone and compares them to `dex-hashes.json` above; a green **VERIFICATION SUCCESSFUL** means the code matches bit-for-bit. Full explanation + manual method: [README](https://github.com/${{ github.repository }}#readme).
EOF
gh release delete "$TAG" --yes 2>/dev/null || true
git push origin ":refs/tags/$TAG" 2>/dev/null || true
gh release create "$TAG" \
--title "$TITLE" \
--notes-file release-body.md \
--repo "${{ github.repository }}" \
dex-hashes.json \
app/build/outputs/bundle/release/app-release.aab
- name: Upload AAB Artifact
uses: actions/upload-artifact@v7
with:
name: verifyblind-release-aab
path: app/build/outputs/bundle/release/app-release.aab