mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 22:02:17 +01:00
A coverage env (the native env with gcov counters) runs the native tests in CI; gcovr writes the HTML report and a table on the run's summary page. The web UI tests report coverage with Node's built-in coverage, and genhtml turns its lcov into HTML. Both reports are run artifacts, and pushes to main publish them to GitHub Pages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
354 lines
12 KiB
YAML
354 lines
12 KiB
YAML
name: ESPSomfy-RTS Build
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
release:
|
|
types: [published]
|
|
|
|
jobs:
|
|
test:
|
|
name: Unit tests
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
# pioarduino's fork of PlatformIO Core, which the pioarduino platform needs.
|
|
# Pinned: 6.2.0.post1 reports itself as 6.2.0-post.1, which the
|
|
# platform's ">=6.2.0" reads as a pre-release and refuses.
|
|
- name: Install PlatformIO and gcovr
|
|
run: pip install pioarduino==6.2.0 gcovr==8.8
|
|
|
|
# The coverage env is the native env with gcov counters: the same
|
|
# tests, measured.
|
|
- name: Run native unit tests
|
|
run: pio test -e coverage
|
|
|
|
# gcovr.cfg picks the files; the table goes to the run's summary page.
|
|
- name: Coverage report
|
|
run: |
|
|
mkdir -p coverage
|
|
gcovr --html-details coverage/index.html \
|
|
--markdown "$GITHUB_STEP_SUMMARY" --markdown-title "Native tests coverage"
|
|
|
|
- name: Upload coverage report
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: coverage-cpp
|
|
path: coverage/
|
|
retention-days: 14
|
|
|
|
webui:
|
|
name: Web UI tests
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Check out code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "22"
|
|
|
|
# The protocol 2 client (data-src/js) against the recorded fixtures.
|
|
# Coverage: a table in the log, and lcov for the HTML report.
|
|
- name: Run web UI tests
|
|
run: |
|
|
mkdir -p coverage
|
|
node --test --experimental-test-coverage \
|
|
--test-coverage-include="data-src/js/**" \
|
|
--test-reporter=spec --test-reporter-destination=stdout \
|
|
--test-reporter=lcov --test-reporter-destination=coverage/lcov.info \
|
|
"test/js/*.test.js"
|
|
|
|
- name: Coverage report
|
|
run: |
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y -qq lcov
|
|
genhtml coverage/lcov.info --output-directory coverage/html \
|
|
--title "ESPSomfy-RTS web UI tests"
|
|
|
|
- name: Upload coverage report
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: coverage-js
|
|
path: coverage/html/
|
|
retention-days: 14
|
|
|
|
# The coverage of main on the repo's GitHub Pages site
|
|
# (Settings > Pages > Source: GitHub Actions).
|
|
coverage-pages:
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
needs: [test, webui]
|
|
name: Publish coverage
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
pages: write
|
|
id-token: write
|
|
environment:
|
|
name: github-pages
|
|
url: ${{ steps.deploy.outputs.page_url }}
|
|
concurrency:
|
|
group: pages
|
|
cancel-in-progress: false
|
|
|
|
steps:
|
|
- name: Download native tests coverage
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: coverage-cpp
|
|
path: site/cpp
|
|
|
|
- name: Download web UI tests coverage
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: coverage-js
|
|
path: site/js
|
|
|
|
- name: Index page
|
|
run: |
|
|
cat > site/index.html <<EOF
|
|
<!doctype html>
|
|
<meta charset="utf-8">
|
|
<title>ESPSomfy-RTS coverage</title>
|
|
<h1>ESPSomfy-RTS test coverage</h1>
|
|
<p>main at <a href="${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}">${GITHUB_SHA::7}</a>, $(date -u '+%Y-%m-%d %H:%M UTC')</p>
|
|
<ul>
|
|
<li><a href="cpp/">Native tests</a> (pio test -e native): only the sources the native env builds</li>
|
|
<li><a href="js/">Web UI tests</a> (data-src/js)</li>
|
|
</ul>
|
|
EOF
|
|
|
|
- name: Upload site
|
|
uses: actions/upload-pages-artifact@v3
|
|
with:
|
|
path: site
|
|
|
|
- name: Deploy to GitHub Pages
|
|
id: deploy
|
|
uses: actions/deploy-pages@v4
|
|
|
|
build:
|
|
# Don't build or publish firmware that fails its tests.
|
|
needs: [test, webui]
|
|
permissions: write-all
|
|
name: ${{ matrix.name }}
|
|
runs-on: ubuntu-latest
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# fwname: firmware-only binary for OTA updates
|
|
# elfname: the symbols of that binary, to decode a crash's backtrace
|
|
# obname: onboard image (bootloader + partitions + firmware + littlefs merged)
|
|
# for flashing a new chip via USB/serial
|
|
# addr_bootloader: chip-dependent (ESP32: 0x1000, S3/C3/C6: 0x0, C5/P4: 0x2000)
|
|
# addr_fs: must match the spiffs offset in the env's partition table
|
|
# (0x310000 in both esp32_3MB.csv and esp32_huge_app.csv)
|
|
include:
|
|
- env: esp32dev
|
|
name: ESP32
|
|
chip: ESP32
|
|
addr_bootloader: "0x1000"
|
|
addr_fs: "0x310000"
|
|
fwname: SomfyController.ino.esp32.bin
|
|
elfname: SomfyController.ino.esp32.elf
|
|
fsname: SomfyController.littlefs.esp32.bin
|
|
obname: SomfyController.onboard.esp32.bin
|
|
- env: esp32s3
|
|
name: ESP32-S3
|
|
chip: ESP32-S3
|
|
addr_bootloader: "0x0"
|
|
addr_fs: "0x670000"
|
|
fwname: SomfyController.ino.esp32s3.bin
|
|
elfname: SomfyController.ino.esp32s3.elf
|
|
fsname: SomfyController.littlefs.esp32s3.bin
|
|
obname: SomfyController.onboard.esp32s3.bin
|
|
- env: esp32c3
|
|
name: ESP32-C3
|
|
chip: ESP32-C3
|
|
addr_bootloader: "0x0"
|
|
addr_fs: "0x310000"
|
|
fwname: SomfyController.ino.esp32c3.bin
|
|
elfname: SomfyController.ino.esp32c3.elf
|
|
fsname: SomfyController.littlefs.esp32c3.bin
|
|
obname: SomfyController.onboard.esp32c3.bin
|
|
- env: esp32c5
|
|
name: ESP32-C5
|
|
chip: ESP32-C5
|
|
addr_bootloader: "0x2000"
|
|
addr_fs: "0x310000"
|
|
fwname: SomfyController.ino.esp32c5.bin
|
|
elfname: SomfyController.ino.esp32c5.elf
|
|
fsname: SomfyController.littlefs.esp32c5.bin
|
|
obname: SomfyController.onboard.esp32c5.bin
|
|
- env: esp32c6
|
|
name: ESP32-C6
|
|
chip: ESP32-C6
|
|
addr_bootloader: "0x0"
|
|
addr_fs: "0x310000"
|
|
fwname: SomfyController.ino.esp32c6.bin
|
|
elfname: SomfyController.ino.esp32c6.elf
|
|
fsname: SomfyController.littlefs.esp32c6.bin
|
|
obname: SomfyController.onboard.esp32c6.bin
|
|
- env: esp32p4
|
|
name: ESP32-P4
|
|
chip: ESP32-P4
|
|
addr_bootloader: "0x2000"
|
|
addr_fs: "0x310000"
|
|
fwname: SomfyController.ino.esp32p4.bin
|
|
elfname: SomfyController.ino.esp32p4.elf
|
|
fsname: SomfyController.littlefs.esp32p4.bin
|
|
obname: SomfyController.onboard.esp32p4.bin
|
|
- env: esp32p4es
|
|
name: ESP32-P4 (before v2.0)
|
|
chip: ESP32-P4
|
|
addr_bootloader: "0x2000"
|
|
addr_fs: "0x310000"
|
|
fwname: SomfyController.ino.esp32p4es.bin
|
|
elfname: SomfyController.ino.esp32p4es.elf
|
|
fsname: SomfyController.littlefs.esp32p4es.bin
|
|
obname: SomfyController.onboard.esp32p4es.bin
|
|
|
|
steps:
|
|
- name: Get Release
|
|
if: github.event_name == 'release'
|
|
id: get_release
|
|
uses: bruceadams/get-release@v1.3.2
|
|
env:
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
|
|
- name: Check out code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Update version from release tag
|
|
if: github.event_name == 'release'
|
|
run: |
|
|
VERSION="${{ github.event.release.tag_name }}"
|
|
VERSION="${VERSION#v}"
|
|
sed -i "s/#define FW_VERSION \"v[0-9.]*\"/#define FW_VERSION \"v${VERSION}\"/" src/ConfigSettings.h
|
|
sed -i "s/^[0-9.].*/${VERSION}/" data-src/appversion
|
|
sed -i "s/\?v=[0-9.]*c/?v=${VERSION}c/g" data-src/index.html
|
|
sed -i "s/appVersion = 'v[0-9.]*'/appVersion = 'v${VERSION}'/" data-src/index.js
|
|
|
|
- name: Commit version update
|
|
if: github.event_name == 'release' && matrix.env == 'esp32dev'
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add src/ConfigSettings.h data-src/appversion data-src/index.html data-src/index.js
|
|
git commit -m "chore: bump version to ${{ github.event.release.tag_name }}"
|
|
git push origin HEAD:${{ github.event.release.target_commitish }}
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: Install PlatformIO and esptool
|
|
run: pip install pioarduino==6.2.0 esptool
|
|
|
|
- name: Build LittleFS image
|
|
run: pio run -e ${{ matrix.env }} -t buildfs
|
|
|
|
- name: Save LittleFS image
|
|
run: cp .pio/build/${{ matrix.env }}/littlefs.bin littlefs.bin
|
|
|
|
- name: Build firmware
|
|
run: pio run -e ${{ matrix.env }}
|
|
|
|
- name: Check firmware size
|
|
run: python .github/size_check.py .pio/build/${{ matrix.env }} ${{ matrix.env }} 8
|
|
|
|
- name: Restore LittleFS image
|
|
run: cp littlefs.bin .pio/build/${{ matrix.env }}/littlefs.bin
|
|
|
|
- name: List build artifacts
|
|
run: find .pio/build/${{ matrix.env }} -maxdepth 1 -name "*.bin" | sort
|
|
|
|
- name: Create onboard image
|
|
run: |
|
|
python -m esptool --chip ${{ matrix.chip }} \
|
|
merge-bin -o ${{ matrix.obname }} \
|
|
${{ matrix.addr_bootloader }} .pio/build/${{ matrix.env }}/bootloader.bin \
|
|
0x8000 .pio/build/${{ matrix.env }}/partitions.bin \
|
|
0x10000 .pio/build/${{ matrix.env }}/firmware.bin \
|
|
${{ matrix.addr_fs }} .pio/build/${{ matrix.env }}/littlefs.bin
|
|
|
|
- name: Compress onboard image
|
|
run: zip ${{ matrix.obname }}.zip ${{ matrix.obname }}
|
|
|
|
# A panic prints "ELF file SHA256: <first hex digits>". The .sha256 file
|
|
# beside the ELF holds the whole hash, so a crash log shows which build
|
|
# it came from.
|
|
- name: Compress ELF
|
|
run: |
|
|
cp .pio/build/${{ matrix.env }}/firmware.elf ${{ matrix.elfname }}
|
|
sha256sum ${{ matrix.elfname }} > ${{ matrix.elfname }}.sha256
|
|
cat ${{ matrix.elfname }}.sha256
|
|
zip -9 ${{ matrix.elfname }}.zip ${{ matrix.elfname }} ${{ matrix.elfname }}.sha256
|
|
|
|
- name: Upload artifacts
|
|
if: github.event_name != 'release'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ${{ matrix.name }}
|
|
path: |
|
|
.pio/build/${{ matrix.env }}/firmware.bin
|
|
.pio/build/${{ matrix.env }}/firmware.elf
|
|
.pio/build/${{ matrix.env }}/partitions.bin
|
|
.pio/build/${{ matrix.env }}/bootloader.bin
|
|
.pio/build/${{ matrix.env }}/littlefs.bin
|
|
${{ matrix.obname }}.zip
|
|
retention-days: 5
|
|
|
|
- name: Upload LittleFS
|
|
if: github.event_name == 'release'
|
|
uses: shogo82148/actions-upload-release-asset@v1.7.5
|
|
with:
|
|
github_token: ${{ github.token }}
|
|
upload_url: ${{ steps.get_release.outputs.upload_url }}
|
|
asset_name: ${{ matrix.fsname }}
|
|
asset_path: .pio/build/${{ matrix.env }}/littlefs.bin
|
|
overwrite: true
|
|
|
|
- name: Upload firmware
|
|
if: github.event_name == 'release'
|
|
uses: shogo82148/actions-upload-release-asset@v1.7.5
|
|
with:
|
|
github_token: ${{ github.token }}
|
|
upload_url: ${{ steps.get_release.outputs.upload_url }}
|
|
asset_name: ${{ matrix.fwname }}
|
|
asset_path: .pio/build/${{ matrix.env }}/firmware.bin
|
|
overwrite: true
|
|
|
|
- name: Upload onboard image
|
|
if: github.event_name == 'release'
|
|
uses: shogo82148/actions-upload-release-asset@v1.7.5
|
|
with:
|
|
github_token: ${{ github.token }}
|
|
upload_url: ${{ steps.get_release.outputs.upload_url }}
|
|
asset_name: ${{ matrix.obname }}.zip
|
|
asset_path: ${{ matrix.obname }}.zip
|
|
overwrite: true
|
|
asset_content_type: application/zip
|
|
|
|
- name: Upload ELF
|
|
if: github.event_name == 'release'
|
|
uses: shogo82148/actions-upload-release-asset@v1.7.5
|
|
with:
|
|
github_token: ${{ github.token }}
|
|
upload_url: ${{ steps.get_release.outputs.upload_url }}
|
|
asset_name: ${{ matrix.elfname }}.zip
|
|
asset_path: ${{ matrix.elfname }}.zip
|
|
overwrite: true
|
|
asset_content_type: application/zip
|