|
| 1 | +# |
| 2 | + |
| 3 | +name: HIL-circuitpython |
| 4 | + |
| 5 | +on: |
| 6 | + pull_request: |
| 7 | + branches: [ main ] |
| 8 | + paths: |
| 9 | + # This is quite a big job so run only when files affecting it change. |
| 10 | + - .github/workflows/hil-circuitpython.yml |
| 11 | + - examples/notecard-basics/cpy_example.py |
| 12 | + - test/hitl/** |
| 13 | + - test/scripts/usbmount |
| 14 | + - test/scripts/check_cpy*.* |
| 15 | + - notecard/** |
| 16 | + |
| 17 | + workflow_dispatch: |
| 18 | + inputs: |
| 19 | + flash_device: |
| 20 | + required: false |
| 21 | + type: boolean |
| 22 | + default: true |
| 23 | + |
| 24 | +jobs: |
| 25 | + test: |
| 26 | + runs-on: [self-hosted, linux, circuitpython, swan-3.0, notecard-serial] |
| 27 | + defaults: |
| 28 | + run: |
| 29 | + shell: bash |
| 30 | + strategy: |
| 31 | + matrix: |
| 32 | + CIRCUITPYTHON_VERSION: [8.2.2] |
| 33 | + flash_device: # has to be an array - use the input from workflow_dispatch if present, otherwlse true |
| 34 | + - ${{ github.event.inputs.flash_device=='' && true || github.event.inputs.flash_device }} |
| 35 | + lock_cpy_filesystem: [true] |
| 36 | + env: |
| 37 | + USB_MSD_ATTACH_TIME: 15 |
| 38 | + CIRCUITPYTHON_UF2: "adafruit-circuitpython-swan_r5-en_US-${{ matrix.CIRCUITPYTHON_VERSION }}.uf2" |
| 39 | + CIRCUITPYTHON_VERSION: ${{ matrix.CIRCUITPYTHON_VERSION}} |
| 40 | + steps: |
| 41 | + - name: Checkout Code |
| 42 | + uses: actions/checkout@v3 |
| 43 | + |
| 44 | + - name: Set Env Vars |
| 45 | + run: | |
| 46 | + # environment variables set in a step cannot be used until subsequent steps |
| 47 | + echo "CIRCUITPYTHON_UF2_URL=https://downloads.circuitpython.org/bin/swan_r5/en_US/${CIRCUITPYTHON_UF2}" >> $GITHUB_ENV |
| 48 | +
|
| 49 | + - name: Check Runner Config |
| 50 | + run: test/scripts/check_cpy_runner_config.sh |
| 51 | + |
| 52 | + - name: Download Latest Bootloader |
| 53 | + env: |
| 54 | + REPO: adafruit/tinyuf2 |
| 55 | + ASSET: tinyuf2-swan_r5 |
| 56 | + if: ${{ matrix.flash_device }} |
| 57 | + run: | |
| 58 | + echo "retrieving the latest release from ${REPO}" |
| 59 | + wget -q -O latest.json "https://api.github.com/repos/${REPO}/releases/latest" |
| 60 | +
|
| 61 | + echo "extracting asset details for ${ASSET}" |
| 62 | + asset_file="${ASSET}_asset.json" |
| 63 | + jq -r --arg ASSET "$ASSET" '.assets[] | select(.name | startswith($ASSET))' latest.json > $asset_file |
| 64 | +
|
| 65 | + # extract the name and download url without double quotes |
| 66 | + download_name=$(jq -r '.name' $asset_file) |
| 67 | + download_url=$(jq -r '.browser_download_url' $asset_file) |
| 68 | + echo "Downloading release from $download_url" |
| 69 | + wget -q -N $download_url |
| 70 | + unzip -o $download_name |
| 71 | + binfile=$(basename $download_name .zip).bin |
| 72 | + echo "TINYUF2_BIN=$binfile" >> $GITHUB_ENV |
| 73 | +
|
| 74 | + - name: Download CircuitPython v${{ env.CIRCUITPYTHON_VERSION }} |
| 75 | + if: ${{ matrix.flash_device }} |
| 76 | + run: | |
| 77 | + echo "Downloading CircuitPython for Swan from $CIRCUITPYTHON_UF2_URL" |
| 78 | + wget -q -N "$CIRCUITPYTHON_UF2_URL" |
| 79 | +
|
| 80 | + - name: Erase device and program bootloader |
| 81 | + if: ${{ matrix.flash_device }} |
| 82 | + run: | |
| 83 | + # cannot use st-flash - every 2nd programing incorrectly puts the device in DFU mode |
| 84 | + # st-flash --reset write $binfile 0x8000000 |
| 85 | + # Have to use the version of openocd bundled with the STM32 platform in PlatformIO, which (presumably) has the stm32 extensions compiled in |
| 86 | + ~/.platformio/packages/tool-openocd/bin/openocd \ |
| 87 | + -d2 -s ~/.platformio/packages/tool-openocd/openocd/scripts \ |
| 88 | + -f interface/stlink.cfg -c "transport select hla_swd" -f target/stm32l4x.cfg \ |
| 89 | + -c "init; halt; stm32l4x mass_erase 0" \ |
| 90 | + -c "program $TINYUF2_BIN 0x8000000 verify reset; shutdown" |
| 91 | +
|
| 92 | + - name: Program CircuitPython |
| 93 | + if: ${{ matrix.flash_device }} |
| 94 | + run: | |
| 95 | + # wait for the bootloader drive to appear |
| 96 | + timeout $USB_MSD_ATTACH_TIME bash test/scripts/wait_for_file.sh "$CPY_FS_UF2" |
| 97 | +
|
| 98 | + # The bootloader reboots quickly once the whole file has been received, |
| 99 | + # causing an input/output error to be reported. |
| 100 | + # Ignore that, and fail if the CIRCUITPY filesystem doesn't appear |
| 101 | + echo "Uploading CircuitPython binary..." |
| 102 | + cp "$CIRCUITPYTHON_UF2" "$CPY_FS_UF2" || true |
| 103 | + echo Ignore the input/output error above. Waiting for device to boot. |
| 104 | + timeout $USB_MSD_ATTACH_TIME bash test/scripts/wait_for_file.sh "$CPY_FS_CIRCUITPY" |
| 105 | + echo "CircuitPython binary uploaded and running." |
| 106 | +
|
| 107 | + - name: Make CircuitPython filesystem writeable to pyboard |
| 108 | + if: ${{ matrix.lock_cpy_filesystem }} |
| 109 | + run: | |
| 110 | + timeout $USB_MSD_ATTACH_TIME bash test/scripts/wait_for_file.sh "$CPY_FS_CIRCUITPY" |
| 111 | +
|
| 112 | + # only copy if it's changed or not present. After the device has reset, no further changes can be made |
| 113 | + # until the filesystem is erased. This allows the workflow to be rerun flash_device=false |
| 114 | + diff test/hitl/boot.py "$CPY_FS_CIRCUITPY/boot.py" || cp test/hitl/boot.py "$CPY_FS_CIRCUITPY" |
| 115 | +
|
| 116 | + # reset the device (todo move this blob to a utility script) |
| 117 | + ~/.platformio/packages/tool-openocd/bin/openocd \ |
| 118 | + -d2 -s ~/.platformio/packages/tool-openocd/openocd/scripts \ |
| 119 | + -f interface/stlink.cfg -c "transport select hla_swd" -f target/stm32l4x.cfg \ |
| 120 | + -c "init; halt; reset; shutdown" |
| 121 | +
|
| 122 | + # wait for the device to come back |
| 123 | + timeout $USB_MSD_ATTACH_TIME bash test/scripts/wait_for_file.sh "$CPY_FS_CIRCUITPY" |
| 124 | +
|
| 125 | + - name: Setup Python |
| 126 | + run: | |
| 127 | + python3 -m venv .venv-runner |
| 128 | + . .venv-runner/bin/activate |
| 129 | + pip install -r test/hitl/requirements.txt |
| 130 | +
|
| 131 | + - name: Setup 'note-python' on device |
| 132 | + if: ${{ ! matrix.lock_cpy_filesystem }} |
| 133 | + run: | |
| 134 | + mkdir -p ${CPY_FS_CIRCUITPY}/lib/notecard |
| 135 | + cp notecard/*.py ${CPY_FS_CIRCUITPY}/lib/notecard/ |
| 136 | + cp examples/notecard-basics/cpy_example.py ${CPY_FS_CIRCUITPY}/example.py |
| 137 | +
|
| 138 | + - name: Run CircuitPython Tests |
| 139 | + run: | |
| 140 | + . .venv-runner/bin/activate |
| 141 | + ${{ ! matrix.lock_cpy_filesystem }} && skipsetup=--skipsetup |
| 142 | + pytest $skipsetup "--productuid=$CPY_PRODUCT_UID" "--port=$CPY_SERIAL" --platform=circuitpython test/hitl |
0 commit comments