From bd4ede2fb782e30c89e44ff52b7e5137f010a1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Grome=C5=A1?= Date: Wed, 1 Jan 2025 14:14:08 +0100 Subject: [PATCH] [CI] Add size metrics (#1367) * [CI] Add CI scripts, save metrics on build * Fix token name * Fix path * Pass size files via artifacts * Fix path to artifacts * Fix git hash in artifact filename * Fix git hash * Fix artifact name * Fix artifact path * Avoid filenames with colons * Fix artifact paths * Remove incorrect cd * Add missing cd * Fix paths in second repo * More path fixing * Fix artifacts repo name * Remove path from example filename in output * Add hash to commit message * Fix typo * Fix artifact commit message * Move git hash * Use GITHUB_SHA variable * Drop markdown format --------- Co-authored-by: jgromes --- .github/workflows/main.yml | 69 ++++++++++++++++++++++---------- extras/test/ci/build_arduino.sh | 13 ++++++ extras/test/ci/build_examples.sh | 41 +++++++++++++++++++ extras/test/ci/parse_size.sh | 24 +++++++++++ 4 files changed, 126 insertions(+), 21 deletions(-) create mode 100755 extras/test/ci/build_arduino.sh create mode 100755 extras/test/ci/build_examples.sh create mode 100755 extras/test/ci/parse_size.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 963e4eb3..7e7e374b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -180,28 +180,55 @@ jobs: if: ${{ env.run-build == 'true' }} run: | - for example in $(find $PWD/examples -name '*.ino' | sort); do - # check whether to skip this sketch - if [ ! -z '${{ steps.prep.outputs.skip-pattern }}' ] && [[ ${example} =~ ${{ steps.prep.outputs.skip-pattern }} ]]; then - # skip sketch - echo -e "\n\033[1;33mSkipped ${example##*/} (matched with ${{ steps.prep.outputs.skip-pattern }})\033[0m"; - else - # apply special flags for LoRaWAN - if [[ ${example} =~ "LoRaWAN" ]]; then - flags="-DRADIOLIB_LORAWAN_DEV_ADDR=0 -DRADIOLIB_LORAWAN_FNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_SNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_NWKSENC_KEY=0 -DRADIOLIB_LORAWAN_APPS_KEY=0 -DRADIOLIB_LORAWAN_APP_KEY=0 -DRADIOLIB_LORAWAN_NWK_KEY=0 -DRADIOLIB_LORAWAN_DEV_EUI=0 -DARDUINO_TTGO_LORA32_V1" - fi + cd $PWD/extras/test/ci + ./build_examples.sh ${{ matrix.id }} "${{ steps.prep.outputs.skip-pattern }}" ${{ steps.prep.outputs.options }} + + - name: Parse sizes + if: ${{ env.run-build == 'true' }} + run: + | + cd $PWD/extras/test/ci + ./parse_size.sh ${{ matrix.id }} + + - name: Extract short commit hash + id: short-hash + run: echo "::set-output name=short_sha::$(git rev-parse --short HEAD)" + + - name: Upload size report as artifact + uses: actions/upload-artifact@v3 + with: + name: size-file-${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }} + path: extras/test/ci/size_${{ steps.short-hash.outputs.short_sha }}_${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}.csv - # build sketch - echo -e "\n\033[1;33mBuilding ${example##*/} ... \033[0m"; - arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn ${{ matrix.id }}${{ steps.prep.outputs.options }} --build-property compiler.cpp.extra_flags="$flags" $example --warnings=${{ steps.prep.outputs.warnings }} - if [ $? -ne 0 ]; then - echo -e "\033[1;31m${example##*/} build FAILED\033[0m\n"; - exit 1; - else - echo -e "\033[1;32m${example##*/} build PASSED\033[0m\n"; - fi - fi - done + metrics: + runs-on: ubuntu-latest + needs: build + steps: + - name: Clone artifact repo + run: + | + cd $PWD/.. + git clone https://${{ github.actor }}:${{ secrets.ACTIONS_METRICS_PUSH_TOKEN }}@github.com/radiolib-org/artifacts.git + cd artifacts + git config --global user.name "${{ github.actor }}" + git config --global user.email "${{ github.actor }}@users.noreply.github.com" + + - name: Download size artifacts + uses: actions/download-artifact@v3 + with: + path: aggregated-sizes + + - name: Push size files + run: + | + ls -R aggregated-sizes + mkdir -p $PWD/../artifacts/radiolib-ci/l0 + cp aggregated-sizes/*/size_*.csv $PWD/../artifacts/radiolib-ci/l0/. + cd $PWD/../artifacts/radiolib-ci + git add . + COMMIT_URL="https://github.com/jgromes/RadioLib/commit/$GITHUB_SHA" + git commit -m "Push artifacts from $COMMIT_URL" + git push origin main esp-build: runs-on: ubuntu-latest diff --git a/extras/test/ci/build_arduino.sh b/extras/test/ci/build_arduino.sh new file mode 100755 index 00000000..1e46c100 --- /dev/null +++ b/extras/test/ci/build_arduino.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +board=$1 +sketch=$2 +flags=$3 +warnings="all" + +arduino-cli compile \ + --libraries ../../../../ \ + --fqbn $board \ + --build-property compiler.cpp.extra_flags="$flags" \ + --warnings=$warnings \ + $sketch --export-binaries diff --git a/extras/test/ci/build_examples.sh b/extras/test/ci/build_examples.sh new file mode 100755 index 00000000..44bfb9c3 --- /dev/null +++ b/extras/test/ci/build_examples.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +#board=arduino:avr:mega +board="$1" +#skip="(STM32WL|LR11x0_Firmware_Update|NonArduino)" +skip="$2" +#options="" +options="$3" + +# file for saving the compiled binary size reports +size_file="size_$board.txt" +rm -f $size_file + +path="../../../examples" +for example in $(find $path -name '*.ino' | sort); do + # check whether to skip this sketch + if [ ! -z '$skip' ] && [[ ${example} =~ ${skip} ]]; then + # skip sketch + echo -e "\n\033[1;33mSkipped ${example##*/} (matched with $skip)\033[0m"; + else + # apply special flags for LoRaWAN + if [[ ${example} =~ "LoRaWAN" ]]; then + flags="-DRADIOLIB_LORAWAN_DEV_ADDR=0 -DRADIOLIB_LORAWAN_FNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_SNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_NWKSENC_KEY=0 -DRADIOLIB_LORAWAN_APPS_KEY=0 -DRADIOLIB_LORAWAN_APP_KEY=0 -DRADIOLIB_LORAWAN_NWK_KEY=0 -DRADIOLIB_LORAWAN_DEV_EUI=0 -DARDUINO_TTGO_LORA32_V1" + fi + + # build sketch + echo -e "\n\033[1;33mBuilding ${example##*/} ... \033[0m"; + board_opts=$board$options + ./build_arduino.sh $board_opts $example "$flags" + if [ $? -ne 0 ]; then + echo -e "\033[1;31m${example##*/} build FAILED\033[0m\n"; + exit 1; + else + echo -e "\033[1;32m${example##*/} build PASSED\033[0m\n"; + dir="$(dirname -- "$example")" + file="$(basename -- "$example")" + size="$(size $dir/build/*/$file.elf)" + echo $size >> $size_file + fi + fi +done diff --git a/extras/test/ci/parse_size.sh b/extras/test/ci/parse_size.sh new file mode 100755 index 00000000..679a3f9c --- /dev/null +++ b/extras/test/ci/parse_size.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +board=$1 +hash=$(git rev-parse --short HEAD) + +in_file="size_$board.txt" +out_file="size_${hash}_${board//:/-}.csv" +rm -f $out_file + +# write the header +echo "text,data,bss,dec,hex,filename" > "$out_file" + +# convert to CSV +awk 'NR > 1 { + split($12, path_parts, "/"); + filename_with_ext = path_parts[length(path_parts)]; + split(filename_with_ext, filename_parts, "."); + filename = filename_parts[1]; + print $7 "," $8 "," $9 "," $10 "," $11 "," filename +}' "$in_file" >> "$out_file" + +# remove input file +rm -f $in_file +