Compare commits

..

No commits in common. "master" and "add-metro-esp32s3" have entirely different histories.

6 changed files with 135 additions and 246 deletions

View file

@ -1,19 +1,20 @@
name: Github Arduino Library CI name: Github Arduino Library CI
on: [push, pull_request] on: [push]
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- uses: actions/setup-python@v5 - uses: actions/setup-python@v4
with: with:
python-version: '3.x' python-version: '3.x'
- name: pre-install - name: pre-install
run: bash ./actions_install.sh run: bash ./actions_install.sh
- name: test platforms - name: test platforms
run: | run: |
python3 build_platform.py uno leonardo mega2560 zero esp8266 esp32 pico_rp2040 feather_m4_express feather_rp2350 python3 build_platform.py uno leonardo mega2560 zero esp8266 esp32 pico_rp2040 feather_m4_express

View file

@ -1,9 +1,9 @@
# Arduino CI Scripts # Arduino CI Scripts
This repo contains various scripts and tools related to running continuous integration (CI) checks on Arduino Library Repos. The operations include: This repos contains various scripts and tools related to running continuous integration (CI) checks on Arduino Library Repos. The operations include:
* checking formatting using [clang-format](https://clang.llvm.org/docs/ClangFormat.html), * checking formatting using using [clang-format](https://clang.llvm.org/docs/ClangFormat.html),
* generating documentation from source comments using [Doxygen](https://www.doxygen.nl/), and * generating documentation from source comments using using [Doxygen](https://www.doxygen.nl/), and
* building each example in the library for selected targets. * building each example in the library for selected targets.
There is an associated guide available here: There is an associated guide available here:
@ -74,20 +74,5 @@ clang-format -i File_To_Format.cpp
The `doxy_gen_and_deploy.sh` script uses [Doxygen](https://www.doxygen.nl/) to generate and deploy documentation The `doxy_gen_and_deploy.sh` script uses [Doxygen](https://www.doxygen.nl/) to generate and deploy documentation
for the library. Any issues, like missing documentation, will cause the CI to fail. for the library. Any issues, like missing documentation, will cause the CI to fail.
See the [guide](https://learn.adafruit.com/the-well-automated-arduino-library/doxygen) for details on installing and running Doxygen locally. The guide also has some See the [the guide](https://learn.adafruit.com/the-well-automated-arduino-library/doxygen) for details on installing and running doxygen locally. The guide also has some
[tips](https://learn.adafruit.com/the-well-automated-arduino-library/doxygen-tips) on basic usage of Doxygen markup within your code. [tips](https://learn.adafruit.com/the-well-automated-arduino-library/doxygen-tips) on basic usage of doxygen markup within your code.
### Preserving Folders in Documentation Branch
By default, the documentation deployment script cleans the gh-pages branch before adding new documentation. If you need to preserve certain folders (like custom web interfaces), you can set the `PRESERVE_FOLDERS` environment variable in your workflow:
```yaml
- name: doxygen
env:
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
PRETTYNAME : "My Arduino Library"
PRESERVE_FOLDERS: "webserial,assets"
run: bash ci/doxy_gen_and_deploy.sh
```
This will preserve the listed folders (comma-separated) during the documentation generation process.

View file

@ -37,8 +37,7 @@ arduino-cli core update-index > /dev/null
case "$GITHUB_REPOSITORY" in case "$GITHUB_REPOSITORY" in
(*/ci-arduino|*/Adafruit_Learning_System_Guides) ;; (*/ci-arduino|*/Adafruit_Learning_System_Guides) ;;
(*) (*)
repo_topics=$(curl -f --request GET --url "https://api.github.com/repos/$GITHUB_REPOSITORY" || echo '{"topics":[]}') repo_topics=$(curl --request GET --url "https://api.github.com/repos/$GITHUB_REPOSITORY" | jq -r '.topics[]')
repo_topics=$(echo $repo_topics | jq -r '.topics[]' )
if [[ ! $repo_topics =~ "arduino-library" ]]; then if [[ ! $repo_topics =~ "arduino-library" ]]; then
echo "::warning::arduino-library is not found in this repo topics. Please add this tag in repo About" echo "::warning::arduino-library is not found in this repo topics. Please add this tag in repo About"
fi fi

View file

@ -1,4 +1,3 @@
# board: [ platform, uf2_family, manual core URL]
ALL_PLATFORMS={ ALL_PLATFORMS={
# classic Arduino AVR # classic Arduino AVR
"uno" : ["arduino:avr:uno", None, None], "uno" : ["arduino:avr:uno", None, None],
@ -7,53 +6,32 @@ ALL_PLATFORMS={
# Arduino SAMD # Arduino SAMD
"zero" : ["arduino:samd:arduino_zero_native", "0x68ed2b88", None, None], "zero" : ["arduino:samd:arduino_zero_native", "0x68ed2b88", None, None],
"cpx" : ["arduino:samd:adafruit_circuitplayground_m0", "0x68ed2b88", None], "cpx" : ["arduino:samd:adafruit_circuitplayground_m0", "0x68ed2b88", None],
# Arduino MBED GIGA
"giga" : ["arduino:mbed_giga:giga", None, None],
# Espressif # Espressif
"esp8266" : ["esp8266:esp8266:huzzah:eesz=4M3M,xtal=80", None, None], "esp8266" : ["esp8266:esp8266:huzzah:eesz=4M3M,xtal=80", None, None],
"esp32" : ["esp32:esp32:featheresp32:FlashFreq=80", None, None], "esp32" : ["esp32:esp32:featheresp32:FlashFreq=80", None, None],
"itsybitsy_esp32" : ["esp32:esp32:adafruit_itsybitsy_esp32:FlashFreq=80", None, None],
"feather_esp8266" : ["esp8266:esp8266:huzzah:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200", None, None], "feather_esp8266" : ["esp8266:esp8266:huzzah:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200", None, None],
"feather_esp32" : ["esp32:esp32:featheresp32:FlashFreq=80", None, None], "feather_esp32" : ["esp32:esp32:featheresp32:FlashFreq=80", None, None],
"wippersnapper_feather_esp32" : ["esp32:esp32:featheresp32:FlashFreq=80,PartitionScheme=min_spiffs", None, None],
"feather_esp32_v2" : ["esp32:esp32:adafruit_feather_esp32_v2", None, None], "feather_esp32_v2" : ["esp32:esp32:adafruit_feather_esp32_v2", None, None],
"qtpy_esp32" : ["esp32:esp32:adafruit_qtpy_esp32_pico", None, None],
"sparklemotion_esp32" : ["esp32:esp32:sparklemotion", None, None],
"sparklemotionmini_esp32" : ["esp32:esp32:sparklemotionmini", None, None],
## ESP32-C3/C6
"feather_esp32c6" : ["esp32:esp32:adafruit_feather_esp32c6:FlashMode=qio", None, None],
"wippersnapper_feather_esp32c6" : ["esp32:esp32:adafruit_feather_esp32c6:CDCOnBoot=cdc,CPUFreq=160,FlashFreq=80,FlashMode=qio,PartitionScheme=min_spiffs", None, None],
"wippersnapper_feather_esp32c6_debug" : ["esp32:esp32:adafruit_feather_esp32c6:CDCOnBoot=cdc,DebugLevel=verbose,CPUFreq=160,FlashFreq=80,FlashMode=qio,PartitionScheme=min_spiffs", None, None],
"qtpy_esp32c3" : ["esp32:esp32:adafruit_qtpy_esp32c3:FlashMode=qio", None, None],
"wippersnapper_qtpy_esp32c3" : ["esp32:esp32:adafruit_qtpy_esp32c3:FlashMode=qio,PartitionScheme=min_spiffs", None, None],
## ESP32-S2 ## ESP32-S2
"magtag" : ["esp32:esp32:adafruit_magtag29_esp32s2", "0xbfdd4eee", None], "magtag" : ["esp32:esp32:adafruit_magtag29_esp32s2", "0xbfdd4eee", None],
"funhouse" : ["esp32:esp32:adafruit_funhouse_esp32s2", "0xbfdd4eee", None], "funhouse" : ["esp32:esp32:adafruit_funhouse_esp32s2", "0xbfdd4eee", None],
"funhouse_noota" : ["esp32:esp32:adafruit_funhouse_esp32s2:PartitionScheme=tinyuf2_noota", "0xbfdd4eee", None],
"metroesp32s2" : ["esp32:esp32:adafruit_metro_esp32s2", "0xbfdd4eee", None], "metroesp32s2" : ["esp32:esp32:adafruit_metro_esp32s2", "0xbfdd4eee", None],
"qtpy_esp32s2" : ["esp32:esp32:adafruit_qtpy_esp32s2", "0xbfdd4eee", None], "qtpy_esp32s2" : ["esp32:esp32:adafruit_qtpy_esp32s2", "0xbfdd4eee", None],
"feather_esp32s2" : ["esp32:esp32:adafruit_feather_esp32s2", "0xbfdd4eee", None], "feather_esp32s2" : ["esp32:esp32:adafruit_feather_esp32s2", "0xbfdd4eee", None],
"feather_esp32s2_debug" : ["esp32:esp32:adafruit_feather_esp32s2:DebugLevel=verbose", "0xbfdd4eee", None],
"feather_esp32s2_tft" : ["esp32:esp32:adafruit_feather_esp32s2_tft", "0xbfdd4eee", None], "feather_esp32s2_tft" : ["esp32:esp32:adafruit_feather_esp32s2_tft", "0xbfdd4eee", None],
"feather_esp32s2_tft_debug" : ["esp32:esp32:adafruit_feather_esp32s2_tft:DebugLevel=verbose", "0xbfdd4eee", None],
"feather_esp32s2_reverse_tft" : ["esp32:esp32:adafruit_feather_esp32s2_reversetft", "0xbfdd4eee", None], "feather_esp32s2_reverse_tft" : ["esp32:esp32:adafruit_feather_esp32s2_reversetft", "0xbfdd4eee", None],
## ESP32-S3 ## ESP32-S3
"feather_esp32s3" : ["esp32:esp32:adafruit_feather_esp32s3_nopsram", "0xc47e5767", None], "feather_esp32s3" : ["esp32:esp32:adafruit_feather_esp32s3_nopsram", "0xc47e5767", None],
"feather_esp32s3_debug" : ["esp32:esp32:adafruit_feather_esp32s3_nopsram:DebugLevel=verbose", "0xc47e5767", None],
"feather_esp32s3_4mbflash_2mbpsram" : ["esp32:esp32:adafruit_feather_esp32s3", "0xc47e5767", None], "feather_esp32s3_4mbflash_2mbpsram" : ["esp32:esp32:adafruit_feather_esp32s3", "0xc47e5767", None],
"feather_esp32s3_4mbflash_2mbpsram_debug" : ["esp32:esp32:adafruit_feather_esp32s3:DebugLevel=verbose", "0xc47e5767", None],
"feather_esp32s3_tft" : ["esp32:esp32:adafruit_feather_esp32s3_tft", "0xc47e5767", None], "feather_esp32s3_tft" : ["esp32:esp32:adafruit_feather_esp32s3_tft", "0xc47e5767", None],
"feather_esp32s3_tft_debug" : ["esp32:esp32:adafruit_feather_esp32s3_tft:DebugLevel=verbose", "0xc47e5767", None],
"feather_esp32s3_reverse_tft" : ["esp32:esp32:adafruit_feather_esp32s3_reversetft", "0xc47e5767", None], "feather_esp32s3_reverse_tft" : ["esp32:esp32:adafruit_feather_esp32s3_reversetft", "0xc47e5767", None],
"feather_esp32s3_reverse_tft_debug" : ["esp32:esp32:adafruit_feather_esp32s3_reversetft:DebugLevel=verbose", "0xc47e5767", None],
"matrixportal_s3" : ["esp32:esp32:adafruit_matrixportal_esp32s3", "0xc47e5767", None], "matrixportal_s3" : ["esp32:esp32:adafruit_matrixportal_esp32s3", "0xc47e5767", None],
"metro_esp32s3" : ["esp32:esp32:adafruit_metro_esp32s3", "0xc47e5767", None], "metro_esp32s3" : ["esp32:esp32:adafruit_metro_esp32s3", "0xc47e5767", None],
"pycamera_s3" : ["esp32:esp32:adafruit_camera_esp32s3", "0xc47e5767", None],
"qualia_s3_rgb666" : ["esp32:esp32:adafruit_qualia_s3_rgb666", "0xc47e5767", None], "qualia_s3_rgb666" : ["esp32:esp32:adafruit_qualia_s3_rgb666", "0xc47e5767", None],
"qtpy_esp32s3" : ["esp32:esp32:adafruit_qtpy_esp32s3_nopsram", "0xc47e5767", None], "qtpy_esp32s3" : ["esp32:esp32:adafruit_qtpy_esp32s3_nopsram", "0xc47e5767", None],
"qtpy_esp32s3_n4r2" : ["esp32:esp32:adafruit_qtpy_esp32s3_n4r2", "0xc47e5767", None], "qtpy_esp32s3_n4r2" : ["esp32:esp32:adafruit_qtpy_esp32s3_n4r2", "0xc47e5767", None],
# ESP32-P4 "qtpy_esp32" : ["esp32:esp32:adafruit_qtpy_esp32_pico", None, None],
"esp32p4" : ["esp32:esp32:esp32p4:JTAGAdapter=default,PSRAM=disabled,USBMode=default,CDCOnBoot=cdc,MSCOnBoot=default,DFUOnBoot=default,UploadMode=default,PartitionScheme=default,CPUFreq=360,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,DebugLevel=none,EraseFlash=none", "0x3d308e94", None], "qtpy_esp32c3" : ["esp32:esp32:adafruit_qtpy_esp32c3:FlashMode=qio", None, None],
# Adafruit AVR # Adafruit AVR
"trinket_3v" : ["adafruit:avr:trinket3", None, None], "trinket_3v" : ["adafruit:avr:trinket3", None, None],
"trinket_5v" : ["adafruit:avr:trinket5", None, None], "trinket_5v" : ["adafruit:avr:trinket5", None, None],
@ -102,11 +80,6 @@ ALL_PLATFORMS={
"neokeytrinkey_m0" : ["adafruit:samd:adafruit_neokeytrinkey_m0", "0x68ed2b88", None], "neokeytrinkey_m0" : ["adafruit:samd:adafruit_neokeytrinkey_m0", "0x68ed2b88", None],
"slidetrinkey_m0" : ["adafruit:samd:adafruit_slidetrinkey_m0", "0x68ed2b88", None], "slidetrinkey_m0" : ["adafruit:samd:adafruit_slidetrinkey_m0", "0x68ed2b88", None],
"proxlighttrinkey_m0" : ["adafruit:samd:adafruit_proxlighttrinkey_m0", "0x68ed2b88", None], "proxlighttrinkey_m0" : ["adafruit:samd:adafruit_proxlighttrinkey_m0", "0x68ed2b88", None],
"trrstrinkey_m0" : ["adafruit:samd:adafruit_trrstrinkey_m0", "0x68ed2b88", None],
"thumbsticktrinkey_m0" : ["adafruit:samd:adafruit_thumbsticktrinkey_m0", "0x68ed2b88", None],
"sht4xtrinkey_m0" : ["adafruit:samd:adafruit_sht4xtrinkey_m0", "0x68ed2b88", None],
"pixeltrinkey_m0" : ["adafruit:samd:adafruit_pixeltrinkey_m0", "0x68ed2b88", None],
"X_m0" : ["adafruit:samd:adafruit_X_m0", "0x68ed2b88", None],
"qtpy_m0" : ["adafruit:samd:adafruit_qtpy_m0", "0x68ed2b88", None], "qtpy_m0" : ["adafruit:samd:adafruit_qtpy_m0", "0x68ed2b88", None],
"qtpy_m0_tinyusb" : ["adafruit:samd:adafruit_qtpy_m0:usbstack=tinyusb", "0x68ed2b88", None], "qtpy_m0_tinyusb" : ["adafruit:samd:adafruit_qtpy_m0:usbstack=tinyusb", "0x68ed2b88", None],
# Arduino SAMD # Arduino SAMD
@ -120,40 +93,23 @@ ALL_PLATFORMS={
"cpb" : ["adafruit:nrf52:cplaynrf52840:softdevice=s140v6,debug=l0", "0xada52840", None], "cpb" : ["adafruit:nrf52:cplaynrf52840:softdevice=s140v6,debug=l0", "0xada52840", None],
"clue" : ["adafruit:nrf52:cluenrf52840:softdevice=s140v6,debug=l0", "0xada52840", None], "clue" : ["adafruit:nrf52:cluenrf52840:softdevice=s140v6,debug=l0", "0xada52840", None],
"ledglasses_nrf52840" : ["adafruit:nrf52:ledglasses_nrf52840:softdevice=s140v6,debug=l0", "0xada52840", None], "ledglasses_nrf52840" : ["adafruit:nrf52:ledglasses_nrf52840:softdevice=s140v6,debug=l0", "0xada52840", None],
# RP2040 & RP2350 (Philhower) # RP2040 (Philhower)
"pico_rp2040" : ["rp2040:rp2040:rpipico:freq=125,flash=2097152_0", "0xe48bff56", None], "pico_rp2040" : ["rp2040:rp2040:rpipico:freq=125,flash=2097152_0", "0xe48bff56", None],
"pico_rp2040_tinyusb" : ["rp2040:rp2040:rpipico:flash=2097152_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None], "pico_rp2040_tinyusb" : ["rp2040:rp2040:rpipico:flash=2097152_0,freq=125,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"pico_rp2040_tinyusb_host" : ["rp2040:rp2040:rpipico:flash=2097152_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb_host", "0xe48bff56", None],
"pico_rp2350" : ["rp2040:rp2040:rpipico2:freq=125,flash=4194304_0", "0xe48bff56", None],
"pico_rp2350_tinyusb" : ["rp2040:rp2040:rpipico2:flash=4194304_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"pico_rp2350_tinyusb_host" : ["rp2040:rp2040:rpipico2:flash=4194304_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb_host", "0xe48bff56", None],
"picow_rp2040" : ["rp2040:rp2040:rpipicow:flash=2097152_0,freq=125", "0xe48bff56", None], "picow_rp2040" : ["rp2040:rp2040:rpipicow:flash=2097152_0,freq=125", "0xe48bff56", None],
"picow_rp2040_tinyusb" : ["rp2040:rp2040:rpipicow:flash=2097152_131072,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None], "picow_rp2040_tinyusb" : ["rp2040:rp2040:rpipicow:flash=2097152_131072,freq=133,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"feather_rp2040" : ["rp2040:rp2040:adafruit_feather:freq=125,flash=8388608_0", "0xe48bff56", None], "feather_rp2040" : ["rp2040:rp2040:adafruit_feather:freq=125,flash=8388608_0", "0xe48bff56", None],
"feather_rp2040_tinyusb" : ["rp2040:rp2040:adafruit_feather:flash=8388608_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None], "feather_rp2040_tinyusb" : ["rp2040:rp2040:adafruit_feather:flash=8388608_0,freq=125,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"feather_rp2040_adalogger" : ["rp2040:rp2040:adafruit_feather_adalogger:freq=125,flash=8388608_0", "0xe48bff56", None],
"feather_rp2040_adalogger_tinyusb" : ["rp2040:rp2040:adafruit_feather_adalogger:flash=8388608_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"feather_rp2040_rfm" : ["rp2040:rp2040:adafruit_feather_rfm:freq=125,flash=8388608_0", "0xe48bff56", None], "feather_rp2040_rfm" : ["rp2040:rp2040:adafruit_feather_rfm:freq=125,flash=8388608_0", "0xe48bff56", None],
"feather_rp2040_rfm_tinyusb" : ["rp2040:rp2040:adafruit_feather_rfm:flash=8388608_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None], "feather_rp2040_rfm_tinyusb" : ["rp2040:rp2040:adafruit_feather_rfm:flash=8388608_0,freq=125,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"feather_rp2040_dvi" : ["rp2040:rp2040:adafruit_feather_dvi:freq=125,flash=8388608_0", "0xe48bff56", None], "feather_rp2040_dvi" : ["rp2040:rp2040:adafruit_feather_dvi:freq=125,flash=8388608_0", "0xe48bff56", None],
"feather_rp2040_dvi_tinyusb" : ["rp2040:rp2040:adafruit_feather_dvi:flash=8388608_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None], "feather_rp2040_dvi_tinyusb" : ["rp2040:rp2040:adafruit_feather_dvi:flash=8388608_0,freq=125,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"feather_rp2040_usbhost_tinyusb" : ["rp2040:rp2040:adafruit_feather_usb_host:flash=8388608_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None], "feather_rp2040_usbhost_tinyusb" : ["rp2040:rp2040:adafruit_feather_usb_host:flash=8388608_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"feather_rp2350" : ["rp2040:rp2040:adafruit_feather_rp2350_hstx:arch=arm,flash=8388608_0,freq=150,dbgport=Disabled,dbglvl=None,usbstack=picosdk", "0xe48bff56", None], "qt2040_trinkey" : ["rp2040:rp2040:adafruit_trinkeyrp2040qt:freq=125,flash=8388608_0", "0xe48bff56", None],
"feather_rp2350_tinyusb" : ["rp2040:rp2040:adafruit_feather_rp2350_hstx:arch=arm,flash=8388608_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None], "qt2040_trinkey_tinyusb" : ["rp2040:rp2040:adafruit_trinkeyrp2040qt:flash=8388608_0,freq=125,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"metro_rp2040" : ["rp2040:rp2040:adafruit_metro:flash=16777216_0,freq=200,dbgport=Disabled,dbglvl=None,usbstack=picosdk", "0xe48bff56", None],
"metro_rp2040_tinyusb" : ["rp2040:rp2040:adafruit_metro:flash=16777216_0,freq=200,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"metro_rp2350" : ["rp2040:rp2040:adafruit_metro_rp2350:arch=arm,flash=16777216_0,freq=150,dbgport=Disabled,dbglvl=None,usbstack=picosdk", "0xe48bff56", None],
"metro_rp2350_tinyusb" : ["rp2040:rp2040:adafruit_metro_rp2350:arch=arm,flash=16777216_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"qt2040_trinkey" : ["rp2040:rp2040:adafruit_trinkeyrp2040qt:flash=8388608_0,freq=125","0xe48bff56", None],
"qt2040_trinkey_tinyusb" : ["rp2040:rp2040:adafruit_trinkeyrp2040qt:flash=8388608_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"qt_py_rp2040": ["rp2040:rp2040:adafruit_qtpy:freq=125,flash=8388608_0", "0xe48bff56", None], "qt_py_rp2040": ["rp2040:rp2040:adafruit_qtpy:freq=125,flash=8388608_0", "0xe48bff56", None],
"qt_py_rp2040_tinyusb": ["rp2040:rp2040:adafruit_qtpy:flash=8388608_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None], "qt_py_rp2040_tinyusb": ["rp2040:rp2040:adafruit_qtpy:flash=8388608_0,freq=125,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"itsybitsy_rp2040" : ["rp2040:rp2040:adafruit_itsybitsy:freq=125,flash=8388608_524288", "0xe48bff56", None],
"itsybitsy_rp2040_tinyusb" : ["rp2040:rp2040:adafruit_itsybitsy:flash=8388608_524288,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"floppsy_rp2040" : ["rp2040:rp2040:adafruit_floppsy:freq=125,flash=16777216_14680064", "0xe48bff56", None],
"floppsy_rp2040_tinyusb" : ["rp2040:rp2040:adafruit_floppsy:flash=16777216_14680064,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
"fruit_jam" : ["rp2040:rp2040:adafruit_fruitjam:arch=arm,flash=16777216_0,freq=150,dbgport=Disabled,dbglvl=None,usbstack=picosdk", "0xe48bff56", None],
"fruit_jam_tinyusb" : ["rp2040:rp2040:adafruit_fruitjam:arch=arm,flash=16777216_0,freq=120,dbgport=Disabled,dbglvl=None,usbstack=tinyusb", "0xe48bff56", None],
# Attiny8xy, 16xy, 32xy (SpenceKonde) # Attiny8xy, 16xy, 32xy (SpenceKonde)
"attiny3217" : ["megaTinyCore:megaavr:atxy7:chip=3217", None, None], "attiny3217" : ["megaTinyCore:megaavr:atxy7:chip=3217", None, None],
"attiny3216" : ["megaTinyCore:megaavr:atxy6:chip=3216", None, None], "attiny3216" : ["megaTinyCore:megaavr:atxy6:chip=3216", None, None],
@ -165,15 +121,11 @@ ALL_PLATFORMS={
"attiny816" : ["megaTinyCore:megaavr:atxy6:chip=816", None, None], "attiny816" : ["megaTinyCore:megaavr:atxy6:chip=816", None, None],
"attiny807" : ["megaTinyCore:megaavr:atxy7:chip=807", None, None], "attiny807" : ["megaTinyCore:megaavr:atxy7:chip=807", None, None],
"attiny806" : ["megaTinyCore:megaavr:atxy6:chip=806", None, None], "attiny806" : ["megaTinyCore:megaavr:atxy6:chip=806", None, None],
# CH32v2 (openwch)
"CH32V20x_EVT": ["WCH:ch32v:CH32V20x_EVT", None, None],
# groupings # groupings
"main_platforms" : ("uno", "leonardo", "mega2560", "zero", "qtpy_m0", "main_platforms" : ("uno", "leonardo", "mega2560", "zero", "qtpy_m0",
"esp8266", "esp32", "metro_m4", "trinket_m0"), "esp8266", "esp32", "metro_m4", "trinket_m0"),
"arcada_platforms" : ("pybadge", "pygamer", "hallowing_m4", "arcada_platforms" : ("pybadge", "pygamer", "hallowing_m4",
"cpb", "cpx_ada"), "cpb", "cpx_ada"),
"wippersnapper_platforms" : ("metro_m4_airliftlite_tinyusb", "pyportal_tinyusb"), "wippersnapper_platforms" : ("metro_m4_airliftlite_tinyusb", "pyportal_tinyusb"),
"rp2040_platforms" : ("pico_rp2040", "feather_rp2040", "feather_rp2350") "rp2040_platforms" : ("pico_rp2040", "feather_rp2040")
} }

View file

@ -2,7 +2,6 @@ import sys
import glob import glob
import time import time
import os import os
import re
import shutil import shutil
import subprocess import subprocess
import collections import collections
@ -62,20 +61,8 @@ elif "METROX-Examples-and-Project-Sketches" in BUILD_DIR:
CROSS = u'\N{cross mark}' CROSS = u'\N{cross mark}'
CHECK = u'\N{check mark}' CHECK = u'\N{check mark}'
BSP_URLS = (
"https://adafruit.github.io/arduino-board-index/package_adafruit_index.json,"
"http://arduino.esp8266.com/stable/package_esp8266com_index.json,"
#"https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json," # esp32 beta release
"https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json,"
"https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json,"
"https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json,"
"https://drazzy.good-enough.cloud/package_drazzy.com_index.json,"
"https://github.com/openwch/board_manager_files/raw/main/package_ch32v_index.json"
)
# global exit code
success = 0
BSP_URLS = "https://adafruit.github.io/arduino-board-index/package_adafruit_index.json,http://arduino.esp8266.com/stable/package_esp8266com_index.json,https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json,https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json,https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json,http://drazzy.com/package_drazzy.com_index.json"
class ColorPrint: class ColorPrint:
@ -99,7 +86,6 @@ class ColorPrint:
def print_bold(message, end = '\n'): def print_bold(message, end = '\n'):
sys.stdout.write('\x1b[1;37m' + message.strip() + '\x1b[0m' + end) sys.stdout.write('\x1b[1;37m' + message.strip() + '\x1b[0m' + end)
def manually_install_esp32_bsp(repo_info): def manually_install_esp32_bsp(repo_info):
print("Manually installing latest ESP32 BSP...") print("Manually installing latest ESP32 BSP...")
# Assemble git url # Assemble git url
@ -134,18 +120,13 @@ def manually_install_esp32_bsp(repo_info):
print(out) print(out)
print("Installed ESP32 BSP from source!") print("Installed ESP32 BSP from source!")
def install_platform(fqbn, full_platform_name=None): def install_platform(fqbn, full_platform_name=None):
if os.path.exists("/home/runner/.arduino15/package_drazzy.json"):
print("Moving drazzy.json")
shutil.move("/home/runner/.arduino15/package_drazzy.json", "/home/runner/.arduino15/package_drazzy.com_index.json")
print("Installing", fqbn, end=" ") print("Installing", fqbn, end=" ")
if fqbn == "adafruit:avr": # we have a platform dep if fqbn == "adafruit:avr": # we have a platform dep
install_platform("arduino:avr", full_platform_name) install_platform("arduino:avr", full_platform_name)
if full_platform_name[2] is not None: if full_platform_name[2] is not None:
manually_install_esp32_bsp(full_platform_name[2]) # build esp32 bsp from desired source and branch manually_install_esp32_bsp(full_platform_name[2]) # build esp32 bsp from desired source and branch
for retry in range(0, 3): for retry in range(0, 3):
print("arduino-cli core install "+fqbn+" --additional-urls "+BSP_URLS)
if os.system("arduino-cli core install "+fqbn+" --additional-urls "+BSP_URLS+" > /dev/null") == 0: if os.system("arduino-cli core install "+fqbn+" --additional-urls "+BSP_URLS+" > /dev/null") == 0:
break break
print("...retrying...", end=" ") print("...retrying...", end=" ")
@ -158,7 +139,6 @@ def install_platform(fqbn, full_platform_name=None):
# print installed core version # print installed core version
print(os.popen('arduino-cli core list | grep {}'.format(fqbn)).read(), end='') print(os.popen('arduino-cli core list | grep {}'.format(fqbn)).read(), end='')
def run_or_die(cmd, error): def run_or_die(cmd, error):
print(cmd) print(cmd)
attempt = 0 attempt = 0
@ -171,81 +151,66 @@ def run_or_die(cmd, error):
ColorPrint.print_fail(error) ColorPrint.print_fail(error)
exit(-1) exit(-1)
################################ Install Arduino IDE
print()
ColorPrint.print_info('#'*40)
print("INSTALLING ARDUINO BOARDS")
ColorPrint.print_info('#'*40)
def is_library_installed(lib_name): run_or_die("arduino-cli core update-index --additional-urls "+BSP_URLS+
" > /dev/null", "FAILED to update core indices")
print()
################################ Install dependencies
our_name=None
try:
if IS_LEARNING_SYS:
libprop = open(BUILD_DIR+'/library.deps')
else:
libprop = open(BUILD_DIR+'/library.properties')
for line in libprop:
if line.startswith("name="):
our_name = line.replace("name=", "").strip()
if line.startswith("depends="):
deps = line.replace("depends=", "").split(",")
for dep in deps:
dep = dep.strip()
print("Installing "+dep)
run_or_die('arduino-cli lib install "'+dep+'" > /dev/null',
"FAILED to install dependency "+dep)
except OSError:
print("No library dep or properties found!")
pass # no library properties
# Delete the existing library if we somehow downloaded
# due to dependencies
if our_name:
run_or_die("arduino-cli lib uninstall \""+our_name+"\"", "Could not uninstall")
print("Libraries installed: ", glob.glob(os.environ['HOME']+'/Arduino/libraries/*'))
# link our library folder to the arduino libraries folder
if not IS_LEARNING_SYS:
try: try:
installed_libs = subprocess.check_output(["arduino-cli", "lib", "list"]).decode("utf-8") os.symlink(BUILD_DIR, os.environ['HOME']+'/Arduino/libraries/' + os.path.basename(BUILD_DIR))
return not all(not item for item in [re.match('^'+lib_name+'\\s*\\d+\\.', line) for line in installed_libs.split('\n')]) except FileExistsError:
except subprocess.CalledProcessError as e: pass
print("Error checking installed libraries:", e)
return False
def install_library_deps():
print()
ColorPrint.print_info('#'*40)
print("INSTALLING ARDUINO LIBRARIES")
ColorPrint.print_info('#'*40)
run_or_die("arduino-cli core update-index --additional-urls "+BSP_URLS+
" > /dev/null", "FAILED to update core indices")
print()
# Install dependencies
our_name = None
try:
if IS_LEARNING_SYS:
libprop = open(BUILD_DIR+'/library.deps')
else:
libprop = open(BUILD_DIR+'/library.properties')
for line in libprop:
if line.startswith("name="):
our_name = line.replace("name=", "").strip()
if line.startswith("depends="):
deps = line.replace("depends=", "").split(",")
for dep in deps:
dep = dep.strip()
if not is_library_installed(dep):
print("Installing "+dep)
run_or_die('arduino-cli lib install "'+dep+'" > /dev/null',
"FAILED to install dependency "+dep)
else:
print("Skipping already installed lib: "+dep)
except OSError:
print("No library dep or properties found!")
pass # no library properties
# Delete the existing library if we somehow downloaded
# due to dependencies
if our_name:
run_or_die("arduino-cli lib uninstall \""+our_name+"\"", "Could not uninstall")
print("Libraries installed: ", glob.glob(os.environ['HOME']+'/Arduino/libraries/*'))
# link our library folder to the arduino libraries folder
if not IS_LEARNING_SYS:
try:
os.symlink(BUILD_DIR, os.environ['HOME']+'/Arduino/libraries/' + os.path.basename(BUILD_DIR))
except FileExistsError:
pass
################################ UF2 Utils. ################################ UF2 Utils.
def glob01(pattern): def glob01(pattern):
result = glob.glob(pattern) result = glob.glob(pattern)
if len(result) > 1: if len(result) > 1:
raise RuntimeError(f"Required pattern {pattern} to match at most 1 file, got {result}") raise RuntimeError(f"Required pattern {pattern} to match at most 1 file, got {result}")
return result[0] if result else None return result[0] if result else None
def glob1(pattern): def glob1(pattern):
result = glob.glob(pattern) result = glob.glob(pattern)
if len(result) != 1: if len(result) != 1:
raise RuntimeError(f"Required pattern {pattern} to match exactly 1 file, got {result}") raise RuntimeError(f"Required pattern {pattern} to match exactly 1 file, got {result}")
return result[0] return result[0]
def download_uf2_utils(): def download_uf2_utils():
"""Downloads uf2conv tools if we don't already have them """Downloads uf2conv tools if we don't already have them
""" """
@ -261,12 +226,10 @@ def download_uf2_utils():
return False return False
return True return True
def generate_uf2(example_path):
def generate_uf2(platform, fqbn, example_path):
"""Generates a .uf2 file from a .bin or .hex file. """Generates a .uf2 file from a .bin or .hex file.
:param str platform: The platform name.
:param str fqbn: The fully qualified board name.
:param str example_path: A path to the compiled .bin or .hex file. :param str example_path: A path to the compiled .bin or .hex file.
""" """
if not download_uf2_utils(): if not download_uf2_utils():
return None return None
@ -313,6 +276,21 @@ def generate_uf2(platform, fqbn, example_path):
return None return None
return output_file return output_file
################################ Test platforms
platforms = []
success = 0
# expand groups:
for arg in sys.argv[1:]:
platform = ALL_PLATFORMS.get(arg, None)
if isinstance(platform, list):
platforms.append(arg)
elif isinstance(platform, tuple):
for p in platform:
platforms.append(p)
else:
print("Unknown platform: ", arg)
exit(-1)
@contextmanager @contextmanager
def group_output(title): def group_output(title):
@ -328,42 +306,25 @@ def group_output(title):
sys.stdout.flush() sys.stdout.flush()
def test_examples_in_folder(platform, folderpath): def test_examples_in_folder(folderpath):
global success global success
fqbn = ALL_PLATFORMS[platform][0]
for example in sorted(os.listdir(folderpath)): for example in sorted(os.listdir(folderpath)):
examplepath = folderpath+"/"+example examplepath = folderpath+"/"+example
if os.path.isdir(examplepath): if os.path.isdir(examplepath):
test_examples_in_folder(platform, examplepath) test_examples_in_folder(examplepath)
continue continue
if not examplepath.endswith(".ino"): if not examplepath.endswith(".ino"):
continue continue
print('\t'+example, end=' ') print('\t'+example, end=' ')
# check if we should SKIP # check if we should SKIP
skipfilename = folderpath+"/."+platform+".test.skip" skipfilename = folderpath+"/."+platform+".test.skip"
onlyfilename = folderpath+"/."+platform+".test.only" onlyfilename = folderpath+"/."+platform+".test.only"
# check if we should GENERATE UF2 # check if we should GENERATE UF2
gen_file_name = folderpath+"/."+platform+".generate" gen_file_name = folderpath+"/."+platform+".generate"
# .skip txt include all skipped platforms, one per line
skip_txt = folderpath+"/.skip.txt"
is_skip = False
if os.path.exists(skipfilename): if os.path.exists(skipfilename):
is_skip = True
if os.path.exists(skip_txt):
with open(skip_txt) as f:
lines = f.readlines()
for line in lines:
if line.strip() == platform:
is_skip = True
break
if is_skip:
ColorPrint.print_warn("skipping") ColorPrint.print_warn("skipping")
continue continue
if glob.glob(folderpath+"/.*.test.only"): if glob.glob(folderpath+"/.*.test.only"):
platformname = glob.glob(folderpath+"/.*.test.only")[0].split('.')[1] platformname = glob.glob(folderpath+"/.*.test.only")[0].split('.')[1]
if platformname != "none" and not platformname in ALL_PLATFORMS: if platformname != "none" and not platformname in ALL_PLATFORMS:
@ -405,11 +366,11 @@ def test_examples_in_folder(platform, folderpath):
with group_output(f"{example} {fqbn} build output"): with group_output(f"{example} {fqbn} build output"):
ColorPrint.print_fail(err.decode("utf-8")) ColorPrint.print_fail(err.decode("utf-8"))
if os.path.exists(gen_file_name): if os.path.exists(gen_file_name):
if ALL_PLATFORMS[platform][1] is None: if ALL_PLATFORMS[platform][1] == None:
ColorPrint.print_info("Platform does not support UF2 files, skipping...") ColorPrint.print_info("Platform does not support UF2 files, skipping...")
else: else:
ColorPrint.print_info("Generating UF2...") ColorPrint.print_info("Generating UF2...")
filename = generate_uf2(platform, fqbn, folderpath) filename = generate_uf2(folderpath)
if filename is None: if filename is None:
success = 1 # failure success = 1 # failure
if IS_LEARNING_SYS: if IS_LEARNING_SYS:
@ -425,38 +386,53 @@ def test_examples_in_folder(platform, folderpath):
ColorPrint.print_fail(err.decode("utf-8")) ColorPrint.print_fail(err.decode("utf-8"))
success = 1 success = 1
def test_examples_in_learningrepo(folderpath):
global success
for project in os.listdir(folderpath):
projectpath = folderpath+"/"+project
if os.path.isdir(learningrepo):
test_examples_in_learningrepo(projectpath)
continue
if not projectpath.endswith(".ino"):
continue
# found an INO!
print('\t'+projectpath, end=' ', flush=True)
# check if we should SKIP
skipfilename = folderpath+"/."+platform+".test.skip"
onlyfilename = folderpath+"/."+platform+".test.only"
if os.path.exists(skipfilename):
ColorPrint.print_warn("skipping")
continue
elif glob.glob(folderpath+"/.*.test.only") and not os.path.exists(onlyfilename):
ColorPrint.print_warn("skipping")
continue
def main(): cmd = ['arduino-cli', 'compile', '--warnings', 'all', '--fqbn', fqbn, projectpath]
# Test platforms proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
platforms = [] stderr=subprocess.PIPE)
r = proc.wait()
# expand groups: out = proc.stdout.read()
for arg in sys.argv[1:]: err = proc.stderr.read()
platform = ALL_PLATFORMS.get(arg, None) if r == 0:
if isinstance(platform, list): ColorPrint.print_pass(CHECK)
platforms.append(arg) if err:
elif isinstance(platform, tuple): # also print out warning message
for p in platform: ColorPrint.print_fail(err.decode("utf-8"))
platforms.append(p)
else: else:
print("Unknown platform: ", arg) ColorPrint.print_fail(CROSS)
exit(-1) ColorPrint.print_fail(out.decode("utf-8"))
ColorPrint.print_fail(err.decode("utf-8"))
# Install libraries deps success = 1
install_library_deps()
for platform in platforms:
fqbn = ALL_PLATFORMS[platform][0]
print('#'*80)
ColorPrint.print_info("SWITCHING TO "+fqbn)
install_platform(":".join(fqbn.split(':', 2)[0:2]), ALL_PLATFORMS[platform]) # take only first two elements
print('#'*80)
if not IS_LEARNING_SYS:
test_examples_in_folder(platform, BUILD_DIR+"/examples")
else:
test_examples_in_folder(platform, BUILD_DIR)
if __name__ == "__main__": for platform in platforms:
main() fqbn = ALL_PLATFORMS[platform][0]
exit(success) print('#'*80)
ColorPrint.print_info("SWITCHING TO "+fqbn)
install_platform(":".join(fqbn.split(':', 2)[0:2]), ALL_PLATFORMS[platform]) # take only first two elements
print('#'*80)
if not IS_LEARNING_SYS:
test_examples_in_folder(BUILD_DIR+"/examples")
else:
test_examples_in_folder(BUILD_DIR)
exit(success)

View file

@ -18,7 +18,6 @@ __AUTHOR__="Jeroen de Bruijn, modified by ladyada"
# Optional global variables: # Optional global variables:
# - DOXYFILE : The Doxygen configuration file. # - DOXYFILE : The Doxygen configuration file.
# - PRETTYNAME : A string name of the project (for the doxy headers) # - PRETTYNAME : A string name of the project (for the doxy headers)
# - PRESERVE_FOLDERS : Comma-separated list of folders to preserve during cleanup
# #
# For information on how to encrypt variables for Travis CI please go to # For information on how to encrypt variables for Travis CI please go to
# https://docs.travis-ci.com/user/environment-variables/#Encrypted-Variables # https://docs.travis-ci.com/user/environment-variables/#Encrypted-Variables
@ -85,19 +84,6 @@ git config --global push.default simple
git config user.name "Doxygen CI" git config user.name "Doxygen CI"
git config user.email "ci-arduino@invalid" git config user.email "ci-arduino@invalid"
# Check if PRESERVE_FOLDERS is set and back them up
if [ -n "$PRESERVE_FOLDERS" ]; then
echo "Preserving folders: $PRESERVE_FOLDERS"
mkdir -p /tmp/preserved
# Move preserved folders to temp dir
for folder in ${PRESERVE_FOLDERS//,/ }; do
if [ -d "$folder" ]; then
echo "Backing up folder: $folder"
cp -r "$folder" /tmp/preserved/
fi
done
fi
# Remove everything currently in the gh-pages branch. # Remove everything currently in the gh-pages branch.
# GitHub is smart enough to know which files have changed and which files have # GitHub is smart enough to know which files have changed and which files have
# stayed the same and will only update the changed files. So the gh-pages branch # stayed the same and will only update the changed files. So the gh-pages branch
@ -113,16 +99,6 @@ else
rm -r -- !(index.html) || true rm -r -- !(index.html) || true
fi fi
# Restore preserved folders if they were backed up
if [ -n "$PRESERVE_FOLDERS" ]; then
for folder in ${PRESERVE_FOLDERS//,/ }; do
if [ -d "/tmp/preserved/$folder" ]; then
echo "Restoring folder: $folder"
cp -r "/tmp/preserved/$folder" ./
fi
done
fi
# Need to create a .nojekyll file to allow filenames starting with an underscore # Need to create a .nojekyll file to allow filenames starting with an underscore
# to be seen on the gh-pages site. Therefore creating an empty .nojekyll file. # to be seen on the gh-pages site. Therefore creating an empty .nojekyll file.
# Presumably this is only needed when the SHORT_NAMES option in Doxygen is set # Presumably this is only needed when the SHORT_NAMES option in Doxygen is set