Files
opencode-mobile/.github/workflows/publish-fdroid.yml
engineer ace8c19816 feat(analytics): add consent-gated activation-funnel analytics via PostHog
Installs are up 615% but 7-day retention is ~0% and we had no analytics SDK
to see where users drop off. Adds a thin PostHog wrapper (src/lib/analytics.ts)
that tracks app_opened, connection_form_submitted, connection_attempted,
connection_succeeded/failed (with a coarse error_class, e.g. the known 401
auth bug), message_sent, and response_received.

PostHog was chosen over Aptabase for its GMS-free JS-only RN SDK (fine for
the F-Droid/no-Firebase build), EU-hosted/self-host option, and generous
free tier. Analytics shares the exact same consent flag as Sentry
(telemetry.ts now gates both) so zero network calls happen without explicit
opt-in.

Requires a new EXPO_PUBLIC_POSTHOG_KEY CI secret (wired into build.yml,
publish-fdroid.yml, publish-play-store.yml, and documented in
publish-app-store.yml alongside the existing Sentry secrets).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJKAQ6HAikWGQK7PGZ5Y4E
2026-07-16 15:48:16 -07:00

149 lines
5.8 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Publish F-Droid Repo
on:
push:
tags: ["v*"]
workflow_dispatch:
jobs:
publish-fdroid:
runs-on: ubuntu-latest
permissions:
contents: write
env:
EXPO_PUBLIC_SENTRY_DSN: ${{ secrets.EXPO_PUBLIC_SENTRY_DSN }}
EXPO_PUBLIC_POSTHOG_KEY: ${{ secrets.EXPO_PUBLIC_POSTHOG_KEY }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 20
cache: npm
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 17
- name: Setup Android SDK
uses: android-actions/setup-android@v4
- name: Cache Gradle
uses: actions/cache@v5
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
android/.gradle
key: ${{ runner.os }}-gradle-${{ hashFiles('android/**/*.gradle*', 'android/gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Install dependencies
run: npm install --legacy-peer-deps
- name: Expo prebuild
run: npx expo prebuild --platform android --no-install
- name: Setup signing
run: |
if [[ -n "${{ secrets.KEYSTORE_BASE64 }}" ]]; then
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > android/app/release.keystore
echo "RELEASE_STORE_FILE=release.keystore" >> "$GITHUB_ENV"
echo "RELEASE_STORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> "$GITHUB_ENV"
echo "RELEASE_KEY_ALIAS=${{ secrets.KEY_ALIAS }}" >> "$GITHUB_ENV"
echo "RELEASE_KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> "$GITHUB_ENV"
echo "Signing: production keystore"
else
keytool -genkey -v -keystore android/app/debug.keystore -storepass android \
-alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 \
-dname "CN=Android Debug,O=Android,C=US"
echo "Signing: debug keystore"
fi
- name: Build APK
working-directory: android
run: ./gradlew assembleRelease
- name: Re-sign APK v1+v2 only (drop v3/v4 for fdroidserver compatibility)
if: ${{ env.RELEASE_STORE_FILE != '' }}
run: |
# androguard (used by fdroidserver) crashes parsing a v2+v3 signature
# block pair: "'NoOverwriteDict' object has no attribute 'append'".
# expo prebuild regenerates build.gradle, so we can't rely on the
# gradle signing flags surviving — force v1+v2-only here deterministically.
APK=android/app/build/outputs/apk/release/app-release.apk
APKSIGNER=$(ls "$ANDROID_HOME"/build-tools/*/apksigner | sort -V | tail -1)
echo "Using $APKSIGNER"
"$APKSIGNER" sign \
--ks android/app/release.keystore \
--ks-pass "pass:${RELEASE_STORE_PASSWORD}" \
--ks-key-alias "${RELEASE_KEY_ALIAS}" \
--key-pass "pass:${RELEASE_KEY_PASSWORD}" \
--v1-signing-enabled true \
--v2-signing-enabled true \
--v3-signing-enabled false \
--v4-signing-enabled false \
"$APK"
echo "=== signature schemes after re-sign ==="
"$APKSIGNER" verify -v "$APK" | grep -i "Verified using" || true
- name: Install fdroidserver
# androguard version matters. 4.1.4 crashes extracting the signer cert
# ("'NoOverwriteDict' object has no attribute 'append'" in
# parse_v2_v3_signature) — this is what broke the publish from v0.4.2 on.
# 4.1.3 is the version that successfully published v0.3.2–v0.4.1 and parses
# our (v1+v2-only, re-signed above) APK cleanly — verified locally against
# the release APK via fdroidserver.common.get_first_signer_certificate.
run: pip install "fdroidserver==2.4.4" "androguard==4.1.3"
- name: Setup F-Droid repo
id: fdroid-setup
run: |
FDROID_DIR="$HOME/fdroid-repo"
mkdir -p "$FDROID_DIR/repo"
mkdir -p "$FDROID_DIR/metadata"
echo "${{ secrets.FDROID_REPO_KEYSTORE_B64 }}" | base64 -d > "$FDROID_DIR/repo-keystore.jks"
cat > "$FDROID_DIR/config.yml" << CONFIGEOF
repo_url: https://dzianisv.github.io/opencode-mobile/fdroid/repo
repo_name: OpenCode Mobile
repo_description: OpenCode Mobile - AI coding assistant companion app
keystore: $FDROID_DIR/repo-keystore.jks
repo_keyalias: ${{ secrets.FDROID_REPO_KEY_ALIAS }}
keystorepass: ${{ secrets.FDROID_REPO_KEYSTORE_PASS }}
keypass: ${{ secrets.FDROID_REPO_KEY_PASS }}
CONFIGEOF
cp android/app/build/outputs/apk/release/app-release.apk "$FDROID_DIR/repo/"
echo "fdroid-dir=$FDROID_DIR" >> "$GITHUB_OUTPUT"
- name: Generate F-Droid repo index
run: |
cd "${{ steps.fdroid-setup.outputs.fdroid-dir }}"
fdroid update --create-metadata
- name: Verify F-Droid repo index was generated
run: |
IDX="${{ steps.fdroid-setup.outputs.fdroid-dir }}/repo/index.xml"
if [[ ! -f "$IDX" ]]; then
echo "ERROR: F-Droid repo index not generated at $IDX"
ls -la "${{ steps.fdroid-setup.outputs.fdroid-dir }}/repo/" || true
exit 1
fi
echo "F-Droid repo index verified: $(wc -c < "$IDX") bytes"
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ${{ steps.fdroid-setup.outputs.fdroid-dir }}/repo
destination_dir: fdroid/repo
keep_files: true