Android CI workflow + CODEMAP (android-грабли, рецепт)
build-android.yaml (раннер android/VM 118): provision -> build-android.sh -> APK в gitea release на теге. CODEMAP: полный android-рецепт + 5 грабель (libssl-dev, bindgen sysroot, no-hwcodec, JDK17, debug-подпись). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
|||||||
|
name: build-android
|
||||||
|
# Собирает преднастроенный RustDesk APK (arm64-v8a) на раннере `android` (= VM 118, где тулчейн
|
||||||
|
# поднят provision-android.sh). Логику несёт scripts/build-android.sh — тот же путь, что и вручную.
|
||||||
|
#
|
||||||
|
# Секреты репозитория: RUSTDESK_SERVER, RUSTDESK_PUB_KEY, (опц.) RUSTDESK_PRESET_PASSWORD.
|
||||||
|
# Публикация: на теге v* APK прикрепляется к Gitea Release; иначе кладётся в ~/rd-ci-out.
|
||||||
|
# Подпись: без flutter/android/key.properties APK debug-подписан (для теста); свой keystore -> релизная.
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
tags: ['v*']
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY_HOST: gitea.gusik.tech
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
android:
|
||||||
|
runs-on: android
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Provision toolchain (идемпотентно)
|
||||||
|
run: |
|
||||||
|
chmod +x scripts/*.sh
|
||||||
|
bash scripts/provision-android.sh
|
||||||
|
|
||||||
|
- name: Build preconfigured APK
|
||||||
|
env:
|
||||||
|
RUSTDESK_SERVER: ${{ secrets.RUSTDESK_SERVER }}
|
||||||
|
RUSTDESK_PUB_KEY: ${{ secrets.RUSTDESK_PUB_KEY }}
|
||||||
|
RUSTDESK_PRESET_PASSWORD: ${{ secrets.RUSTDESK_PRESET_PASSWORD }}
|
||||||
|
run: bash scripts/build-android.sh
|
||||||
|
|
||||||
|
- name: Attach APK to Gitea Release
|
||||||
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||||
|
GITHUB_REF_NAME: ${{ github.ref_name }}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
base="https://${REGISTRY_HOST}/api/v1/repos/${GITHUB_REPOSITORY}"
|
||||||
|
hdr="Authorization: token ${GITEA_TOKEN}"
|
||||||
|
curl -sf -X POST "$base/releases" -H "$hdr" -H 'Content-Type: application/json' \
|
||||||
|
-d "{\"tag_name\":\"${GITHUB_REF_NAME}\",\"name\":\"${GITHUB_REF_NAME}\",\"draft\":false,\"prerelease\":false}" || true
|
||||||
|
relid=$(curl -sf "$base/releases/tags/${GITHUB_REF_NAME}" -H "$hdr" | python3 -c 'import sys,json;print(json.load(sys.stdin)["id"])')
|
||||||
|
[ -n "$relid" ] || { echo "нет release id"; exit 1; }
|
||||||
|
for f in dist/*.apk; do
|
||||||
|
echo "Uploading $(basename "$f")..."
|
||||||
|
curl -sf -X POST "$base/releases/$relid/assets?name=$(basename "$f")" -H "$hdr" -F "attachment=@$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Stash APK (dispatch)
|
||||||
|
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/rd-ci-out
|
||||||
|
cp dist/*.apk ~/rd-ci-out/
|
||||||
|
ls -la ~/rd-ci-out/*.apk
|
||||||
+24
-4
@@ -11,8 +11,10 @@
|
|||||||
| `scripts/bump-upstream.sh` | `[<tag>|latest]` → тянет пины тулчейна из CI-конфигов целевого тега RustDesk (flutter-build.yml + bridge.yml) и переписывает `upstream.txt` (с диффом). Так бамп версии не разъезжается с Flutter/vcpkg/LLVM/FRB/NDK. |
|
| `scripts/bump-upstream.sh` | `[<tag>|latest]` → тянет пины тулчейна из CI-конфигов целевого тега RustDesk (flutter-build.yml + bridge.yml) и переписывает `upstream.txt` (с диффом). Так бамп версии не разъезжается с Flutter/vcpkg/LLVM/FRB/NDK. |
|
||||||
| `scripts/provision-windows.ps1` | Идемпотентно доводит тулчейн до пинов (Rust+rustfmt, Flutter, LLVM, vcpkg@коммит). Ставит только отсутствующее/несовпадающее. Зовётся из build-windows.ps1 (skip: `RD_SKIP_PROVISION=1`). |
|
| `scripts/provision-windows.ps1` | Идемпотентно доводит тулчейн до пинов (Rust+rustfmt, Flutter, LLVM, vcpkg@коммит). Ставит только отсутствующее/несовпадающее. Зовётся из build-windows.ps1 (skip: `RD_SKIP_PROVISION=1`). |
|
||||||
| `scripts/build-windows.ps1` | Оркестратор Windows-сборки: provision → load env → клон@пин → preconfigure → codegen → vcpkg install → build.py → портативный установщик → `dist/`. |
|
| `scripts/build-windows.ps1` | Оркестратор Windows-сборки: provision → load env → клон@пин → preconfigure → codegen → vcpkg install → build.py → портативный установщик → `dist/`. |
|
||||||
|
| `scripts/provision-android.sh` | Идемпотентный Android-тулчейн на VM 118 под пины (Flutter/NDK/cargo-ndk/vcpkg/JDK17/apt). Пишет `~/dev/rd-android.env`. |
|
||||||
|
| `scripts/build-android.sh` | Оркестратор Android APK (arm64-v8a): env → клон@пин → preconfigure → build_android_deps → codegen → cargo-ndk → jniLibs → flutter apk → `dist/`. |
|
||||||
| `config/server.env.example` | Шаблон значений. Реальный `config/server.env` — в `.gitignore`. |
|
| `config/server.env.example` | Шаблон значений. Реальный `config/server.env` — в `.gitignore`. |
|
||||||
| `.gitea/workflows/` | CI: `build-windows.yaml` (раннер `windows:host`), `build-android.yaml` (VM 118). *(в работе)* |
|
| `.gitea/workflows/` | CI: `build-windows.yaml` (раннер `windows`, ✅ зелёный), `build-android.yaml` (раннер `android`/VM 118). |
|
||||||
| `rustdesk/` | Клон апстрима (gitignored, создаётся сборкой). |
|
| `rustdesk/` | Клон апстрима (gitignored, создаётся сборкой). |
|
||||||
| `dist/` | Готовые артефакты (gitignored). |
|
| `dist/` | Готовые артефакты (gitignored). |
|
||||||
|
|
||||||
@@ -73,9 +75,27 @@ GUSIK-PC `python3` = Microsoft Store-заглушка (реальный толь
|
|||||||
Стоковый Flutter 3.24.5 x64 engine отработал — `flutter build windows` собрался БЕЗ кастомного
|
Стоковый Flutter 3.24.5 x64 engine отработал — `flutter build windows` собрался БЕЗ кастомного
|
||||||
`windows-x64-release.zip` (тот нужен апстриму только для Win7). Для Win10/11 подмена не требуется.
|
`windows-x64-release.zip` (тот нужен апстриму только для Win7). Для Win10/11 подмена не требуется.
|
||||||
|
|
||||||
## Android toolchain (VM 118, позже)
|
## Android (VM 118, раннер `android`)
|
||||||
Flutter 3.24.5, NDK r28c, cargo-ndk 3.1.2, Rust android-таргеты, vcpkg android-триплеты
|
Тулчейн: `scripts/provision-android.sh` (Flutter 3.24.5, NDK r28c от Google напрямую, cargo-ndk 3.1.2,
|
||||||
(oboe, cpu-features, ffmpeg host=false). Публикация APK: gitea release + F-Droid (шаблон GusVoice).
|
Rust+aarch64-target, vcpkg@пин, FRB codegen; apt: clang/cmake/nasm/libssl-dev/openjdk-17). Пишет
|
||||||
|
`~/dev/rd-android.env`. Ставит в `~/dev` (диск VM расширен до 84G, было 64G).
|
||||||
|
Сборка: `scripts/build-android.sh` (arm64-v8a): клон@пин → preconfigure → `build_android_deps.sh arm64-v8a`
|
||||||
|
(vcpkg под arm, ffmpeg/aom из исходников — долго) → FRB codegen (`--llvm-path` авто) → `cargo ndk build`
|
||||||
|
→ jniLibs (.so+libc++_shared.so) → `flutter build apk` → `dist/rustdesk-<tag>-arm64.apk`.
|
||||||
|
Пороговый Rust-target ставит provision. Пин submodule hbb_common, пины из upstream.txt.
|
||||||
|
|
||||||
|
### Android-грабли (все зашиты в скрипты)
|
||||||
|
- **openssl-sys (host)**: `cargo ndk` падал «Could not find OpenSSL» для host-таргета → `libssl-dev` (provision).
|
||||||
|
- **bindgen NDK-sysroot**: magnum-opus/hwcodec/scrap bindgen резолвил `#include <stdint.h>` в host-glibc →
|
||||||
|
`bits/libc-header-start.h not found`. Фикс: `BINDGEN_EXTRA_CLANG_ARGS_aarch64_linux_android="--sysroot=$NDK/.../sysroot --target=aarch64-linux-android21"` (build-android.sh).
|
||||||
|
- **hwcodec**: пока БЕЗ него (`RUSTDESK_ANDROID_FEATURES=flutter`); его build.rs добавлял свои bindgen-грабли.
|
||||||
|
Включить: `RUSTDESK_ANDROID_FEATURES=flutter,hwcodec` (после доводки).
|
||||||
|
- **Java/Gradle**: VM дефолт Java 21, Gradle 7.6.4 не тянет → `JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64`
|
||||||
|
(build-android.sh, как RustDesk CI). Kotlin `e:`-варнинги (metadata 2.1.0 vs 1.6.0) — НЕ фатальны.
|
||||||
|
- **Подпись**: release требует key.properties → без него патчим build.gradle на debug-подпись
|
||||||
|
(`signingConfig = key.properties есть ? release : debug`). Свой keystore = `flutter/android/key.properties`.
|
||||||
|
|
||||||
|
Публикация APK: `.gitea/workflows/build-android.yaml` (раннер `android`) → gitea release на теге. F-Droid — позже.
|
||||||
|
|
||||||
## Грабли: прокси и vcpkg (GUSIK-PC)
|
## Грабли: прокси и vcpkg (GUSIK-PC)
|
||||||
На машине в env задан `NO_PROXY=...,192.168.5.0/24,...` (CIDR). WinHTTP-загрузчик vcpkg (и
|
На машине в env задан `NO_PROXY=...,192.168.5.0/24,...` (CIDR). WinHTTP-загрузчик vcpkg (и
|
||||||
|
|||||||
Reference in New Issue
Block a user