Skip to content

Commit ec5a245

Browse files
committed
feat: Add library installation before sketch builds in CI scripts
1 parent c386501 commit ec5a245

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed

.github/scripts/sketch_utils.sh

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,14 @@ function build_sketch { # build_sketch <ide_path> <user_path> <path-to-ino> [ext
244244
fi
245245
fi
246246

247+
# Install libraries from ci.json if they exist
248+
install_libs -ai "$ide_path" -s "$sketchdir" ${log_compilation:+-v}
249+
install_result=$?
250+
if [ $install_result -ne 0 ]; then
251+
echo "ERROR: Library installation failed for $sketchname" >&2
252+
exit $install_result
253+
fi
254+
247255
ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
248256
if [ -n "$ARDUINO_BUILD_DIR" ]; then
249257
build_dir="$ARDUINO_BUILD_DIR"
@@ -558,7 +566,17 @@ function build_sketches { # build_sketches <ide_path> <user_path> <target> <path
558566
continue
559567
fi
560568
echo ""
569+
570+
# Install libraries from ci.json if they exist
571+
install_libs -ai "$ide_path" -s "$sketchdir"
572+
install_result=$?
573+
if [ $install_result -ne 0 ]; then
574+
echo "ERROR: Library installation failed for $sketchdirname" >&2
575+
return $install_result
576+
fi
577+
561578
echo "Building Sketch Index $sketchnum - $sketchdirname"
579+
562580
build_sketch "${args[@]}" -s "$sketchdir" "${xtra_opts[@]}"
563581
local result=$?
564582
if [ $result -ne 0 ]; then
@@ -580,13 +598,160 @@ function build_sketches { # build_sketches <ide_path> <user_path> <target> <path
580598
return 0
581599
}
582600

601+
function install_libs { # install_libs <ide_path> <sketchdir> [-v]
602+
local ide_path=""
603+
local sketchdir=""
604+
local verbose=false
605+
606+
# Return codes:
607+
# 0 = success / nothing to do
608+
# 2 = usage / arguments error
609+
# 3 = prerequisite missing (arduino-cli)
610+
# 4 = ci.json invalid
611+
# N = arduino-cli exit status when a library install fails
612+
613+
while [ -n "$1" ]; do
614+
case "$1" in
615+
-ai ) shift; ide_path=$1 ;;
616+
-s ) shift; sketchdir=$1 ;;
617+
-v ) verbose=true ;;
618+
* )
619+
echo "ERROR: Unknown argument: $1" >&2
620+
echo "USAGE: install_libs -ai <ide_path> -s <sketchdir> [-v]" >&2
621+
return 2
622+
;;
623+
esac
624+
shift
625+
done
626+
627+
if [ -z "$ide_path" ]; then
628+
echo "ERROR: IDE path not provided" >&2
629+
echo "USAGE: install_libs -ai <ide_path> -s <sketchdir> [-v]" >&2
630+
return 2
631+
fi
632+
if [ -z "$sketchdir" ]; then
633+
echo "ERROR: Sketch directory not provided" >&2
634+
echo "USAGE: install_libs -ai <ide_path> -s <sketchdir> [-v]" >&2
635+
return 2
636+
fi
637+
if [ ! -f "$ide_path/arduino-cli" ]; then
638+
echo "ERROR: arduino-cli not found at $ide_path/arduino-cli" >&2
639+
return 3
640+
fi
641+
642+
# No ci.json => nothing to install
643+
if [ ! -f "$sketchdir/ci.json" ]; then
644+
[ "$verbose" = true ] && echo "No ci.json found in $sketchdir, skipping library installation"
645+
return 0
646+
fi
647+
648+
# Validate JSON early
649+
if ! jq -e . "$sketchdir/ci.json" >/dev/null 2>&1; then
650+
echo "ERROR: $sketchdir/ci.json is not valid JSON" >&2
651+
return 4
652+
fi
653+
654+
local libs_type
655+
libs_type=$(jq -r '.libs | type' "$sketchdir/ci.json" 2>/dev/null)
656+
if [ -z "$libs_type" ] || [ "$libs_type" = "null" ]; then
657+
[ "$verbose" = true ] && echo "No libs field found in ci.json, skipping library installation"
658+
return 0
659+
elif [ "$libs_type" != "array" ]; then
660+
echo "ERROR: libs field in ci.json must be an array, found: $libs_type" >&2
661+
return 4
662+
fi
663+
664+
local libs_count
665+
libs_count=$(jq -r '.libs | length' "$sketchdir/ci.json" 2>/dev/null)
666+
if [ "$libs_count" -eq 0 ]; then
667+
[ "$verbose" = true ] && echo "libs array is empty in ci.json, skipping library installation"
668+
return 0
669+
fi
670+
671+
echo "Installing $libs_count libraries from $sketchdir/ci.json"
672+
673+
local needs_unsafe=false
674+
local original_unsafe_setting=""
675+
local libs
676+
libs=$(jq -r '.libs[]? // empty' "$sketchdir/ci.json")
677+
678+
# Detect if any lib is a Git URL (needs unsafe install)
679+
for lib in $libs; do
680+
if [[ "$lib" == https://github.com/* ]]; then
681+
needs_unsafe=true
682+
break
683+
fi
684+
done
685+
686+
# Enable unsafe installs if needed, remember original setting
687+
if [ "$needs_unsafe" = true ]; then
688+
[ "$verbose" = true ] && echo "Checking current unsafe install setting..."
689+
original_unsafe_setting=$("$ide_path/arduino-cli" config get library.enable_unsafe_install 2>/dev/null || echo "false")
690+
if [ "$original_unsafe_setting" = "false" ]; then
691+
[ "$verbose" = true ] && echo "Enabling unsafe installs for Git URLs..."
692+
if ! "$ide_path/arduino-cli" config set library.enable_unsafe_install true >/dev/null 2>&1; then
693+
echo "WARNING: Failed to enable unsafe installs, Git URL installs may fail" >&2
694+
# continue; the install will surface a real error if it matters
695+
fi
696+
else
697+
[ "$verbose" = true ] && echo "Unsafe installs already enabled"
698+
fi
699+
fi
700+
701+
local rc=0 install_status=0 output=""
702+
for lib in $libs; do
703+
[ "$verbose" = true ] && echo "Processing library: $lib"
704+
705+
if [[ "$lib" == https://github.com/* ]]; then
706+
[ "$verbose" = true ] && echo "Installing library from GitHub URL: $lib"
707+
if [ "$verbose" = true ]; then
708+
"$ide_path/arduino-cli" lib install --git-url "$lib"
709+
install_status=$?
710+
else
711+
output=$("$ide_path/arduino-cli" lib install --git-url "$lib" 2>&1)
712+
install_status=$?
713+
[ $install_status -ne 0 ] && echo "$output" | grep -Ei "error|warning|warn" >&2 || true
714+
fi
715+
else
716+
[ "$verbose" = true ] && echo "Installing library by name: $lib"
717+
if [ "$verbose" = true ]; then
718+
"$ide_path/arduino-cli" lib install "$lib"
719+
install_status=$?
720+
else
721+
output=$("$ide_path/arduino-cli" lib install "$lib" 2>&1)
722+
install_status=$?
723+
[ $install_status -ne 0 ] && echo "$output" | grep -Ei "error|warning|warn" >&2 || true
724+
fi
725+
fi
726+
727+
if [ $install_status -ne 0 ]; then
728+
echo "ERROR: Failed to install library: $lib" >&2
729+
rc=$install_status
730+
break
731+
else
732+
[ "$verbose" = true ] && echo "Successfully installed library: $lib"
733+
fi
734+
done
735+
736+
# Restore unsafe setting if we changed it
737+
if [ "$needs_unsafe" = true ] && [ "$original_unsafe_setting" = "false" ]; then
738+
[ "$verbose" = true ] && echo "Restoring original unsafe install setting..."
739+
"$ide_path/arduino-cli" config set library.enable_unsafe_install false >/dev/null 2>&1 || true
740+
fi
741+
742+
[ $rc -eq 0 ] && echo "Library installation completed"
743+
return $rc
744+
}
745+
746+
583747
USAGE="
584748
USAGE: ${0} [command] [options]
585749
Available commands:
586750
count: Count sketches.
587751
build: Build a sketch.
588752
chunk_build: Build a chunk of sketches.
589753
check_requirements: Check if target meets sketch requirements.
754+
install_libs: Install libraries from ci.json file.
590755
"
591756

592757
cmd=$1
@@ -606,6 +771,8 @@ case "$cmd" in
606771
;;
607772
"check_requirements") check_requirements "$@"
608773
;;
774+
"install_libs") install_libs "$@"
775+
;;
609776
*)
610777
echo "ERROR: Unrecognized command"
611778
echo "$USAGE"

tests/validation/hello_world/ci.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"libs": [
3+
4+
"https://github.com/arduino-libraries/WiFi101.git"
5+
]
6+
}

0 commit comments

Comments
 (0)