6 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
3 changed files with 159 additions and 124 deletions

View File

@@ -29,125 +29,101 @@ jobs:
distribution: temurin distribution: temurin
java-version: '17' java-version: '17'
- name: Install Android SDK command-line tools and packages - name: Install native build prerequisites
shell: bash shell: bash
run: | run: |
set -euxo pipefail set -euxo pipefail
export ANDROID_SDK_ROOT="$HOME/.android/sdk" sudo apt-get update
export ANDROID_HOME="$ANDROID_SDK_ROOT" sudo apt-get install -y clang make perl pkg-config file binutils
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-36" \
"build-tools;36.0.0" \
"ndk;27.2.12479018" \
"cmake;3.22.1"
- name: Prepare optional release signing - name: Install Rust toolchain
if: github.event_name == 'release' shell: bash
continue-on-error: true 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: env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} CI_VERSION_CODE: ${{ github.run_number }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} CI_ARTIFACT_TIMESTAMP: ${{ github.run_id }}
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
run: | run: |
set -euxo pipefail 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: Prepare CI build metadata - name: Verify debug APK bundles native Git
id: build_meta
shell: bash
run: |
set -euxo pipefail
timestamp_utc="$(date -u +%Y%m%d-%H%M%S)"
version_code="$(date -u +%s)"
project_name="$(basename "$GITHUB_REPOSITORY")"
python3 - "$version_code" <<'PY'
from pathlib import Path
import re, sys
path = Path('app/build.gradle.kts')
text = path.read_text(encoding='utf-8')
new_text, count = re.subn(r'(\bversionCode\s*=\s*)\d+', rf'\g<1>{sys.argv[1]}', text, count=1)
if count != 1:
raise SystemExit('versionCode not found in app/build.gradle.kts')
path.write_text(new_text, encoding='utf-8')
PY
echo "Using CI versionCode: $version_code"
echo "project_name=$project_name" >> "$GITHUB_OUTPUT"
echo "timestamp_utc=$timestamp_utc" >> "$GITHUB_OUTPUT"
echo "version_code=$version_code" >> "$GITHUB_OUTPUT"
- name: Build debug APK
if: github.event_name != 'release' if: github.event_name != 'release'
shell: bash shell: bash
run: | run: |
set -euxo pipefail set -euxo pipefail
export ANDROID_SDK_ROOT="$HOME/.android/sdk" python3 - <<'PY'
export ANDROID_HOME="$ANDROID_SDK_ROOT" from pathlib import Path
./gradlew --no-daemon clean assembleDebug 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' if: github.event_name == 'release'
shell: bash shell: bash
run: | run: |
set -euxo pipefail set -euxo pipefail
export ANDROID_SDK_ROOT="$HOME/.android/sdk" python3 - <<'PY'
export ANDROID_HOME="$ANDROID_SDK_ROOT" from pathlib import Path
./gradlew --no-daemon bundleRelease import zipfile
aab = next(Path('app/build/outputs/bundle/release').glob('*.aab'))
- name: Rename release AAB for upload with zipfile.ZipFile(aab) as zf:
if: github.event_name == 'release' names = zf.namelist()
id: release_aab required = {
shell: bash 'base/lib/arm64-v8a/libgit.so',
run: | 'base/lib/armeabi-v7a/libgit.so',
set -euxo pipefail 'base/lib/x86/libgit.so',
aab="$(find app/build/outputs/bundle/release -name '*.aab' | head -n 1)" 'base/lib/x86_64/libgit.so',
renamed="app/build/outputs/bundle/release/${{ steps.build_meta.outputs.project_name }}-${{ steps.build_meta.outputs.timestamp_utc }}-release.aab" }
mv -f "$aab" "$renamed" found = {name for name in names if name in required}
echo "Renamed release AAB to $(basename "$renamed")" print('AAB_NATIVE_GIT', sorted(found))
echo "path=$renamed" >> "$GITHUB_OUTPUT" missing = sorted(required - found)
if missing:
raise SystemExit(f'Missing native Git libraries in {aab}: {missing}')
PY
- name: Upload debug APK - name: Upload debug APK
if: github.event_name != 'release' if: github.event_name != 'release'
@@ -171,7 +147,7 @@ jobs:
exit 1 exit 1
fi fi
release_id="$(python3 -c 'import json, os; print(json.load(open(os.environ["GITHUB_EVENT_PATH"], encoding="utf-8"))["release"]["id"])')" release_id="$(python3 -c 'import json, os; print(json.load(open(os.environ["GITHUB_EVENT_PATH"], encoding="utf-8"))["release"]["id"])')"
aab="${{ steps.release_aab.outputs.path }}" aab="$(find app/build/outputs/bundle/release -name '*.aab' | head -n 1)"
curl --fail-with-body \ curl --fail-with-body \
--request POST \ --request POST \
--header "Authorization: token ${token}" \ --header "Authorization: token ${token}" \

View File

@@ -38,6 +38,9 @@ ANDROID_TOOLBIN="$ANDROID_NDK_DIR/toolchains/llvm/prebuilt/linux-x86_64/bin"
STATE_TTL_SECONDS=86400 STATE_TTL_SECONDS=86400
HIDE_EMULATOR_WINDOW="false" HIDE_EMULATOR_WINDOW="false"
QUIET_LOG_DIR="$PROJECT_DIR/build/reports/android-project-tooling" 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() { log() {
printf '\n[%s] %s\n' "tooling" "$1" printf '\n[%s] %s\n' "tooling" "$1"
@@ -48,7 +51,7 @@ quiet_log_name() {
local arg local arg
for arg in "$@"; do for arg in "$@"; do
case "$arg" in 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#--}" mode="${arg#--}"
;; ;;
esac esac
@@ -299,6 +302,7 @@ import re
path = Path(r'''$gradle_file''') path = Path(r'''$gradle_file''')
text = path.read_text() text = path.read_text()
ci_version_code = r'''$CI_VERSION_CODE'''.strip()
version_code_match = re.search(r'versionCode\s*=\s*(\d+)', text) version_code_match = re.search(r'versionCode\s*=\s*(\d+)', text)
version_name_match = re.search(r'versionName\s*=\s*"(\d+)\.(\d+)\.(\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)) current_code = int(version_code_match.group(1))
major, minor, patch = map(int, version_name_match.groups()) 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}' 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'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) 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 PY
} }
@@ -352,6 +357,34 @@ upload_build_artifact_if_possible() {
bash "$UPLOAD_SCRIPT" "$artifact_path" 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_env() {
setup_java_env setup_java_env
export ANDROID_HOME="$SDK_DIR" export ANDROID_HOME="$SDK_DIR"
@@ -502,10 +535,11 @@ build_host_git() {
build_android_git_for_abi() { build_android_git_for_abi() {
local abi="$1" local abi="$1"
local cc="$2" local cc="$2"
local rust_target="$3"
local output_dir="$ANDROID_JNI_DIR/$abi" local output_dir="$ANDROID_JNI_DIR/$abi"
local output_binary="$output_dir/libgit.so" local output_binary="$output_dir/libgit.so"
local stamp="$output_dir/.source-fingerprint" 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" require_path "$ANDROID_TOOLBIN/$cc"
@@ -530,6 +564,7 @@ build_android_git_for_abi() {
AR=llvm-ar \ AR=llvm-ar \
RANLIB=llvm-ranlib \ RANLIB=llvm-ranlib \
STRIP=llvm-strip \ STRIP=llvm-strip \
RUST_TARGETS="$rust_target" \
"${make_args[@]}" \ "${make_args[@]}" \
git git
@@ -554,10 +589,10 @@ build_android_git() {
local fingerprint local fingerprint
fingerprint="$(git_source_fingerprint)" fingerprint="$(git_source_fingerprint)"
build_android_git_for_abi "arm64-v8a" "aarch64-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" "$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" "$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" "$fingerprint" build_android_git_for_abi "x86_64" "x86_64-linux-android${ANDROID_API}-clang" "x86_64-linux-android" "$fingerprint"
} }
build_all_git_targets() { build_all_git_targets() {
@@ -786,6 +821,11 @@ maybe_run_operation() {
build_all_git_targets build_all_git_targets
return return
;; ;;
--compile-android-git)
setup_env
build_android_git
return
;;
*) *)
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" artifact_target="$PROJECT_DIR/app/build/outputs/apk/debug/githug-android-debug-v${version_code}.apk"
;; ;;
--build-release-aab) --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 esac
fi fi
@@ -811,6 +855,9 @@ maybe_run_operation() {
build_host_git build_host_git
export GITHUG_TEST_GIT_BINARY="$HOST_GIT_BINARY" export GITHUG_TEST_GIT_BINARY="$HOST_GIT_BINARY"
fi fi
if [ "$mode" = "--build-release-aab" ]; then
prepare_optional_release_signing
fi
if [ "$should_compile_android_git" = "true" ]; then if [ "$should_compile_android_git" = "true" ]; then
build_android_git build_android_git
fi fi
@@ -838,7 +885,7 @@ maybe_run_operation() {
log "Expected build output not found for rename: ${artifact_source#$PROJECT_DIR/}" log "Expected build output not found for rename: ${artifact_source#$PROJECT_DIR/}"
fi fi
if [ "$should_auto_commit" = "true" ]; then if [ "$should_auto_commit" = "true" ] && [ "$NO_COMMIT" != "true" ]; then
auto_commit_if_needed auto_commit_if_needed
fi fi
@@ -850,7 +897,7 @@ maybe_run_operation() {
print_usage() { print_usage() {
cat <<EOF_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 Set up the environment and build the debug APK
--build-release-aab Set up the environment and build a release Android App Bundle (AAB) --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 --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 --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-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 --quiet Write full output to build/reports/android-project-tooling/ and print only a concise result
EOF_USAGE EOF_USAGE
} }
@@ -872,7 +920,7 @@ validate_args() {
shift || true shift || true
case "$mode" in 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 echo "Unknown argument: $mode" >&2
@@ -885,6 +933,9 @@ validate_args() {
case "$1" in case "$1" in
--quiet) --quiet)
;; ;;
--no-commit)
NO_COMMIT="true"
;;
--hide-emulator-window) --hide-emulator-window)
if [ "$mode" != "--test-emulator" ]; then if [ "$mode" != "--test-emulator" ]; then
echo "--hide-emulator-window can only be used with --test-emulator" >&2 echo "--hide-emulator-window can only be used with --test-emulator" >&2
@@ -913,11 +964,18 @@ main() {
require_tool git require_tool git
require_tool perl require_tool perl
require_tool make require_tool make
require_tool clang
require_tool pkg-config require_tool pkg-config
require_tool readelf require_tool readelf
require_tool file 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 "$TMP_DIR"
ensure_dir "$SDK_DIR" ensure_dir "$SDK_DIR"
ensure_dir "$GRADLE_USER_HOME_DIR" ensure_dir "$GRADLE_USER_HOME_DIR"
@@ -936,6 +994,7 @@ main() {
log "NDK dir: $ANDROID_NDK_DIR" log "NDK dir: $ANDROID_NDK_DIR"
log "CMake dir: $ANDROID_CMAKE_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 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 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 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" log "To set up and build a release AAB in one step: bash ./AndroidProjectTooling.sh --build-release-aab"

View File

@@ -21,7 +21,7 @@ The UI supports a terminal-centered workflow with optional inspection panes:
## Development Workflow ## 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. 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 --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` | 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 --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` | 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. | `app/build/outputs/bundle/release/githug-android-release-v<versionCode>.aab` | | `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 | | `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: 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: When `--build` or `--build-release-aab` is used, the script also:
- increments `versionCode` by 1 - increments `versionCode` by 1 for local builds, or honors `CI_VERSION_CODE` when provided
- increments the patch component of `versionName`, for example `0.1.0` to `0.1.1` - increments the patch component of `versionName` for local builds
- compiles the generated Android `libgit.so` binaries when they are missing or stale - 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 - 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 - 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: The build commands currently run these Gradle tasks: