mirror of
https://github.com/uutils/coreutils
synced 2024-10-15 12:24:09 +00:00
add Android to CICD
This commit is contained in:
parent
1f025c19af
commit
4caeb2ff1d
55
.github/workflows/CICD.yml
vendored
55
.github/workflows/CICD.yml
vendored
|
@ -844,6 +844,61 @@ jobs:
|
||||||
n_fails=$(echo "$output" | grep "^FAIL:\s" | wc --lines)
|
n_fails=$(echo "$output" | grep "^FAIL:\s" | wc --lines)
|
||||||
if [ $n_fails -gt 0 ] ; then echo "::warning ::${n_fails}+ test failures" ; fi
|
if [ $n_fails -gt 0 ] ; then echo "::warning ::${n_fails}+ test failures" ; fi
|
||||||
|
|
||||||
|
test_android:
|
||||||
|
name: Test Android builds
|
||||||
|
needs: [ min_version, deps ]
|
||||||
|
runs-on: macos-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
api-level: [28]
|
||||||
|
target: [default]
|
||||||
|
arch: [x86] # , arm64-v8a
|
||||||
|
env:
|
||||||
|
TERMUX: v0.118.0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: AVD cache
|
||||||
|
uses: actions/cache@v2
|
||||||
|
id: avd-cache
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.android/avd/*
|
||||||
|
~/.android/avd/*/snapshots/*
|
||||||
|
~/.android/adb*
|
||||||
|
key: avd-${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }}
|
||||||
|
- name: Create and cache emulator image
|
||||||
|
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||||
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
|
with:
|
||||||
|
api-level: ${{ matrix.api-level }}
|
||||||
|
target: ${{ matrix.target }}
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
ram-size: 2048M
|
||||||
|
disk-size: 5120M
|
||||||
|
force-avd-creation: true
|
||||||
|
emulator-options: -no-snapshot-load -noaudio -no-boot-anim -camera-back none
|
||||||
|
script: |
|
||||||
|
wget https://github.com/termux/termux-app/releases/download/${{ env.TERMUX }}/termux-app_${{ env.TERMUX }}+github-debug_${{ matrix.arch }}.apk
|
||||||
|
util/android-commands.sh snapshot termux-app_${{ env.TERMUX }}+github-debug_${{ matrix.arch }}.apk
|
||||||
|
adb -s emulator-5554 emu avd snapshot save ${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }}
|
||||||
|
echo "Emulator image created."
|
||||||
|
pkill -9 qemu-system-x86_64
|
||||||
|
- name: Build and Test on Android
|
||||||
|
uses: reactivecircus/android-emulator-runner@v2
|
||||||
|
with:
|
||||||
|
api-level: ${{ matrix.api-level }}
|
||||||
|
target: ${{ matrix.target }}
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
ram-size: 2048M
|
||||||
|
disk-size: 5120M
|
||||||
|
force-avd-creation: false
|
||||||
|
emulator-options: -no-snapshot-save -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -snapshot ${{ matrix.api-level }}-${{ matrix.arch }}+termux-${{ env.TERMUX }}
|
||||||
|
script: |
|
||||||
|
util/android-commands.sh sync
|
||||||
|
util/android-commands.sh build
|
||||||
|
util/android-commands.sh tests
|
||||||
|
|
||||||
test_freebsd:
|
test_freebsd:
|
||||||
name: Tests/FreeBSD test suite
|
name: Tests/FreeBSD test suite
|
||||||
needs: [ min_version, deps ]
|
needs: [ min_version, deps ]
|
||||||
|
|
152
util/android-commands.sh
Executable file
152
util/android-commands.sh
Executable file
|
@ -0,0 +1,152 @@
|
||||||
|
# spell-checker:ignore termux keyevent sdcard binutils unmatch adb's dumpsys logcat pkill
|
||||||
|
|
||||||
|
# There are three shells: the host's, adb, and termux. Only adb lets us run
|
||||||
|
# commands directly on the emulated device, only termux provides a GNU
|
||||||
|
# environment on the emulated device (to e.g. run cargo). So we use adb to
|
||||||
|
# launch termux, then to send keystrokes to it while it's running.
|
||||||
|
# This means that the commands sent to termux are first parsed as arguments in
|
||||||
|
# this shell, then as arguments in the adb shell, before finally being used as
|
||||||
|
# text inputs to the app. Hence, the "'wrapping'" on those commands.
|
||||||
|
# There's no way to get any feedback from termux, so every time we run a
|
||||||
|
# command on it, we make sure it ends by creating a unique *.probe file at the
|
||||||
|
# end of the command. The contents of the file are used as a return code: 0 on
|
||||||
|
# success, some other number for errors (an empty file is basically the same as
|
||||||
|
# 0). Note that the return codes are text, not raw bytes.
|
||||||
|
|
||||||
|
|
||||||
|
this_repo="$(dirname $(dirname -- "$(readlink -- "${0}")"))"
|
||||||
|
|
||||||
|
help () {
|
||||||
|
echo \
|
||||||
|
"Usage: $0 COMMAND [ARG]
|
||||||
|
|
||||||
|
where COMMAND is one of:
|
||||||
|
snapshot APK install APK and dependencies on an emulator to prep a snapshot
|
||||||
|
(you can, but probably don't want to, run this for physical
|
||||||
|
devices -- just set up termux and the dependencies yourself)
|
||||||
|
sync [REPO] push the repo at REPO to the device, deleting and restoring all
|
||||||
|
symlinks (locally) in the process; by default, REPO is:
|
||||||
|
$this_repo
|
||||||
|
build run \`cargo build --features feat_os_unix_android\` on the
|
||||||
|
device, then pull the output as build.log
|
||||||
|
tests run \`cargo test --features feat_os_unix_android\` on the
|
||||||
|
device, then pull the output as tests.log
|
||||||
|
|
||||||
|
If you have multiple devices, use the ANDROID_SERIAL environment variable to
|
||||||
|
specify which to connect to."
|
||||||
|
}
|
||||||
|
|
||||||
|
hit_enter() {
|
||||||
|
adb shell input keyevent 66
|
||||||
|
}
|
||||||
|
|
||||||
|
launch_termux() {
|
||||||
|
echo "launching termux"
|
||||||
|
if ! adb shell 'am start -n com.termux/.HomeActivity' ; then
|
||||||
|
echo "failed to launch termux"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# the emulator can sometimes be a little slow to launch the app
|
||||||
|
while ! adb shell 'ls /sdcard/launch.probe' 2>/dev/null; do
|
||||||
|
echo "waiting for launch.probe"
|
||||||
|
sleep 5
|
||||||
|
adb shell input text 'touch\ /sdcard/launch.probe' && hit_enter
|
||||||
|
done
|
||||||
|
echo "found launch.probe"
|
||||||
|
adb shell 'rm /sdcard/launch.probe' && echo "removed launch.probe"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_termux_command() {
|
||||||
|
command="$1" # text of the escaped command, including creating the probe!
|
||||||
|
probe="$2" # unique file that indicates the command is complete
|
||||||
|
launch_termux
|
||||||
|
adb shell input text "$command" && hit_enter
|
||||||
|
while ! adb shell "ls $probe" 2>/dev/null; do echo "waiting for $probe"; sleep 30; done
|
||||||
|
return_code=$(adb shell "cat $probe")
|
||||||
|
adb shell "rm $probe"
|
||||||
|
echo "return code: $return_code"
|
||||||
|
return $return_code
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshot () {
|
||||||
|
apk="$1"
|
||||||
|
echo "running snapshot"
|
||||||
|
adb install -g "$apk"
|
||||||
|
probe='/sdcard/pkg.probe'
|
||||||
|
command="'yes | pkg install rust binutils openssl -y; touch $probe'"
|
||||||
|
run_termux_command "$command" "$probe"
|
||||||
|
echo "snapshot complete"
|
||||||
|
adb shell input text "exit" && hit_enter && hit_enter
|
||||||
|
}
|
||||||
|
|
||||||
|
sync () {
|
||||||
|
repo="$1"
|
||||||
|
echo "running sync $1"
|
||||||
|
# android doesn't allow symlinks on shared dirs, and adb can't selectively push files
|
||||||
|
symlinks=$(find "$repo" -type l)
|
||||||
|
# dash doesn't support process substitution :(
|
||||||
|
echo $symlinks | sort >symlinks
|
||||||
|
git -C "$repo" diff --name-status | cut -f 2 >modified
|
||||||
|
modified_links=$(join symlinks modified)
|
||||||
|
if [ ! -z "$modified_links" ]; then
|
||||||
|
echo "You have modified symlinks. Either stash or commit them, then try again: $modified_links"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! git ls-files --error-unmatch $symlinks >/dev/null; then
|
||||||
|
echo "You have untracked symlinks. Either remove or commit them, then try again."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rm $symlinks
|
||||||
|
# adb's shell user only has access to shared dirs...
|
||||||
|
adb push "$repo" /sdcard/coreutils
|
||||||
|
git -C "$repo" checkout $symlinks
|
||||||
|
# ...but shared dirs can't build, so move it home as termux
|
||||||
|
probe='/sdcard/mv.probe'
|
||||||
|
command="'cp -r /sdcard/coreutils ~/; touch $probe'"
|
||||||
|
run_termux_command "$command" "$probe"
|
||||||
|
}
|
||||||
|
|
||||||
|
build () {
|
||||||
|
probe='/sdcard/build.probe'
|
||||||
|
command="'cd ~/coreutils && cargo build --features feat_os_unix_android 2>/sdcard/build.log; echo \$? >$probe'"
|
||||||
|
echo "running build"
|
||||||
|
run_termux_command "$command" "$probe"
|
||||||
|
return_code=$?
|
||||||
|
adb pull /sdcard/build.log .
|
||||||
|
cat build.log
|
||||||
|
return $return_code
|
||||||
|
}
|
||||||
|
|
||||||
|
tests () {
|
||||||
|
probe='/sdcard/tests.probe'
|
||||||
|
command="'cd ~/coreutils && cargo test --features feat_os_unix_android --no-fail-fast >/sdcard/tests.log 2>&1; echo \$? >$probe'"
|
||||||
|
run_termux_command "$command" "$probe"
|
||||||
|
return_code=$?
|
||||||
|
adb pull /sdcard/tests.log .
|
||||||
|
cat tests.log
|
||||||
|
return $return_code
|
||||||
|
}
|
||||||
|
|
||||||
|
#adb logcat &
|
||||||
|
exit_code=0
|
||||||
|
|
||||||
|
if [ $# -eq 1 ]; then
|
||||||
|
case "$1" in
|
||||||
|
sync) sync "$this_repo"; exit_code=$?;;
|
||||||
|
build) build; exit_code=$?;;
|
||||||
|
tests) tests; exit_code=$?;;
|
||||||
|
*) help;;
|
||||||
|
esac
|
||||||
|
elif [ $# -eq 2 ]; then
|
||||||
|
case "$1" in
|
||||||
|
snapshot) snapshot "$2"; exit_code=$?;;
|
||||||
|
sync) sync "$2"; exit_code=$?;;
|
||||||
|
*) help; exit 1;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
help
|
||||||
|
exit_code=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#pkill adb
|
||||||
|
exit $exit_code
|
Loading…
Reference in a new issue