Skip to content

fix(ci): resolve syntax errors and unclosed if blocks in workflows #6

fix(ci): resolve syntax errors and unclosed if blocks in workflows

fix(ci): resolve syntax errors and unclosed if blocks in workflows #6

name: Feature Test Suite
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
jobs:
feature-tests:
name: Android ${{ matrix.android_version }} feature tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- android_version: "13"
api_level: "33"
patcher_script: scripts/patcher_a13.sh
source_base: Sources/android13
- android_version: "14"
api_level: "34"
patcher_script: scripts/patcher_a14.sh
source_base: Sources/android14
- android_version: "15"
api_level: "35"
patcher_script: scripts/patcher_a15.sh
source_base: Sources/android15
- android_version: "16"
api_level: "36"
patcher_script: scripts/patcher_a16.sh
source_base: Sources/android16
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Run feature tests
id: run_feature_tests
shell: bash
run: |
set -euo pipefail
SOURCE_BASE="${{ matrix.source_base }}"
PATCHER="./${{ matrix.patcher_script }}"
API_LEVEL="${{ matrix.api_level }}"
DEVICE_NAME="CI Android ${{ matrix.android_version }}"
DEVICE_CODENAME="ci-a${{ matrix.android_version }}"
VERSION_NAME="ci-${GITHUB_RUN_NUMBER}-${GITHUB_RUN_ATTEMPT}"
chmod +x "$PATCHER"
find_source_jar() {
local base="$1"
local relative="$2"
if [ ! -d "$base" ]; then
echo ""
return 0
fi
# Support both layouts:
# - Sources/android14/global/framework.jar
# - Sources/.../framework/framework.jar
find "$base" -type f \( -name "${relative}.jar" -o -path "*/${relative}/${relative}.jar" \) 2>/dev/null | sort | head -n1
}
FRAMEWORK_SRC="$(find_source_jar "$SOURCE_BASE" framework)"
SERVICES_SRC="$(find_source_jar "$SOURCE_BASE" services)"
MIUI_SERVICES_SRC="$(find_source_jar "$SOURCE_BASE" miui-services)"
MIUI_FRAMEWORK_SRC="$(find_source_jar "$SOURCE_BASE" miui-framework)"
if [ -z "$FRAMEWORK_SRC" ] && [ -z "$SERVICES_SRC" ] && [ -z "$MIUI_SERVICES_SRC" ] && [ -z "$MIUI_FRAMEWORK_SRC" ]; then
echo "No source JARs found under ${SOURCE_BASE}; skipping Android ${{ matrix.android_version }} tests."
exit 0
fi
has_framework=0
has_services=0
has_miui_services=0
has_miui_framework=0
[ -n "$FRAMEWORK_SRC" ] && has_framework=1
[ -n "$SERVICES_SRC" ] && has_services=1
[ -n "$MIUI_SERVICES_SRC" ] && has_miui_services=1
[ -n "$MIUI_FRAMEWORK_SRC" ] && has_miui_framework=1
echo "Detected source jars for Android ${{ matrix.android_version }}:"
echo " framework: ${has_framework}"
echo " services: ${has_services}"
echo " miui-services: ${has_miui_services}"
echo " miui-framework: ${has_miui_framework}"
case "${{ matrix.android_version }}" in
13|14)
FEATURES=(
"--disable-signature-verification"
"--kaorios-toolbox"
"--add-gboard"
)
;;
15|16)
FEATURES=(
"--disable-signature-verification"
"--cn-notification-fix"
"--disable-secure-flag"
"--kaorios-toolbox"
"--add-gboard"
)
;;
*)
echo "Unsupported Android version in matrix: ${{ matrix.android_version }}"
exit 1
;;
esac
RESULTS_ROOT="test-results/android${{ matrix.android_version }}"
mkdir -p "$RESULTS_ROOT"
feature_is_runnable() {
local feature="$1"
case "$feature" in
--disable-signature-verification)
[ $has_framework -eq 1 ] || [ $has_services -eq 1 ] || [ $has_miui_services -eq 1 ]
;;
--cn-notification-fix)
[ $has_miui_services -eq 1 ]
;;
--disable-secure-flag)
[ $has_services -eq 1 ] || [ $has_miui_services -eq 1 ]
;;
--kaorios-toolbox)
[ $has_framework -eq 1 ]
;;
--add-gboard)
[ $has_miui_services -eq 1 ] || [ $has_miui_framework -eq 1 ]
;;
*)
return 1
;;
esac
}
build_feature_jar_flags() {
local feature="$1"
FEATURE_JAR_FLAGS=()
case "$feature" in
--disable-signature-verification)
[ $has_framework -eq 1 ] && FEATURE_JAR_FLAGS+=(--framework)
[ $has_services -eq 1 ] && FEATURE_JAR_FLAGS+=(--services)
[ $has_miui_services -eq 1 ] && FEATURE_JAR_FLAGS+=(--miui-services)
;;
--cn-notification-fix)
[ $has_miui_services -eq 1 ] && FEATURE_JAR_FLAGS+=(--miui-services)
;;
--disable-secure-flag)
[ $has_services -eq 1 ] && FEATURE_JAR_FLAGS+=(--services)
[ $has_miui_services -eq 1 ] && FEATURE_JAR_FLAGS+=(--miui-services)
;;
--kaorios-toolbox)
[ $has_framework -eq 1 ] && FEATURE_JAR_FLAGS+=(--framework)
;;
--add-gboard)
[ $has_miui_services -eq 1 ] && FEATURE_JAR_FLAGS+=(--miui-services)
[ $has_miui_framework -eq 1 ] && FEATURE_JAR_FLAGS+=(--miui-framework)
;;
esac
}
failures=0
tests_requested=${#FEATURES[@]}
tests_executed=0
tests_skipped=0
for feature in "${FEATURES[@]}"; do
case_name="${feature#--}"
case_dir="${RESULTS_ROOT}/${case_name}"
mkdir -p "$case_dir"
if ! feature_is_runnable "$feature"; then
echo "SKIPPED: ${feature} (required source jars unavailable)"
echo "Required source jars unavailable for ${feature}" > "${case_dir}/skip.txt"
tests_skipped=$((tests_skipped + 1))
continue
fi
rm -rf backup framework_decompile services_decompile miui-services_decompile miui-framework_decompile
rm -f framework.jar services.jar miui-services.jar miui-framework.jar
rm -f framework_patched.jar services_patched.jar miui-services_patched.jar miui-framework_patched.jar
rm -f Framework-Patcher-*.zip
[ $has_framework -eq 1 ] && cp "$FRAMEWORK_SRC" framework.jar
[ $has_services -eq 1 ] && cp "$SERVICES_SRC" services.jar
[ $has_miui_services -eq 1 ] && cp "$MIUI_SERVICES_SRC" miui-services.jar
[ $has_miui_framework -eq 1 ] && cp "$MIUI_FRAMEWORK_SRC" miui-framework.jar
build_feature_jar_flags "$feature"
if [ ${#FEATURE_JAR_FLAGS[@]} -eq 0 ]; then
echo "SKIPPED: ${feature} (no applicable jars available)"
echo "No applicable jars available for ${feature}" > "${case_dir}/skip.txt"
tests_skipped=$((tests_skipped + 1))
continue
fi
tests_executed=$((tests_executed + 1))
echo "============================================================"
echo "Android ${{ matrix.android_version }} | Running feature: ${feature}"
echo "Using JAR flags: ${FEATURE_JAR_FLAGS[*]}"
echo "============================================================"
set +e
bash "$PATCHER" \
"$API_LEVEL" \
"$DEVICE_CODENAME" \
"${VERSION_NAME}-${case_name}" \
"${FEATURE_JAR_FLAGS[@]}" \
"$feature" \
2>&1 | tee "${case_dir}/run.log"
cmd_status=${PIPESTATUS[0]}
set -e
if [ "$cmd_status" -ne 0 ]; then
echo "FAILED: ${feature} (exit ${cmd_status})"
failures=$((failures + 1))
continue
fi
module_zip="$(ls Framework-Patcher-*.zip 2>/dev/null | head -n1 || true)"
if [ -z "$module_zip" ]; then
echo "FAILED: ${feature} (module zip not created)"
failures=$((failures + 1))
continue
fi
cp "$module_zip" "${case_dir}/Framework-Patcher-android${{ matrix.android_version }}-${case_name}.zip"
for output_jar in framework_patched.jar services_patched.jar miui-services_patched.jar miui-framework_patched.jar; do
if [ -f "$output_jar" ]; then
cp "$output_jar" "${case_dir}/"
fi
done
echo "PASSED: ${feature}"
done
echo "tests_requested=${tests_requested}" >> "$GITHUB_OUTPUT"
echo "tests_executed=${tests_executed}" >> "$GITHUB_OUTPUT"
echo "tests_skipped=${tests_skipped}" >> "$GITHUB_OUTPUT"
echo "failures=${failures}" >> "$GITHUB_OUTPUT"
if [ "$failures" -gt 0 ]; then
echo "Feature test suite failed (${failures}/${tests_executed} executed failed, ${tests_skipped} skipped)."
exit 1
fi
if [ "$tests_executed" -eq 0 ]; then
echo "No runnable feature tests for Android ${{ matrix.android_version }} (all ${tests_requested} skipped due to missing sources)."
exit 0
fi
passed=$((tests_executed - failures))
echo "Feature test suite completed successfully (${passed}/${tests_executed} executed passed, ${tests_skipped} skipped)."
- name: Upload patched JAR artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: android${{ matrix.android_version }}-feature-test-jars-${{ github.run_id }}
if-no-files-found: warn
path: |
test-results/android${{ matrix.android_version }}/**/*_patched.jar
retention-days: 7
- name: Upload module ZIP artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: android${{ matrix.android_version }}-feature-test-modules-${{ github.run_id }}
if-no-files-found: warn
path: |
test-results/android${{ matrix.android_version }}/**/Framework-Patcher-android${{ matrix.android_version }}-*.zip
retention-days: 7
# Completion job to provide a static status check name for branch protection rules
check:
name: Feature Test Suite
needs: feature-tests
runs-on: ubuntu-latest
if: always()
steps:
- name: All tests passed
if: ${{ !(contains(needs.feature-tests.result, 'failure')) && !(contains(needs.feature-tests.result, 'cancelled')) }}
run: exit 0
- name: Tests failed
if: ${{ contains(needs.feature-tests.result, 'failure') || contains(needs.feature-tests.result, 'cancelled') }}
run: exit 1