Files
opencode-mobile/.github/workflows/publish-fdroid.yml
engineer eea84a3f35 fix(ci): pin androguard==4.1.3 for F-Droid publish (4.1.4 crashes on signer cert)
androguard 4.1.4 raises 'NoOverwriteDict object has no attribute append' in
parse_v2_v3_signature when fdroidserver extracts the signer cert — this broke the
self-hosted F-Droid publish from v0.4.2 on. 4.1.3 (which shipped v0.3.2–v0.4.1)
parses our re-signed v1+v2-only APK cleanly; verified locally with
fdroidserver.common.get_first_signer_certificate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 01:29:59 -07:00

148 lines
5.7 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 }}
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