Skip to content

Commit 053f28a

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

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed

.github/scripts/sketch_utils.sh

Lines changed: 159 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" -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,9 @@ function build_sketches { # build_sketches <ide_path> <user_path> <target> <path
558566
continue
559567
fi
560568
echo ""
569+
561570
echo "Building Sketch Index $sketchnum - $sketchdirname"
571+
562572
build_sketch "${args[@]}" -s "$sketchdir" "${xtra_opts[@]}"
563573
local result=$?
564574
if [ $result -ne 0 ]; then
@@ -580,13 +590,160 @@ function build_sketches { # build_sketches <ide_path> <user_path> <target> <path
580590
return 0
581591
}
582592

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

592749
cmd=$1
@@ -606,6 +763,8 @@ case "$cmd" in
606763
;;
607764
"check_requirements") check_requirements "$@"
608765
;;
766+
"install_libs") install_libs "$@"
767+
;;
609768
*)
610769
echo "ERROR: Unrecognized command"
611770
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)