13 Commits

Author SHA1 Message Date
Hermes
438d8e22b4 ci: install Githug native build prerequisites
All checks were successful
Android build / build (push) Successful in 33m18s
Android build / build (release) Successful in 27m50s
2026-09-01 17:28:19 -05:00
Hermes
553c512082 ci: route Android builds through project tooling
Some checks failed
Android build / build (push) Failing after 1m48s
2026-09-01 17:16:48 -05:00
Hermes
0bf7f6b387 fix: cross-compile bundled Android git libs with Rust
All checks were successful
Android build / build (push) Successful in 14m1s
Android build / build (release) Successful in 24m0s
2026-08-31 20:40:02 -05:00
Hermes
1ac5f0d7fa ci: build and verify bundled Android git libs
Some checks failed
Android build / build (push) Failing after 4m53s
2026-08-31 20:33:40 -05:00
Hermes
052ea8de4c ci: verify Android bundles ship native git
Some checks failed
Android build / build (push) Failing after 38s
Android build / build (release) Failing after 53s
2026-08-31 18:53:02 -05:00
Hermes
9c77cdc3a3 ci: compile bundled git for Android builds
Some checks failed
Android build / build (push) Failing after 1m13s
2026-08-31 18:51:08 -05:00
Hermes
b5fea9e010 ci: prefer github token for release asset upload
All checks were successful
Android build / build (push) Successful in 9m6s
Android build / build (release) Successful in 11m31s
2026-08-31 17:52:41 -05:00
Hermes
df07409e48 ci: broaden release asset upload token fallback
Some checks failed
Android build / build (push) Has been cancelled
2026-08-31 16:12:17 -05:00
Hermes
6604b5b94a ci: bump APK versionCode and timestamp AAB names
Some checks failed
Android build / build (push) Successful in 11m49s
Android build / build (release) Failing after 9m55s
2026-08-31 15:05:53 -05:00
Hermes
56eddb424a fix: repair AGP upgrade file corruption
All checks were successful
Android build / build (push) Successful in 7m48s
2026-08-31 13:49:47 -05:00
Hermes
98faa8b6f0 build: upgrade AGP for Android 16 support
Some checks failed
Android build / build (push) Has been cancelled
2026-08-31 13:30:52 -05:00
Hermes
ee21751e03 build: target Android 16 / API 36
All checks were successful
Android build / build (push) Successful in 17m7s
2026-08-31 12:18:29 -05:00
Hermes
0b719dcc36 ci: visible-file push trigger test
All checks were successful
Android build / build (push) Successful in 6m50s
2026-08-30 10:01:44 -05:00
7 changed files with 180 additions and 103 deletions

View File

@@ -1,7 +1,7 @@
name: Android build
permissions:
contents: read
contents: write
releases: write
on:
@@ -29,90 +29,101 @@ jobs:
distribution: temurin
java-version: '17'
- name: Install Android SDK command-line tools and packages
- name: Install native build prerequisites
shell: bash
run: |
set -euxo pipefail
export ANDROID_SDK_ROOT="$HOME/.android/sdk"
export ANDROID_HOME="$ANDROID_SDK_ROOT"
mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools"
if [ ! -x "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" ]; then
tools_url="$(curl -fsSL https://developer.android.com/studio | grep -o 'https://dl.google.com/android/repository/commandlinetools-linux-[0-9][0-9]*_latest.zip' | head -n 1)"
test -n "$tools_url"
curl -fsSL -o /tmp/commandlinetools.zip "$tools_url"
rm -rf "$ANDROID_SDK_ROOT/cmdline-tools/latest" "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools"
unzip -q /tmp/commandlinetools.zip -d "$ANDROID_SDK_ROOT/cmdline-tools"
mv "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools" "$ANDROID_SDK_ROOT/cmdline-tools/latest"
fi
export PATH="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools:$PATH"
set +o pipefail
yes | sdkmanager --licenses >/dev/null
set -o pipefail
sdkmanager \
"platform-tools" \
"platforms;android-35" \
"build-tools;35.0.0" \
"ndk;27.2.12479018" \
"cmake;3.22.1"
sudo apt-get update
sudo apt-get install -y clang make perl pkg-config file binutils
- name: Prepare optional release signing
if: github.event_name == 'release'
continue-on-error: true
- name: Install Rust toolchain
shell: bash
run: |
set -euxo pipefail
if ! command -v cargo >/dev/null 2>&1; then
curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal
fi
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.cargo/bin:$PATH"
cargo --version
rustc --version
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
- name: Run project build tooling for debug APK
if: github.event_name != 'release'
shell: bash
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
shell: bash
run: |
set -euo pipefail
missing=()
for key in ANDROID_KEYSTORE_BASE64 ANDROID_KEYSTORE_PASSWORD ANDROID_KEY_ALIAS ANDROID_KEY_PASSWORD; do
if [ -z "${!key:-}" ]; then
missing+=("$key")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
printf -v missing_csv '%s, ' "${missing[@]}"
missing_csv="${missing_csv%, }"
echo "::error::Release signing secrets missing: ${missing_csv}. Continuing with unsigned/default-signed release AAB."
exit 1
fi
mkdir -p .ci-secrets
printf '%s' "$ANDROID_KEYSTORE_BASE64" | base64 -d > .ci-secrets/release-keystore.jks
cat > keystore.properties <<EOF
storeFile=.ci-secrets/release-keystore.jks
storePassword=$ANDROID_KEYSTORE_PASSWORD
keyAlias=$ANDROID_KEY_ALIAS
keyPassword=$ANDROID_KEY_PASSWORD
EOF
- name: Make Gradle wrapper executable
run: chmod +x gradlew
- name: Write Android SDK location
shell: bash
CI_VERSION_CODE: ${{ github.run_number }}
CI_ARTIFACT_TIMESTAMP: ${{ github.run_id }}
run: |
set -euxo pipefail
printf 'sdk.dir=%s/.android/sdk\n' "$HOME" > local.properties
export PATH="$HOME/.cargo/bin:$PATH"
chmod +x ./AndroidProjectTooling.sh
bash ./AndroidProjectTooling.sh --build --no-commit
- name: Build debug APK
- name: Verify debug APK bundles native Git
if: github.event_name != 'release'
shell: bash
run: |
set -euxo pipefail
export ANDROID_SDK_ROOT="$HOME/.android/sdk"
export ANDROID_HOME="$ANDROID_SDK_ROOT"
./gradlew --no-daemon clean assembleDebug
python3 - <<'PY'
from pathlib import Path
import zipfile
apk = next(Path('app/build/outputs/apk/debug').glob('*.apk'))
with zipfile.ZipFile(apk) as zf:
names = zf.namelist()
required = {
'lib/arm64-v8a/libgit.so',
'lib/armeabi-v7a/libgit.so',
'lib/x86/libgit.so',
'lib/x86_64/libgit.so',
}
found = {name for name in names if name in required}
print('APK_NATIVE_GIT', sorted(found))
missing = sorted(required - found)
if missing:
raise SystemExit(f'Missing native Git libraries in {apk}: {missing}')
PY
- name: Build release AAB
- name: Run project build tooling for release AAB
if: github.event_name == 'release'
shell: bash
env:
CI_VERSION_CODE: ${{ github.run_number }}
CI_ARTIFACT_TIMESTAMP: ${{ github.run_id }}
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
run: |
set -euxo pipefail
export PATH="$HOME/.cargo/bin:$PATH"
chmod +x ./AndroidProjectTooling.sh
bash ./AndroidProjectTooling.sh --build-release-aab --no-commit
- name: Verify release AAB bundles native Git
if: github.event_name == 'release'
shell: bash
run: |
set -euxo pipefail
export ANDROID_SDK_ROOT="$HOME/.android/sdk"
export ANDROID_HOME="$ANDROID_SDK_ROOT"
./gradlew --no-daemon bundleRelease
python3 - <<'PY'
from pathlib import Path
import zipfile
aab = next(Path('app/build/outputs/bundle/release').glob('*.aab'))
with zipfile.ZipFile(aab) as zf:
names = zf.namelist()
required = {
'base/lib/arm64-v8a/libgit.so',
'base/lib/armeabi-v7a/libgit.so',
'base/lib/x86/libgit.so',
'base/lib/x86_64/libgit.so',
}
found = {name for name in names if name in required}
print('AAB_NATIVE_GIT', sorted(found))
missing = sorted(required - found)
if missing:
raise SystemExit(f'Missing native Git libraries in {aab}: {missing}')
PY
- name: Upload debug APK
if: github.event_name != 'release'
@@ -126,13 +137,19 @@ jobs:
if: github.event_name == 'release'
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GITHUB_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euxo pipefail
token="${GITHUB_TOKEN:-${GITEA_TOKEN:-}}"
if [ -z "$token" ]; then
echo "::error::No release upload token is available from secrets.GITEA_TOKEN or github.token"
exit 1
fi
release_id="$(python3 -c 'import json, os; print(json.load(open(os.environ["GITHUB_EVENT_PATH"], encoding="utf-8"))["release"]["id"])')"
aab="$(find app/build/outputs/bundle/release -name '*.aab' | head -n 1)"
curl --fail-with-body \
--request POST \
--header "Authorization: token ${GITEA_TOKEN}" \
--header "Authorization: token ${token}" \
--form "attachment=@${aab}" \
"${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases/${release_id}/assets?name=$(basename "$aab")"

View File

@@ -30,14 +30,17 @@ GRADLE_DIST_URL="https://services.gradle.org/distributions/gradle-8.7-bin.zip"
JDK_DIST_URL="https://api.adoptium.net/v3/binary/latest/17/ga/linux/x64/jdk/hotspot/normal/eclipse"
ANDROID_NDK_PACKAGE="ndk;27.2.12479018"
ANDROID_CMAKE_PACKAGE="cmake;3.22.1"
ANDROID_EMULATOR_SYSTEM_IMAGE="system-images;android-35;google_apis;x86_64"
ANDROID_TEST_AVD_NAME="githug_android_api35"
ANDROID_EMULATOR_SYSTEM_IMAGE="system-images;android-36;google_apis;x86_64"
ANDROID_TEST_AVD_NAME="githug_android_api36"
ANDROID_NDK_DIR="$SDK_DIR/ndk/27.2.12479018"
ANDROID_CMAKE_DIR="$SDK_DIR/cmake/3.22.1"
ANDROID_TOOLBIN="$ANDROID_NDK_DIR/toolchains/llvm/prebuilt/linux-x86_64/bin"
STATE_TTL_SECONDS=86400
HIDE_EMULATOR_WINDOW="false"
QUIET_LOG_DIR="$PROJECT_DIR/build/reports/android-project-tooling"
NO_COMMIT="false"
CI_VERSION_CODE="${CI_VERSION_CODE:-}"
CI_ARTIFACT_TIMESTAMP="${CI_ARTIFACT_TIMESTAMP:-}"
log() {
printf '\n[%s] %s\n' "tooling" "$1"
@@ -48,7 +51,7 @@ quiet_log_name() {
local arg
for arg in "$@"; do
case "$arg" in
--build|--build-release-aab|--test|--clean-test|--test-emulator|--compile-git)
--build|--build-release-aab|--test|--clean-test|--test-emulator|--compile-git|--compile-android-git)
mode="${arg#--}"
;;
esac
@@ -139,8 +142,8 @@ mark_successful_check() {
required_sdk_packages_present() {
[ -d "$SDK_DIR/platform-tools" ] \
&& [ -d "$SDK_DIR/platforms/android-35" ] \
&& [ -d "$SDK_DIR/build-tools/35.0.0" ] \
&& [ -d "$SDK_DIR/platforms/android-36" ] \
&& [ -d "$SDK_DIR/build-tools/36.0.0" ] \
&& [ -d "$ANDROID_NDK_DIR" ] \
&& [ -d "$ANDROID_CMAKE_DIR" ]
}
@@ -148,7 +151,7 @@ required_sdk_packages_present() {
required_emulator_packages_present() {
required_sdk_packages_present \
&& [ -x "$SDK_DIR/emulator/emulator" ] \
&& [ -d "$SDK_DIR/system-images/android-35/google_apis/x86_64" ]
&& [ -d "$SDK_DIR/system-images/android-36/google_apis/x86_64" ]
}
auto_commit_if_needed() {
@@ -299,6 +302,7 @@ import re
path = Path(r'''$gradle_file''')
text = path.read_text()
ci_version_code = r'''$CI_VERSION_CODE'''.strip()
version_code_match = re.search(r'versionCode\s*=\s*(\d+)', text)
version_name_match = re.search(r'versionName\s*=\s*"(\d+)\.(\d+)\.(\d+)"', text)
@@ -309,14 +313,15 @@ if not version_code_match or not version_name_match:
current_code = int(version_code_match.group(1))
major, minor, patch = map(int, version_name_match.groups())
new_code = current_code + 1
new_code = int(ci_version_code) if ci_version_code else current_code + 1
new_name = f'{major}.{minor}.{patch + 1}'
text = re.sub(r'versionCode\s*=\s*\d+', f'versionCode = {new_code}', text, count=1)
text = re.sub(r'versionName\s*=\s*"\d+\.\d+\.\d+"', f'versionName = "{new_name}"', text, count=1)
if not ci_version_code:
text = re.sub(r'versionName\s*=\s*"\d+\.\d+\.\d+"', f'versionName = "{new_name}"', text, count=1)
path.write_text(text)
print(f'Updated versionCode to {new_code} and versionName to {new_name}')
print(f'Updated versionCode to {new_code}' + (f' and versionName to {new_name}' if not ci_version_code else ''))
PY
}
@@ -352,6 +357,34 @@ upload_build_artifact_if_possible() {
bash "$UPLOAD_SCRIPT" "$artifact_path"
}
prepare_optional_release_signing() {
local required=(ANDROID_KEYSTORE_BASE64 ANDROID_KEYSTORE_PASSWORD ANDROID_KEY_ALIAS ANDROID_KEY_PASSWORD)
local missing=()
local key
for key in "${required[@]}"; do
if [ -z "${!key:-}" ]; then
missing+=("$key")
fi
done
if [ ${#missing[@]} -eq ${#required[@]} ]; then
return
fi
if [ ${#missing[@]} -gt 0 ]; then
printf 'Release signing secrets missing: %s\n' "${missing[*]}" >&2
exit 1
fi
mkdir -p "$PROJECT_DIR/.ci-secrets"
printf '%s' "$ANDROID_KEYSTORE_BASE64" | base64 -d > "$PROJECT_DIR/.ci-secrets/release-keystore.jks"
cat > "$PROJECT_DIR/keystore.properties" <<EOF_INNER
storeFile=.ci-secrets/release-keystore.jks
storePassword=$ANDROID_KEYSTORE_PASSWORD
keyAlias=$ANDROID_KEY_ALIAS
keyPassword=$ANDROID_KEY_PASSWORD
EOF_INNER
}
setup_env() {
setup_java_env
export ANDROID_HOME="$SDK_DIR"
@@ -502,10 +535,11 @@ build_host_git() {
build_android_git_for_abi() {
local abi="$1"
local cc="$2"
local rust_target="$3"
local output_dir="$ANDROID_JNI_DIR/$abi"
local output_binary="$output_dir/libgit.so"
local stamp="$output_dir/.source-fingerprint"
local fingerprint="$3:android:$abi:$cc:$ANDROID_API:githug-embedded-main"
local fingerprint="$4:android:$abi:$cc:$rust_target:$ANDROID_API:githug-embedded-main"
require_path "$ANDROID_TOOLBIN/$cc"
@@ -530,6 +564,7 @@ build_android_git_for_abi() {
AR=llvm-ar \
RANLIB=llvm-ranlib \
STRIP=llvm-strip \
RUST_TARGETS="$rust_target" \
"${make_args[@]}" \
git
@@ -554,10 +589,10 @@ build_android_git() {
local fingerprint
fingerprint="$(git_source_fingerprint)"
build_android_git_for_abi "arm64-v8a" "aarch64-linux-android${ANDROID_API}-clang" "$fingerprint"
build_android_git_for_abi "armeabi-v7a" "armv7a-linux-androideabi${ANDROID_API}-clang" "$fingerprint"
build_android_git_for_abi "x86" "i686-linux-android${ANDROID_API}-clang" "$fingerprint"
build_android_git_for_abi "x86_64" "x86_64-linux-android${ANDROID_API}-clang" "$fingerprint"
build_android_git_for_abi "arm64-v8a" "aarch64-linux-android${ANDROID_API}-clang" "aarch64-linux-android" "$fingerprint"
build_android_git_for_abi "armeabi-v7a" "armv7a-linux-androideabi${ANDROID_API}-clang" "armv7-linux-androideabi" "$fingerprint"
build_android_git_for_abi "x86" "i686-linux-android${ANDROID_API}-clang" "i686-linux-android" "$fingerprint"
build_android_git_for_abi "x86_64" "x86_64-linux-android${ANDROID_API}-clang" "x86_64-linux-android" "$fingerprint"
}
build_all_git_targets() {
@@ -598,8 +633,8 @@ ensure_sdk_packages() {
log "Installing required Android SDK packages"
"$CMDLINE_TOOLS_LATEST_DIR/bin/sdkmanager" --sdk_root="$SDK_DIR" \
"platform-tools" \
"platforms;android-35" \
"build-tools;35.0.0" \
"platforms;android-36" \
"build-tools;36.0.0" \
"$ANDROID_NDK_PACKAGE" \
"$ANDROID_CMAKE_PACKAGE"
@@ -629,8 +664,8 @@ ensure_emulator_sdk_packages() {
log "Installing Android emulator SDK packages"
"$CMDLINE_TOOLS_LATEST_DIR/bin/sdkmanager" --sdk_root="$SDK_DIR" \
"platform-tools" \
"platforms;android-35" \
"build-tools;35.0.0" \
"platforms;android-36" \
"build-tools;36.0.0" \
"$ANDROID_NDK_PACKAGE" \
"$ANDROID_CMAKE_PACKAGE" \
"emulator" \
@@ -786,6 +821,11 @@ maybe_run_operation() {
build_all_git_targets
return
;;
--compile-android-git)
setup_env
build_android_git
return
;;
*)
return
;;
@@ -803,7 +843,11 @@ maybe_run_operation() {
artifact_target="$PROJECT_DIR/app/build/outputs/apk/debug/githug-android-debug-v${version_code}.apk"
;;
--build-release-aab)
artifact_target="$PROJECT_DIR/app/build/outputs/bundle/release/githug-android-release-v${version_code}.aab"
if [ -n "$CI_ARTIFACT_TIMESTAMP" ]; then
artifact_target="$PROJECT_DIR/app/build/outputs/bundle/release/Githug-Android-${CI_ARTIFACT_TIMESTAMP}-release.aab"
else
artifact_target="$PROJECT_DIR/app/build/outputs/bundle/release/githug-android-release-v${version_code}.aab"
fi
;;
esac
fi
@@ -811,6 +855,9 @@ maybe_run_operation() {
build_host_git
export GITHUG_TEST_GIT_BINARY="$HOST_GIT_BINARY"
fi
if [ "$mode" = "--build-release-aab" ]; then
prepare_optional_release_signing
fi
if [ "$should_compile_android_git" = "true" ]; then
build_android_git
fi
@@ -838,7 +885,7 @@ maybe_run_operation() {
log "Expected build output not found for rename: ${artifact_source#$PROJECT_DIR/}"
fi
if [ "$should_auto_commit" = "true" ]; then
if [ "$should_auto_commit" = "true" ] && [ "$NO_COMMIT" != "true" ]; then
auto_commit_if_needed
fi
@@ -850,7 +897,7 @@ maybe_run_operation() {
print_usage() {
cat <<EOF_USAGE
Usage: bash ./AndroidProjectTooling.sh [--quiet] [--build | --build-release-aab | --test | --clean-test | --test-emulator [--hide-emulator-window] | --compile-git]
Usage: bash ./AndroidProjectTooling.sh [--quiet] [--build | --build-release-aab | --test | --clean-test | --test-emulator [--hide-emulator-window] | --compile-git | --compile-android-git]
--build Set up the environment and build the debug APK
--build-release-aab Set up the environment and build a release Android App Bundle (AAB)
@@ -859,6 +906,7 @@ Usage: bash ./AndroidProjectTooling.sh [--quiet] [--build | --build-release-aab
--test-emulator Set up a visible Android emulator and run debug instrumentation tests on it
--hide-emulator-window Run --test-emulator with the emulator window hidden
--compile-git Compile Git for the development host and all Android target ABIs
--compile-android-git Compile Git only for the Android target ABIs used by the app
--quiet Write full output to build/reports/android-project-tooling/ and print only a concise result
EOF_USAGE
}
@@ -872,7 +920,7 @@ validate_args() {
shift || true
case "$mode" in
""|--build|--build-release-aab|--test|--clean-test|--test-emulator|--compile-git)
""|--build|--build-release-aab|--test|--clean-test|--test-emulator|--compile-git|--compile-android-git)
;;
*)
echo "Unknown argument: $mode" >&2
@@ -885,6 +933,9 @@ validate_args() {
case "$1" in
--quiet)
;;
--no-commit)
NO_COMMIT="true"
;;
--hide-emulator-window)
if [ "$mode" != "--test-emulator" ]; then
echo "--hide-emulator-window can only be used with --test-emulator" >&2
@@ -913,11 +964,18 @@ main() {
require_tool git
require_tool perl
require_tool make
require_tool clang
require_tool pkg-config
require_tool readelf
require_tool file
local mode="${1:-}"
if [ "$mode" = "--build" ] || [ "$mode" = "--build-release-aab" ] || [ "$mode" = "--test" ] || [ "$mode" = "--clean-test" ] || [ "$mode" = "--compile-git" ] || [ "$mode" = "--test-emulator" ] || [ "$mode" = "--compile-android-git" ]; then
require_tool cargo
fi
if [ "$mode" = "--build" ] || [ "$mode" = "--build-release-aab" ] || [ "$mode" = "--test" ] || [ "$mode" = "--clean-test" ] || [ "$mode" = "--compile-git" ] || [ "$mode" = "--test-emulator" ]; then
require_tool clang
fi
ensure_dir "$TMP_DIR"
ensure_dir "$SDK_DIR"
ensure_dir "$GRADLE_USER_HOME_DIR"
@@ -936,6 +994,7 @@ main() {
log "NDK dir: $ANDROID_NDK_DIR"
log "CMake dir: $ANDROID_CMAKE_DIR"
log "To compile Git for host and Android ABIs: bash ./AndroidProjectTooling.sh --compile-git"
log "To compile Git only for Android ABIs: bash ./AndroidProjectTooling.sh --compile-android-git"
log "To build without a background Gradle daemon: ./gradlew --no-daemon assembleDebug"
log "To set up and build in one step: bash ./AndroidProjectTooling.sh --build"
log "To set up and build a release AAB in one step: bash ./AndroidProjectTooling.sh --build-release-aab"

View File

@@ -0,0 +1 @@
trigger test 2026-08-30T10:01:44-05:00

View File

@@ -21,7 +21,7 @@ The UI supports a terminal-centered workflow with optional inspection panes:
## Development Workflow
Development tasks should be run through the project tooling script. It provisions the local toolchain, keeps paths project-relative, and runs Gradle with the project configuration expected by this repository.
Development tasks should be run through the project tooling script. Local developers and Gitea Actions both use this same script so the compile path stays aligned.
While implementing changes, keep `commit-summary.txt` updated as you go. This file is intentionally ignored by git and excluded from automatic commits so it can be edited manually too; the build tooling uses it as the commit message when it exists and is non-empty.
@@ -50,8 +50,8 @@ Available commands:
| `bash ./AndroidProjectTooling.sh --clean-test` | Compile host Git, clean Gradle outputs, set `GITHUG_TEST_GIT_BINARY`, and run JVM unit tests. | Fresh test reports under `app/build/reports/` |
| `bash ./AndroidProjectTooling.sh --test-emulator` | Install emulator packages if needed, create/start the visible project test AVD, compile Android Git, and run debug instrumentation tests. | Instrumentation reports under `app/build/reports/androidTests/` |
| `bash ./AndroidProjectTooling.sh --test-emulator --hide-emulator-window` | Run the same emulator instrumentation tests without showing the emulator window. | Instrumentation reports under `app/build/reports/androidTests/` |
| `bash ./AndroidProjectTooling.sh --build` | Build the debug APK. | `app/build/outputs/apk/debug/githug-android-debug-v<versionCode>.apk` |
| `bash ./AndroidProjectTooling.sh --build-release-aab` | Build the release Android App Bundle. | `app/build/outputs/bundle/release/githug-android-release-v<versionCode>.aab` |
| `bash ./AndroidProjectTooling.sh --build` | Build the debug APK. Add `--no-commit` to skip the post-build commit. | `app/build/outputs/apk/debug/githug-android-debug-v<versionCode>.apk` |
| `bash ./AndroidProjectTooling.sh --build-release-aab` | Build the release Android App Bundle. Add `--no-commit` to skip the post-build commit. | `app/build/outputs/bundle/release/githug-android-release-v<versionCode>.aab` or `Githug-Android-<timestamp>-release.aab` when `CI_ARTIFACT_TIMESTAMP` is set |
| `bash ./AndroidProjectTooling.sh --compile-git` | Compile Git for the development host and all Android target ABIs. | Host and Android `libgit.so` binaries |
Add `--quiet` before any tooling command when running through an AI or other log-sensitive automation:
@@ -120,13 +120,13 @@ If all required components were verified successfully, the script will skip SDK
When `--build` or `--build-release-aab` is used, the script also:
- increments `versionCode` by 1
- increments the patch component of `versionName`, for example `0.1.0` to `0.1.1`
- increments `versionCode` by 1 for local builds, or honors `CI_VERSION_CODE` when provided
- increments the patch component of `versionName` for local builds
- compiles the generated Android `libgit.so` binaries when they are missing or stale
- bundles full Git manpage source files from Git's `Documentation/` directory into app assets
- renames the generated artifact to a `githug-android-*` filename that includes the post-bump `versionCode`
- renames the generated artifact to a `githug-android-*` filename that includes the post-bump `versionCode`, or to `Githug-Android-<timestamp>-release.aab` when `CI_ARTIFACT_TIMESTAMP` is set for CI release builds
- uploads the renamed APK/AAB with local `./upload2DL.sh` when that script exists
- attempts to create a git commit after a successful build if there are source changes
- attempts to create a git commit after a successful build unless `--no-commit` is passed
The build commands currently run these Gradle tasks:

View File

@@ -19,13 +19,13 @@ plugins {
android {
namespace = "solutions.tretter.githugandroid"
compileSdk = 35
compileSdk = 36
ndkVersion = "27.2.12479018"
defaultConfig {
applicationId = "solutions.tretter.githugandroid"
minSdk = 26
targetSdk = 35
targetSdk = 36
versionCode = 184
versionName = "0.1.183"

View File

@@ -1,4 +1,4 @@
plugins {
id("com.android.application") version "8.6.1" apply false
id("com.android.application") version "8.10.0" apply false
id("org.jetbrains.kotlin.android") version "1.9.24" apply false
}

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME