|
| 1 | +name: Build Android ARM64 Rust |
| 2 | + |
| 3 | +on: |
| 4 | + workflow_dispatch: |
| 5 | + inputs: |
| 6 | + repo: |
| 7 | + description: 'GitHub repo (org/name) or crates.io name' |
| 8 | + required: true |
| 9 | + type: string |
| 10 | + binary: |
| 11 | + description: 'Binary name to install (empty = library .so)' |
| 12 | + required: false |
| 13 | + default: '' |
| 14 | + type: string |
| 15 | + features: |
| 16 | + description: 'Cargo features (comma-separated)' |
| 17 | + required: false |
| 18 | + default: '' |
| 19 | + type: string |
| 20 | + version: |
| 21 | + description: 'Package version' |
| 22 | + required: false |
| 23 | + default: '1.0' |
| 24 | + type: string |
| 25 | + |
| 26 | +jobs: |
| 27 | + build: |
| 28 | + runs-on: ubuntu-latest |
| 29 | + permissions: |
| 30 | + contents: write |
| 31 | + steps: |
| 32 | + - name: Setup Rust + Android target |
| 33 | + run: | |
| 34 | + rustup default stable |
| 35 | + rustup target add aarch64-linux-android |
| 36 | +
|
| 37 | + - name: Setup Android NDK |
| 38 | + run: | |
| 39 | + NDK_VER="r29" |
| 40 | + curl -fsSL "https://dl.google.com/android/repository/android-ndk-${NDK_VER}-linux.zip" -o ndk.zip |
| 41 | + unzip -q ndk.zip |
| 42 | + echo "NDK_ROOT=$PWD/android-ndk-${NDK_VER}" >> $GITHUB_ENV |
| 43 | + echo "CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=$NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang" >> $GITHUB_ENV |
| 44 | +
|
| 45 | + - name: Checkout or cargo-install |
| 46 | + run: | |
| 47 | + REPO="${{ inputs.repo }}" |
| 48 | + # If it looks like a GitHub repo (org/name), clone it |
| 49 | + if echo "$REPO" | grep -q '/'; then |
| 50 | + git clone "https://github.com/${REPO}.git" src |
| 51 | + echo "BUILD_DIR=src" >> $GITHUB_ENV |
| 52 | + echo "PKG_NAME=$(basename $REPO)" >> $GITHUB_ENV |
| 53 | + else |
| 54 | + # It's a crate name — just note it for metadata |
| 55 | + echo "CRATE_NAME=$REPO" >> $GITHUB_ENV |
| 56 | + echo "BUILD_DIR=." >> $GITHUB_ENV |
| 57 | + echo "PKG_NAME=$REPO" >> $GITHUB_ENV |
| 58 | + fi |
| 59 | +
|
| 60 | + - name: Build |
| 61 | + env: |
| 62 | + CC_aarch64_linux_android: ${{ env.NDK_ROOT }}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang |
| 63 | + run: | |
| 64 | + set -e |
| 65 | + mkdir -p dist |
| 66 | + CARGO_FLAGS="--target aarch64-linux-android --release" |
| 67 | + if [ -n "${{ inputs.features }}" ]; then |
| 68 | + CARGO_FLAGS="$CARGO_FLAGS --features ${{ inputs.features }}" |
| 69 | + fi |
| 70 | +
|
| 71 | + cd "$BUILD_DIR" |
| 72 | +
|
| 73 | + if [ -n "${{ inputs.binary }}" ]; then |
| 74 | + # Build specific binary |
| 75 | + cargo build $CARGO_FLAGS --bin "${{ inputs.binary }}" |
| 76 | + cp "target/aarch64-linux-android/release/${{ inputs.binary }}" ../dist/ |
| 77 | + elif [ -f Cargo.toml ] && grep -q 'cdylib\|dylib' Cargo.toml 2>/dev/null; then |
| 78 | + # Build cdylib (shared library) |
| 79 | + cargo build $CARGO_FLAGS --lib |
| 80 | + find target/aarch64-linux-android/release -name '*.so' -exec cp {} ../dist/ \; |
| 81 | + elif [ -d src ]; then |
| 82 | + # Default: try building the default binary |
| 83 | + cargo build $CARGO_FLAGS |
| 84 | + find target/aarch64-linux-android/release -maxdepth 1 -type f -executable -exec cp {} ../dist/ \; |
| 85 | + fi |
| 86 | + cd .. |
| 87 | +
|
| 88 | + echo "=== dist/ ===" |
| 89 | + ls -lh dist/ |
| 90 | +
|
| 91 | + - name: Build .deb + push apt-repo |
| 92 | + run: | |
| 93 | + set -e |
| 94 | + BIN=$(ls dist/ | head -1) |
| 95 | + PKG="${{ env.PKG_NAME }}-aarch64" |
| 96 | + PKG="${PKG//_/-}" |
| 97 | + VER="${{ inputs.version }}" |
| 98 | +
|
| 99 | + TMP=$(mktemp -d) |
| 100 | + DEB_ROOT="$TMP/deb" |
| 101 | + BIN_DIR="$DEB_ROOT/data/data/com.termux/files/usr/bin" |
| 102 | + mkdir -p "$BIN_DIR" "$DEB_ROOT/DEBIAN" |
| 103 | + cp "dist/$BIN" "$BIN_DIR/" |
| 104 | + chmod +x "$BIN_DIR/$BIN" |
| 105 | +
|
| 106 | + SIZE=$(du -sk "$DEB_ROOT/data" 2>/dev/null | cut -f1) |
| 107 | + cat > "$DEB_ROOT/DEBIAN/control" << CTRL |
| 108 | +Package: $PKG |
| 109 | +Version: $VER |
| 110 | +Architecture: aarch64 |
| 111 | +Maintainer: ClaudeCode-Termux |
| 112 | +Installed-Size: ${SIZE:-10} |
| 113 | +Description: $PKG (auto-built from ${{ inputs.repo }}) |
| 114 | +CTRL |
| 115 | + cat "$DEB_ROOT/DEBIAN/control" |
| 116 | + |
| 117 | + DEB="${PKG}_${VER}_aarch64.deb" |
| 118 | + dpkg-deb --root-owner-group -Zxz -b "$DEB_ROOT" "dist/$DEB" |
| 119 | + ls -lh "dist/$DEB" |
| 120 | + |
| 121 | + git config --global user.name "github-actions[bot]" |
| 122 | + git config --global user.email "actions@github.com" |
| 123 | + REPO_URL="https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git" |
| 124 | + if ! git clone --depth 1 -b apt-repo "$REPO_URL" apt_repo 2>/dev/null; then |
| 125 | + git clone --depth 1 "$REPO_URL" apt_repo |
| 126 | + cd apt_repo; git checkout --orphan apt-repo; git rm -rf .; git commit --allow-empty -m init; cd .. |
| 127 | + fi |
| 128 | + cd apt_repo; git checkout apt-repo |
| 129 | + mkdir -p pool; cp "../dist/$DEB" pool/ |
| 130 | + dpkg-scanpackages --multiversion pool > Packages; gzip -9c Packages > Packages.gz |
| 131 | + git add -A |
| 132 | + if ! git diff --staged --quiet; then |
| 133 | + git commit -m "➕ $PKG v$VER"; git push origin apt-repo |
| 134 | + echo "✅ Pushed to apt-repo" |
| 135 | + else |
| 136 | + echo "⏭ Already exists" |
| 137 | + fi |
0 commit comments