ci(android): replace cargo-apk with cargo-ndk + manual APK assembly
cargo-apk 0.10 and its fork cargo-apk2 both failed to discover the installed Android platform in this Gitea runner, despite ANDROID_HOME, platforms;android-34, build-tools, and NDK all being present, readable, and pointed at correctly. We never isolated whether the bug is in the shared ndk-build crate's discovery logic or in the runner's env-var propagation through cargo subcommand exec, so this commit stops fighting either tool and assembles the APK from explicit toolchain steps instead: cargo ndk -> per-ABI .so files aapt2 compile/link -> manifest + resources -> base APK zip -> bundle native libs into lib/<abi>/ zipalign -> 4-byte alignment apksigner -> v2/v3 signing (debug keystore for CI, real for release) The pipeline lives in scripts/build_android_apk.sh so it's reproducible locally (same env vars, same commands). AndroidManifest.xml is now checked in under solitaire_app/android/ and mirrors what cargo-apk would have generated from [package.metadata.android] — keep them in sync if either is changed. Local `cargo apk build` still works on developer machines where cargo-apk is happy; CI just stops depending on it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ env:
|
|||||||
ANDROID_SDK: /opt/android-sdk
|
ANDROID_SDK: /opt/android-sdk
|
||||||
NDK_VERSION: "25.2.9519653"
|
NDK_VERSION: "25.2.9519653"
|
||||||
BUILD_TOOLS_VERSION: "34.0.0"
|
BUILD_TOOLS_VERSION: "34.0.0"
|
||||||
|
PLATFORM: "android-34"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-apk:
|
build-apk:
|
||||||
@@ -32,7 +33,7 @@ jobs:
|
|||||||
- name: Install system dependencies
|
- name: Install system dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update -y
|
sudo apt-get update -y
|
||||||
sudo apt-get install -y openjdk-17-jdk-headless unzip
|
sudo apt-get install -y openjdk-17-jdk-headless unzip zip
|
||||||
|
|
||||||
# ── Android SDK (shared cache key with release workflow) ──────────
|
# ── Android SDK (shared cache key with release workflow) ──────────
|
||||||
- name: Cache Android SDK
|
- name: Cache Android SDK
|
||||||
@@ -56,7 +57,7 @@ jobs:
|
|||||||
sudo ${{ env.ANDROID_SDK }}/cmdline-tools/latest/bin/sdkmanager \
|
sudo ${{ env.ANDROID_SDK }}/cmdline-tools/latest/bin/sdkmanager \
|
||||||
--sdk_root=${{ env.ANDROID_SDK }} \
|
--sdk_root=${{ env.ANDROID_SDK }} \
|
||||||
"build-tools;${{ env.BUILD_TOOLS_VERSION }}" \
|
"build-tools;${{ env.BUILD_TOOLS_VERSION }}" \
|
||||||
"platforms;android-34" \
|
"platforms;${{ env.PLATFORM }}" \
|
||||||
"ndk;${{ env.NDK_VERSION }}"
|
"ndk;${{ env.NDK_VERSION }}"
|
||||||
|
|
||||||
# ── Rust toolchain ─────────────────────────────────────────────────
|
# ── Rust toolchain ─────────────────────────────────────────────────
|
||||||
@@ -84,15 +85,12 @@ jobs:
|
|||||||
key: cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
key: cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
||||||
restore-keys: cargo-registry-
|
restore-keys: cargo-registry-
|
||||||
|
|
||||||
# cargo-apk2 is the maintained fork of cargo-apk; reads the same
|
- name: Cache cargo-ndk binary
|
||||||
# `[package.metadata.android]` block. Cache key prefix `apk2-`
|
|
||||||
# so we don't restore an old cargo-apk binary from the previous key.
|
|
||||||
- name: Cache cargo-apk2 binary
|
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
id: apk-tool-cache
|
id: ndk-tool-cache
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/bin/cargo-apk2
|
path: ~/.cargo/bin/cargo-ndk
|
||||||
key: apk2-${{ runner.os }}-stable
|
key: cargo-ndk-${{ runner.os }}-stable
|
||||||
|
|
||||||
- name: Cache build artifacts
|
- name: Cache build artifacts
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@@ -101,16 +99,19 @@ jobs:
|
|||||||
key: android-target-${{ hashFiles('**/Cargo.lock') }}-${{ github.sha }}
|
key: android-target-${{ hashFiles('**/Cargo.lock') }}-${{ github.sha }}
|
||||||
restore-keys: android-target-${{ hashFiles('**/Cargo.lock') }}-
|
restore-keys: android-target-${{ hashFiles('**/Cargo.lock') }}-
|
||||||
|
|
||||||
# ── Build ──────────────────────────────────────────────────────────
|
- name: Install cargo-ndk
|
||||||
- name: Install cargo-apk2
|
if: steps.ndk-tool-cache.outputs.cache-hit != 'true'
|
||||||
if: steps.apk-tool-cache.outputs.cache-hit != 'true'
|
run: cargo install cargo-ndk --locked
|
||||||
run: cargo install cargo-apk2 --locked
|
|
||||||
|
|
||||||
|
# ── Build APK ──────────────────────────────────────────────────────
|
||||||
- name: Build debug APK
|
- name: Build debug APK
|
||||||
run: |
|
env:
|
||||||
export ANDROID_HOME=${{ env.ANDROID_SDK }}
|
ANDROID_HOME: ${{ env.ANDROID_SDK }}
|
||||||
export ANDROID_NDK_HOME=${{ env.ANDROID_SDK }}/ndk/${{ env.NDK_VERSION }}
|
ANDROID_NDK_HOME: ${{ env.ANDROID_SDK }}/ndk/${{ env.NDK_VERSION }}
|
||||||
cargo apk2 build --package solitaire_app --lib
|
BUILD_TOOLS_VERSION: ${{ env.BUILD_TOOLS_VERSION }}
|
||||||
|
PLATFORM: ${{ env.PLATFORM }}
|
||||||
|
PROFILE: debug
|
||||||
|
run: ./scripts/build_android_apk.sh
|
||||||
|
|
||||||
# ── Artifact ───────────────────────────────────────────────────────
|
# ── Artifact ───────────────────────────────────────────────────────
|
||||||
- name: Upload APK
|
- name: Upload APK
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ env:
|
|||||||
ANDROID_SDK: /opt/android-sdk
|
ANDROID_SDK: /opt/android-sdk
|
||||||
NDK_VERSION: "25.2.9519653"
|
NDK_VERSION: "25.2.9519653"
|
||||||
BUILD_TOOLS_VERSION: "34.0.0"
|
BUILD_TOOLS_VERSION: "34.0.0"
|
||||||
|
PLATFORM: "android-34"
|
||||||
GITEA_API: https://git.aleshym.co/api/v1
|
GITEA_API: https://git.aleshym.co/api/v1
|
||||||
REPO: funman300/Rusty_Solitare
|
REPO: funman300/Rusty_Solitare
|
||||||
|
|
||||||
@@ -24,9 +25,13 @@ jobs:
|
|||||||
id: meta
|
id: meta
|
||||||
run: echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
|
run: echo "tag=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
# ── Android SDK + NDK ──────────────────────────────────────────────
|
# ── System dependencies ────────────────────────────────────────────
|
||||||
# Shared cache key with the debug workflow so a warm debug run
|
- name: Install system dependencies
|
||||||
# saves the ~2 GB SDK download for the release run too.
|
run: |
|
||||||
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install -y openjdk-17-jdk-headless unzip zip jq
|
||||||
|
|
||||||
|
# ── Android SDK (shared cache key with debug workflow) ─────────────
|
||||||
- name: Cache Android SDK
|
- name: Cache Android SDK
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
id: sdk-cache
|
id: sdk-cache
|
||||||
@@ -34,12 +39,6 @@ jobs:
|
|||||||
path: ${{ env.ANDROID_SDK }}
|
path: ${{ env.ANDROID_SDK }}
|
||||||
key: v2-android-sdk-ndk${{ env.NDK_VERSION }}-bt${{ env.BUILD_TOOLS_VERSION }}
|
key: v2-android-sdk-ndk${{ env.NDK_VERSION }}-bt${{ env.BUILD_TOOLS_VERSION }}
|
||||||
|
|
||||||
# Java and jq are always needed (apksigner requires Java even on cache hits).
|
|
||||||
- name: Install system dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt-get install -y openjdk-17-jdk-headless unzip jq
|
|
||||||
|
|
||||||
- name: Install Android SDK + NDK
|
- name: Install Android SDK + NDK
|
||||||
if: steps.sdk-cache.outputs.cache-hit != 'true'
|
if: steps.sdk-cache.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
@@ -54,7 +53,7 @@ jobs:
|
|||||||
sudo ${{ env.ANDROID_SDK }}/cmdline-tools/latest/bin/sdkmanager \
|
sudo ${{ env.ANDROID_SDK }}/cmdline-tools/latest/bin/sdkmanager \
|
||||||
--sdk_root=${{ env.ANDROID_SDK }} \
|
--sdk_root=${{ env.ANDROID_SDK }} \
|
||||||
"build-tools;${{ env.BUILD_TOOLS_VERSION }}" \
|
"build-tools;${{ env.BUILD_TOOLS_VERSION }}" \
|
||||||
"platforms;android-34" \
|
"platforms;${{ env.PLATFORM }}" \
|
||||||
"ndk;${{ env.NDK_VERSION }}"
|
"ndk;${{ env.NDK_VERSION }}"
|
||||||
|
|
||||||
# ── Rust toolchain ─────────────────────────────────────────────────
|
# ── Rust toolchain ─────────────────────────────────────────────────
|
||||||
@@ -82,12 +81,12 @@ jobs:
|
|||||||
key: cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
key: cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
||||||
restore-keys: cargo-registry-
|
restore-keys: cargo-registry-
|
||||||
|
|
||||||
- name: Cache cargo-apk2 binary
|
- name: Cache cargo-ndk binary
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
id: apk-tool-cache
|
id: ndk-tool-cache
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/bin/cargo-apk2
|
path: ~/.cargo/bin/cargo-ndk
|
||||||
key: apk2-${{ runner.os }}-stable
|
key: cargo-ndk-${{ runner.os }}-stable
|
||||||
|
|
||||||
- name: Cache build artifacts
|
- name: Cache build artifacts
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@@ -96,51 +95,33 @@ jobs:
|
|||||||
key: android-release-target-${{ hashFiles('**/Cargo.lock') }}-${{ github.sha }}
|
key: android-release-target-${{ hashFiles('**/Cargo.lock') }}-${{ github.sha }}
|
||||||
restore-keys: android-release-target-${{ hashFiles('**/Cargo.lock') }}-
|
restore-keys: android-release-target-${{ hashFiles('**/Cargo.lock') }}-
|
||||||
|
|
||||||
# ── Build ──────────────────────────────────────────────────────────
|
- name: Install cargo-ndk
|
||||||
- name: Install cargo-apk2
|
if: steps.ndk-tool-cache.outputs.cache-hit != 'true'
|
||||||
if: steps.apk-tool-cache.outputs.cache-hit != 'true'
|
run: cargo install cargo-ndk --locked
|
||||||
run: cargo install cargo-apk2 --locked
|
|
||||||
|
|
||||||
- name: Build release APK
|
# ── Build & sign with release keystore ─────────────────────────────
|
||||||
run: |
|
|
||||||
export ANDROID_HOME=${{ env.ANDROID_SDK }}
|
|
||||||
export ANDROID_NDK_HOME=${{ env.ANDROID_SDK }}/ndk/${{ env.NDK_VERSION }}
|
|
||||||
cargo apk2 build --release --package solitaire_app --lib
|
|
||||||
|
|
||||||
# ── Sign ───────────────────────────────────────────────────────────
|
|
||||||
- name: Decode keystore
|
- name: Decode keystore
|
||||||
run: echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > /tmp/solitaire-release.jks
|
run: echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > /tmp/solitaire-release.jks
|
||||||
|
|
||||||
- name: Align and sign APK
|
- name: Build signed release APK
|
||||||
run: |
|
env:
|
||||||
TAG="${{ steps.meta.outputs.tag }}"
|
ANDROID_HOME: ${{ env.ANDROID_SDK }}
|
||||||
UNSIGNED="target/release/apk/solitaire-quest.apk"
|
ANDROID_NDK_HOME: ${{ env.ANDROID_SDK }}/ndk/${{ env.NDK_VERSION }}
|
||||||
ALIGNED="/tmp/solitaire-quest-aligned.apk"
|
BUILD_TOOLS_VERSION: ${{ env.BUILD_TOOLS_VERSION }}
|
||||||
SIGNED="ferrous-solitaire-${TAG}.apk"
|
PLATFORM: ${{ env.PLATFORM }}
|
||||||
|
PROFILE: release
|
||||||
|
KEYSTORE: /tmp/solitaire-release.jks
|
||||||
|
KEYSTORE_PASS: ${{ secrets.KEYSTORE_PASS }}
|
||||||
|
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
|
||||||
|
KEY_PASS: ${{ secrets.KEY_PASS }}
|
||||||
|
APK_OUT: ferrous-solitaire-${{ steps.meta.outputs.tag }}.apk
|
||||||
|
run: ./scripts/build_android_apk.sh
|
||||||
|
|
||||||
${{ env.ANDROID_SDK }}/build-tools/${{ env.BUILD_TOOLS_VERSION }}/zipalign -v 4 \
|
# ── Publish to Gitea release ───────────────────────────────────────
|
||||||
"$UNSIGNED" "$ALIGNED"
|
|
||||||
|
|
||||||
${{ env.ANDROID_SDK }}/build-tools/${{ env.BUILD_TOOLS_VERSION }}/apksigner sign \
|
|
||||||
--ks /tmp/solitaire-release.jks \
|
|
||||||
--ks-pass "pass:${{ secrets.KEYSTORE_PASS }}" \
|
|
||||||
--ks-key-alias "${{ secrets.KEY_ALIAS }}" \
|
|
||||||
--key-pass "pass:${{ secrets.KEY_PASS }}" \
|
|
||||||
--out "$SIGNED" \
|
|
||||||
"$ALIGNED"
|
|
||||||
|
|
||||||
- name: Verify APK signature
|
|
||||||
run: |
|
|
||||||
TAG="${{ steps.meta.outputs.tag }}"
|
|
||||||
${{ env.ANDROID_SDK }}/build-tools/${{ env.BUILD_TOOLS_VERSION }}/apksigner verify \
|
|
||||||
--verbose "ferrous-solitaire-${TAG}.apk"
|
|
||||||
|
|
||||||
# ── Publish ────────────────────────────────────────────────────────
|
|
||||||
- name: Create Gitea release
|
- name: Create Gitea release
|
||||||
id: release
|
id: release
|
||||||
run: |
|
run: |
|
||||||
TAG="${{ steps.meta.outputs.tag }}"
|
TAG="${{ steps.meta.outputs.tag }}"
|
||||||
# Try to create; fall back to fetching the existing release on 409.
|
|
||||||
RESPONSE=$(curl -s -o /tmp/release.json -w "%{http_code}" \
|
RESPONSE=$(curl -s -o /tmp/release.json -w "%{http_code}" \
|
||||||
-X POST "$GITEA_API/repos/$REPO/releases" \
|
-X POST "$GITEA_API/repos/$REPO/releases" \
|
||||||
-H "Authorization: token ${{ secrets.CI_TOKEN }}" \
|
-H "Authorization: token ${{ secrets.CI_TOKEN }}" \
|
||||||
|
|||||||
Executable
+135
@@ -0,0 +1,135 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build a self-signed Android APK from solitaire_app's cdylib targets.
|
||||||
|
#
|
||||||
|
# Replaces the cargo-apk pipeline with explicit cargo-ndk + aapt2 + apksigner
|
||||||
|
# steps. The CI runner was hitting an SDK-discovery bug inside cargo-apk's
|
||||||
|
# ndk-build crate that we couldn't isolate; running each Android toolchain
|
||||||
|
# step explicitly gives us a debuggable pipeline.
|
||||||
|
#
|
||||||
|
# Required environment:
|
||||||
|
# ANDROID_HOME Path to Android SDK root
|
||||||
|
# ANDROID_NDK_HOME Path to the specific NDK version
|
||||||
|
# BUILD_TOOLS_VERSION e.g. "34.0.0"
|
||||||
|
# PLATFORM e.g. "android-34"
|
||||||
|
#
|
||||||
|
# Optional environment:
|
||||||
|
# PROFILE "debug" (default) | "release"
|
||||||
|
# APK_OUT Output APK path (default: target/$PROFILE/apk/solitaire-quest.apk)
|
||||||
|
# KEYSTORE Path to keystore for signing (default: generates a debug keystore)
|
||||||
|
# KEYSTORE_PASS Keystore password (default: "android" for the generated debug keystore)
|
||||||
|
# KEY_ALIAS Key alias (default: "androiddebugkey")
|
||||||
|
# KEY_PASS Key password (default: same as KEYSTORE_PASS)
|
||||||
|
#
|
||||||
|
# Outputs:
|
||||||
|
# $APK_OUT Signed, zipaligned APK
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${ANDROID_HOME:?ANDROID_HOME must be set}"
|
||||||
|
: "${ANDROID_NDK_HOME:?ANDROID_NDK_HOME must be set}"
|
||||||
|
: "${BUILD_TOOLS_VERSION:?BUILD_TOOLS_VERSION must be set}"
|
||||||
|
: "${PLATFORM:?PLATFORM must be set (e.g. android-34)}"
|
||||||
|
|
||||||
|
PROFILE="${PROFILE:-debug}"
|
||||||
|
APK_OUT="${APK_OUT:-target/${PROFILE}/apk/solitaire-quest.apk}"
|
||||||
|
|
||||||
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
cd "$REPO_ROOT"
|
||||||
|
|
||||||
|
BT="$ANDROID_HOME/build-tools/$BUILD_TOOLS_VERSION"
|
||||||
|
PLATFORM_JAR="$ANDROID_HOME/platforms/$PLATFORM/android.jar"
|
||||||
|
MANIFEST="solitaire_app/android/AndroidManifest.xml"
|
||||||
|
RES_DIR="solitaire_app/res"
|
||||||
|
ASSETS_DIR="assets"
|
||||||
|
|
||||||
|
# --- sanity ----------------------------------------------------------------
|
||||||
|
for f in "$BT/aapt2" "$BT/zipalign" "$BT/apksigner" "$PLATFORM_JAR" "$MANIFEST"; do
|
||||||
|
[ -e "$f" ] || { echo "missing: $f"; exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
STAGING="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$STAGING"' EXIT
|
||||||
|
mkdir -p "$STAGING/lib" "$STAGING/compiled-res"
|
||||||
|
|
||||||
|
# --- 1. native libraries via cargo-ndk -------------------------------------
|
||||||
|
# `-o $STAGING/lib` lays out files as $STAGING/lib/<abi>/libsolitaire_app.so
|
||||||
|
# which is the directory structure the APK expects under lib/.
|
||||||
|
CARGO_NDK_ARGS=(
|
||||||
|
-t arm64-v8a
|
||||||
|
-t armeabi-v7a
|
||||||
|
-t x86_64
|
||||||
|
--platform 26
|
||||||
|
-o "$STAGING/lib"
|
||||||
|
build --package solitaire_app --lib
|
||||||
|
)
|
||||||
|
if [ "$PROFILE" = "release" ]; then
|
||||||
|
CARGO_NDK_ARGS+=( --release )
|
||||||
|
fi
|
||||||
|
echo ">>> cargo ndk ${CARGO_NDK_ARGS[*]}"
|
||||||
|
cargo ndk "${CARGO_NDK_ARGS[@]}"
|
||||||
|
|
||||||
|
# --- 2. compile + link resources and manifest ------------------------------
|
||||||
|
if [ -d "$RES_DIR" ]; then
|
||||||
|
echo ">>> aapt2 compile resources"
|
||||||
|
"$BT/aapt2" compile --dir "$RES_DIR" -o "$STAGING/compiled-res"
|
||||||
|
fi
|
||||||
|
|
||||||
|
LINK_ARGS=(
|
||||||
|
link
|
||||||
|
-o "$STAGING/app-unsigned.apk"
|
||||||
|
-I "$PLATFORM_JAR"
|
||||||
|
--manifest "$MANIFEST"
|
||||||
|
)
|
||||||
|
[ -d "$ASSETS_DIR" ] && LINK_ARGS+=( -A "$ASSETS_DIR" )
|
||||||
|
# Add compiled resources if any
|
||||||
|
shopt -s nullglob
|
||||||
|
RES_FLATS=( "$STAGING/compiled-res"/*.flat )
|
||||||
|
shopt -u nullglob
|
||||||
|
if [ ${#RES_FLATS[@]} -gt 0 ]; then
|
||||||
|
LINK_ARGS+=( "${RES_FLATS[@]}" )
|
||||||
|
fi
|
||||||
|
echo ">>> aapt2 link"
|
||||||
|
"$BT/aapt2" "${LINK_ARGS[@]}"
|
||||||
|
|
||||||
|
# --- 3. add native libraries to the APK ------------------------------------
|
||||||
|
echo ">>> bundle native libraries"
|
||||||
|
( cd "$STAGING" && zip -r -q app-unsigned.apk lib/ )
|
||||||
|
|
||||||
|
# --- 4. zipalign -----------------------------------------------------------
|
||||||
|
echo ">>> zipalign"
|
||||||
|
"$BT/zipalign" -p -f 4 "$STAGING/app-unsigned.apk" "$STAGING/app-aligned.apk"
|
||||||
|
|
||||||
|
# --- 5. sign ---------------------------------------------------------------
|
||||||
|
if [ -z "${KEYSTORE:-}" ]; then
|
||||||
|
# Generate a deterministic debug keystore on the fly.
|
||||||
|
KEYSTORE="$STAGING/debug.keystore"
|
||||||
|
KEYSTORE_PASS="${KEYSTORE_PASS:-android}"
|
||||||
|
KEY_ALIAS="${KEY_ALIAS:-androiddebugkey}"
|
||||||
|
KEY_PASS="${KEY_PASS:-$KEYSTORE_PASS}"
|
||||||
|
echo ">>> generating debug keystore at $KEYSTORE"
|
||||||
|
keytool -genkeypair -v \
|
||||||
|
-keystore "$KEYSTORE" \
|
||||||
|
-storepass "$KEYSTORE_PASS" \
|
||||||
|
-alias "$KEY_ALIAS" \
|
||||||
|
-keypass "$KEY_PASS" \
|
||||||
|
-keyalg RSA -keysize 2048 -validity 10000 \
|
||||||
|
-dname "CN=Android Debug,O=Android,C=US" > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
KEYSTORE_PASS="${KEYSTORE_PASS:-android}"
|
||||||
|
KEY_ALIAS="${KEY_ALIAS:-androiddebugkey}"
|
||||||
|
KEY_PASS="${KEY_PASS:-$KEYSTORE_PASS}"
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$APK_OUT")"
|
||||||
|
echo ">>> apksigner sign -> $APK_OUT"
|
||||||
|
"$BT/apksigner" sign \
|
||||||
|
--ks "$KEYSTORE" \
|
||||||
|
--ks-pass "pass:$KEYSTORE_PASS" \
|
||||||
|
--ks-key-alias "$KEY_ALIAS" \
|
||||||
|
--key-pass "pass:$KEY_PASS" \
|
||||||
|
--out "$APK_OUT" \
|
||||||
|
"$STAGING/app-aligned.apk"
|
||||||
|
|
||||||
|
echo ">>> verify"
|
||||||
|
"$BT/apksigner" verify --verbose "$APK_OUT"
|
||||||
|
|
||||||
|
echo ">>> done: $APK_OUT"
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Mirrors what cargo-apk would generate from [package.metadata.android]
|
||||||
|
in solitaire_app/Cargo.toml. Kept in-tree so the CI workflow can drive
|
||||||
|
aapt2 directly without going through cargo-apk's brittle SDK discovery.
|
||||||
|
|
||||||
|
Keep in sync with:
|
||||||
|
* Cargo.toml: package, min_sdk_version, target_sdk_version,
|
||||||
|
uses_feature, uses_permission, application label/icon,
|
||||||
|
activity orientation
|
||||||
|
* [lib].name (currently "solitaire_app") — matches the
|
||||||
|
`android.app.lib_name` meta-data value below, which is the
|
||||||
|
shared object name without the `lib` prefix or `.so` suffix.
|
||||||
|
-->
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.solitairequest.app"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
|
||||||
|
<uses-sdk
|
||||||
|
android:minSdkVersion="26"
|
||||||
|
android:targetSdkVersion="34" />
|
||||||
|
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.touchscreen"
|
||||||
|
android:required="true" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:label="Ferrous Solitaire"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:hasCode="false">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="android.app.NativeActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize|keyboard|navigation|screenLayout">
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.app.lib_name"
|
||||||
|
android:value="solitaire_app" />
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
Reference in New Issue
Block a user