Skip to content

chore(deps): bump codecov/codecov-action from 4 to 5 #798

chore(deps): bump codecov/codecov-action from 4 to 5

chore(deps): bump codecov/codecov-action from 4 to 5 #798

Workflow file for this run

name: PlatformIO CI
on:
pull_request:
branches:
- master
- develop
- support/*
paths-ignore:
- "**/*.md"
push:
branches:
- master
- develop
- support/*
paths-ignore:
- "**/*.md"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
build-bhaptics:
name: Build ${{ matrix.target }} ${{ matrix.coverage && 'with coverage' || 'without coverage' }}, -D ${{ matrix.battery_flag }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest ]
target:
- bhaptics_tactsuit_x16
- bhaptics_tactsuit_x16_pca9685
- bhaptics_tactsuit_x40
- bhaptics_tactosy2_forearm_right
- bhaptics_tactosyh_hand_right
- bhaptics_tactosyf_foot_right
- bhaptics_tactal
- bhaptics_tactvisor
- bhaptics_tactglove_right
battery_flag: [ SS_BATTERY_ENABLED=true ]
coverage: [ false ]
include:
# Extra tests for x40, as it uses the most features
- target: bhaptics_tactsuit_x40
os: ubuntu-latest
coverage: true
battery_flag: SS_BATTERY_ENABLED=true
env:
PLATFORMIO_BUILD_FLAGS: >-
${{ matrix.coverage && '-lgcov --coverage' || '' }}
${{ matrix.battery_flag && format('-D {0}', matrix.battery_flag) || '' }}
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Get firmware name
id: firmware_name
run: python3 ./.github/scripts/get-firmware-name.py ${{ matrix.target }} '${{ env.PLATFORMIO_BUILD_FLAGS }}'
- name: Speedup package installation
if: matrix.coverage
uses: abbbi/github-actions-tune@v1
- name: Setup LCOV
if: matrix.coverage
uses: hrishikesh-kadam/setup-lcov@v1
- name: Cache PlatformIO target
if: matrix.coverage == false
uses: actions/cache@v4
with:
path: |
./.pio/build/${{ matrix.target }}
key: ${{ runner.os }}-pio-${{ matrix.target }}-${{ steps.firmware_name.outputs.firmware }}-${{ hashFiles('**/*.ini') }}
restore-keys: |
${{ runner.os }}-pio-${{ matrix.target }}-${{ steps.firmware_name.outputs.firmware }}-
${{ runner.os }}-pio-${{ matrix.target }}-
${{ runner.os }}-pio-
- name: Setup PlatformIO
uses: ./.github/actions/setup-platformio
with:
build_cache_dir: ./.pio/build_cache
cache: 'pip cache build_cache'
- name: Install libs
shell: bash
run: |
pio pkg install -e ${{matrix.target}}
- name: Change memory segments
if: matrix.coverage
run: |
sed -i "s/len\s=\s0x2c200\s-\s0xdb5c/len = 2898880/" ~/.platformio/packages/framework-arduinoespressif32-libs/esp32/ld/memory.ld
sed -i "/\[env\]/p; s/\[env\]/board_build.partitions = huge_app.csv/" platformio.ini
- uses: ammaraskar/gcc-problem-matcher@0.3.0
- name: Build
shell: bash
run: |
pio ${{ matrix.coverage && 'debug' || 'run' }} --environment ${{matrix.target}} | tee build.log
- name: Collect memory usage
id: memory_usage
if: matrix.coverage == false
run: |
echo "USAGE_FILENAME=${{ env.USAGE_FILENAME }}" >> $GITHUB_ENV
# RAM: [= ] 11.8% (used 38636 bytes from 327680 bytes)
# Flash: [========= ] 90.1% (used 1181501 bytes from 1310720 bytes)
# Extract the line containing RAM usage
ram_line=$(grep 'RAM:' build.log)
# Extract the line containing Flash usage
flash_line=$(grep 'Flash:' build.log)
# Parse the RAM usage details
ram_percentage=$(echo $ram_line | grep -oP '\d+\.\d+(?=%)')
ram_used=$(echo $ram_line | grep -oP '(?<=used )\d+')
ram_total=$(echo $ram_line | grep -oP '(?<=from )\d+')
# Parse the Flash usage details
flash_percentage=$(echo $flash_line | grep -oP '\d+\.\d+(?=%)')
flash_used=$(echo $flash_line | grep -oP '(?<=used )\d+')
flash_total=$(echo $flash_line | grep -oP '(?<=from )\d+')
# Store as JSON to file usage.json
echo "{\"ram\": {\"percentage\": $ram_percentage, \"used\": $ram_used, \"total\": $ram_total}, \"flash\": {\"percentage\": $flash_percentage, \"used\": $flash_used, \"total\": $flash_total}}" > ${{ env.USAGE_FILENAME }}
# Print the content of usage.json
cat ${{ env.USAGE_FILENAME }}
env:
USAGE_FILENAME: ${{ steps.firmware_name.outputs.firmware }}-usage.json
- name: Upload usage.json artifact
if: matrix.coverage == false
uses: actions/upload-artifact@v4
with:
name: ${{ steps.firmware_name.outputs.firmware }}-usage
path: ${{ env.USAGE_FILENAME }}
retention-days: 1
if-no-files-found: error
- name: Collect initial coverage
if: matrix.coverage
run: |
mkdir -p ./build/lcov
lcov -i -d ./.pio/build/${{matrix.target}}/ -c -o ./build/lcov/lcov.info.${{ steps.firmware_name.outputs.firmware }} -gcov-tool ~/.platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcov
- name: Upload coverage Artifact
uses: actions/upload-artifact@v4
if: matrix.coverage
with:
name: lcov.info.${{ steps.firmware_name.outputs.firmware }}
path: ./build/lcov/lcov.info.${{ steps.firmware_name.outputs.firmware }}
retention-days: 1
build-opengloves:
name: Build ${{ matrix.target }} ${{ matrix.coverage && 'with coverage' || 'without coverage' }}, -D ${{ matrix.comm_flag }} -D ${{ matrix.curl_calibration_flag }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest ]
target:
- opengloves_lucidgloves_proto3
- opengloves_lucidgloves_proto4
- opengloves_lucidgloves_proto4_ffb
- opengloves_indexer_c
- opengloves_indexer_cf
- opengloves_indexer_cs
- opengloves_indexer_csf
comm_flag: [ OPENGLOVES_COMMUNICATION=OPENGLOVES_COMM_SERIAL ]
coverage: [ false ]
include:
- os: ubuntu-latest
target: opengloves_lucidgloves_proto4_ffb
comm_flag: OPENGLOVES_COMMUNICATION=OPENGLOVES_COMM_BTSERIAL
- os: ubuntu-latest
target: opengloves_lucidgloves_proto4_ffb
comm_flag: OPENGLOVES_COMMUNICATION=OPENGLOVES_COMM_BLESERIAL
- os: ubuntu-latest
target: opengloves_lucidgloves_proto4_ffb
comm_flag: OPENGLOVES_COMMUNICATION=OPENGLOVES_COMM_SERIAL
curl_calibration_flag: CALIBRATION_CURL="new ::SenseShift::Input::Calibration::MinMaxCalibrator<float>()"
coverage: true
- os: ubuntu-latest
target: opengloves_lucidgloves_proto4_ffb
comm_flag: OPENGLOVES_COMMUNICATION=OPENGLOVES_COMM_BTSERIAL
curl_calibration_flag: CALIBRATION_CURL="new ::SenseShift::Input::Calibration::CenterPointDeviationCalibrator<float>(0.66F, 0.005F)"
coverage: true
- os: ubuntu-latest
target: opengloves_lucidgloves_proto4_ffb
comm_flag: OPENGLOVES_COMMUNICATION=OPENGLOVES_COMM_BLESERIAL
curl_calibration_flag: CALIBRATION_CURL="new ::SenseShift::Input::Calibration::FixedCenterPointDeviationCalibrator<float>(0.66F, 0.005F)"
coverage: true
env:
PLATFORMIO_BUILD_FLAGS: >-
${{ matrix.coverage && '-lgcov --coverage' || '' }}
${{ matrix.comm_flag && format('-D {0}', matrix.comm_flag) || '' }}
${{ matrix.curl_calibration_flag && format('-D {0}', matrix.curl_calibration_flag) || '' }}
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Get firmware name
id: firmware_name
run: python3 ./.github/scripts/get-firmware-name.py ${{ matrix.target }} '${{ env.PLATFORMIO_BUILD_FLAGS }}'
- name: Speedup package installation
if: matrix.coverage
uses: abbbi/github-actions-tune@v1
- name: Setup LCOV
if: matrix.coverage
uses: hrishikesh-kadam/setup-lcov@v1
- name: Cache PlatformIO target
if: matrix.coverage == false
uses: actions/cache@v4
with:
path: |
./.pio/build/${{ matrix.target }}
key: ${{ runner.os }}-pio-${{ matrix.target }}-${{ steps.firmware_name.outputs.firmware }}-${{ hashFiles('**/*.ini') }}
restore-keys: |
${{ runner.os }}-pio-${{ matrix.target }}-${{ steps.firmware_name.outputs.firmware }}-
${{ runner.os }}-pio-${{ matrix.target }}-
${{ runner.os }}-pio-
- name: Setup PlatformIO
uses: ./.github/actions/setup-platformio
with:
build_cache_dir: ./.pio/build_cache
cache: 'pip cache build_cache'
- name: Install libs
shell: bash
run: |
pio pkg install -e ${{matrix.target}}
- name: Change memory segments
if: matrix.coverage
run: |
sed -i "s/len\s=\s0x2c200\s-\s0xdb5c/len = 2898880/" ~/.platformio/packages/framework-arduinoespressif32-libs/esp32/ld/memory.ld
sed -i "/\[env\]/p; s/\[env\]/board_build.partitions = huge_app.csv/" platformio.ini
- uses: ammaraskar/gcc-problem-matcher@0.3.0
- name: Build
shell: bash
run: |
pio ${{ matrix.coverage && 'debug' || 'run' }} --environment ${{matrix.target}} | tee build.log
- name: Collect memory usage
id: memory_usage
if: matrix.coverage == false
env:
USAGE_FILENAME: ${{ steps.firmware_name.outputs.firmware }}-usage.json
run: |
echo "USAGE_FILENAME=${{ env.USAGE_FILENAME }}" >> $GITHUB_ENV
ram_line=$(grep 'RAM:' build.log)
flash_line=$(grep 'Flash:' build.log)
# Parse the RAM usage details
ram_percentage=$(echo $ram_line | grep -oP '\d+\.\d+(?=%)')
ram_used=$(echo $ram_line | grep -oP '(?<=used )\d+')
ram_total=$(echo $ram_line | grep -oP '(?<=from )\d+')
# Parse the Flash usage details
flash_percentage=$(echo $flash_line | grep -oP '\d+\.\d+(?=%)')
flash_used=$(echo $flash_line | grep -oP '(?<=used )\d+')
flash_total=$(echo $flash_line | grep -oP '(?<=from )\d+')
# Store as JSON to file usage.json
echo "{\"ram\": {\"percentage\": $ram_percentage, \"used\": $ram_used, \"total\": $ram_total}, \"flash\": {\"percentage\": $flash_percentage, \"used\": $flash_used, \"total\": $flash_total}}" > ${{ env.USAGE_FILENAME }}
# Print the content of usage.json
cat ${{ env.USAGE_FILENAME }}
- name: Upload usage.json artifact
if: matrix.coverage == false
uses: actions/upload-artifact@v4
with:
name: ${{ steps.firmware_name.outputs.firmware }}-usage
path: ${{ env.USAGE_FILENAME }}
retention-days: 1
if-no-files-found: error
- name: Upload firmware Artifact
if: matrix.coverage == false
uses: actions/upload-artifact@v4
with:
name: ${{ steps.firmware_name.outputs.firmware }}
path: |
./.pio/build/${{matrix.target}}/firmware.bin
./.pio/build/${{matrix.target}}/firmware.elf
retention-days: 1
if-no-files-found: error
- name: Collect initial coverage
if: matrix.coverage
run: |
echo "::group::List files"
ls -lahR ./.pio/build/${{matrix.target}}/
echo "::endgroup::"
mkdir -p ./build/lcov
lcov -i -d ./.pio/build/${{matrix.target}}/ -c -o ./build/lcov/lcov.info.${{ steps.firmware_name.outputs.firmware }} -gcov-tool ~/.platformio/packages/toolchain-xtensa-esp32/bin/xtensa-esp32-elf-gcov
- name: Upload coverage Artifact
uses: actions/upload-artifact@v4
if: matrix.coverage
with:
name: lcov.info.${{ steps.firmware_name.outputs.firmware }}
path: ./build/lcov/lcov.info.${{ steps.firmware_name.outputs.firmware }}
retention-days: 1
if-no-files-found: error
test:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
target:
- native
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Speedup package installation
uses: abbbi/github-actions-tune@v1
- name: Setup LCOV
uses: hrishikesh-kadam/setup-lcov@v1
- name: Cache PlatformIO target
uses: actions/cache@v4
with:
path: |
./.pio/build/${{ matrix.target }}
key: ${{ runner.os }}-pio-${{ matrix.target }}-${{ hashFiles('**/*.ini') }}
restore-keys: |
${{ runner.os }}-pio-${{ matrix.target }}-
${{ runner.os }}-pio-
- name: Setup PlatformIO
uses: ./.github/actions/setup-platformio
- name: Install libs
shell: bash
run: |
pio pkg install -e ${{matrix.target}}
- uses: ammaraskar/gcc-problem-matcher@0.3.0
- name: Run Unit Tests
run: pio test -e ${{matrix.target}}
- name: Collect coverage report
run: |
mkdir -p ./build/lcov
lcov -d ./.pio/build/${{matrix.target}}/ -c -o ./build/lcov/lcov.info.${{matrix.target}}.test
- name: Upload coverage Artifact
uses: actions/upload-artifact@v4
with:
name: lcov.info.${{matrix.target}}.test
path: ./build/lcov/lcov.info.${{matrix.target}}.test
retention-days: 5
report-coverage:
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
needs:
- build-bhaptics
- build-opengloves
- test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Speedup package installation
uses: abbbi/github-actions-tune@v1
- name: Setup LCOV
uses: hrishikesh-kadam/setup-lcov@v1
- name: Download all workflow run artifacts
id: download
uses: actions/download-artifact@v4
with:
path: build/artifacts
- name: Merge lcov files
run: |
mkdir ./build/lcov/
find ./build/artifacts -mindepth 2 -type f -exec mv '{}' ./build/lcov/ \;
ls -lahR ./build/lcov/
find ./build/lcov -name 'lcov.info.*' -exec echo -a {} \; | xargs lcov -o ./build/lcov/lcov.info
lcov --remove ./build/lcov/lcov.info '/usr/include/*' '*.platformio/*' '*/.pio/*' '*/tool-unity/*' '*/test/*' '*/MockArduino/*' '*/lib/frozen/*' -o ./build/lcov/lcov.info.cleaned
# delete all except the cleaned file
find ./build/lcov -type f -not -name 'lcov.info.cleaned' -delete
- name: Generate HTML report
run: genhtml -p $PWD -o ./build/coverage/ --demangle-cpp ./build/lcov/lcov.info.cleaned
- name: Upload coverage Artifact
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: |
./build/coverage/
retention-days: 5
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
fail_ci_if_error: true
files: ./build/lcov/lcov.info.cleaned
flags: unittests
report-memory-usage:
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
needs:
- build-bhaptics
- build-opengloves
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download all workflow run artifacts
id: download
uses: actions/download-artifact@v4
with:
path: current-usage
pattern: '*-usage'
merge-multiple: true
- name: Merge usage files
shell: python
run: |
import os
import json
# Directory containing the JSON files
directory = "current-usage"
# Initialize an empty dictionary to store the merged content
merged_data = {}
# Iterate over all files in the directory
for filename in os.listdir(directory):
if filename.endswith(".json"):
# Extract the filename without the extension
key = os.path.splitext(filename)[0]
# Construct the full path to the file
filepath = os.path.join(directory, filename)
# Read the content of the file
with open(filepath, 'r') as file:
content = json.load(file)
# Add the content to the merged dictionary
merged_data[key] = content
# Specify the output file
output_file = os.path.join(directory, "merged.json")
# Write the merged content to the output file
with open(output_file, 'w') as file:
json.dump(merged_data, file, indent=4)
print(f"Merged JSON file has been created at: {output_file}")
- name: Upload merged usage.json artifact
uses: actions/upload-artifact@v4
with:
name: merged-usage
path: current-usage/merged.json
- name: Get base branch job ID
if: github.event_name == 'pull_request'
id: base_branch_workflow
uses: actions/github-script@v7
with:
script: |
const { data: workflows } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
branch: context.payload.pull_request.base.ref,
event: 'push',
workflow_id: 'ci.yml',
status: 'completed',
per_page: 1
});
const baseBranchJobId = workflows.workflow_runs[0].id;
console.log(baseBranchJobId);
return baseBranchJobId;
- name: Download base branch usage.json artifact
if: github.event_name == 'pull_request'
id: download-base-usage
uses: actions/download-artifact@v4
continue-on-error: true
with:
name: merged-usage
path: base-usage
github-token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
run-id: ${{ steps.base_branch_workflow.outputs.result }}
- uses: actions/setup-python@v5
if: github.event_name == 'pull_request' && steps.download-base-usage.outcome == 'success'
with:
python-version: '3.x'
- name: Report memory usage table
if: github.event_name == 'pull_request' && steps.download-base-usage.outcome == 'success'
shell: bash
run: |
python -m pip install --upgrade pip pandas tabulate
cat ./base-usage/merged.json
cat ./current-usage/merged.json
echo "## Memory Usage Comparison" > memory-usage-comparison.md
echo "" >> memory-usage-comparison.md
echo "<details>" >> memory-usage-comparison.md
echo " <summary>Click to expand</summary>" >> memory-usage-comparison.md
echo "" >> memory-usage-comparison.md
python ./.github/scripts/compare-memory-usage.py ./base-usage/merged.json ./current-usage/merged.json | tee -a memory-usage-comparison.md
echo "</details>" >> memory-usage-comparison.md
cat ./memory-usage-comparison.md > $GITHUB_STEP_SUMMARY
- uses: thollander/actions-comment-pull-request@v3
if: github.event_name == 'pull_request' && steps.download-base-usage.outcome == 'success'
with:
filePath: memory-usage-comparison.md
comment_tag: memory-usage-comparison
wokwi:
# Skip any PR created by dependabot to avoid permission issues:
if: (github.actor != 'dependabot[bot]')
needs:
- build-bhaptics
- build-opengloves
- test
runs-on: ubuntu-latest
strategy:
matrix:
variant:
- opengloves_lucidgloves_proto3+serial
- opengloves_lucidgloves_proto4+serial
steps:
- uses: actions/checkout@v4
- name: Extract target
id: target_name
run: |
target=$(echo ${{ matrix.variant }} | cut -d'+' -f1)
echo "target=$target" >> $GITHUB_OUTPUT
- name: Download firmware artifact
uses: actions/download-artifact@v4
with:
name: ${{ matrix.variant }}
path: ./.pio/build/${{ steps.target_name.outputs.target }}
- name: Run Wokwi scenario
uses: wokwi/wokwi-ci-action@v1
with:
token: ${{ secrets.WOKWI_CLI_TOKEN }}
path: ./.wokwi/${{ matrix.variant }}
scenario: "test.yaml"