mirror of
https://github.com/hathach/tinyusb.git
synced 2026-08-18 11:02:16 +00:00
The Size Difference Report and HIL comments rendered their titles at h1, which is oversized inside a PR comment. Use h2 for both titles (with subsections demoted to h3 to keep the hierarchy), and rename the HIL comment from "HIL test results" to "Hardware-in-the-loop (HIL) Test Report" for consistency. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
456 lines
16 KiB
YAML
456 lines
16 KiB
YAML
name: Build
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
push:
|
|
branches: [master]
|
|
pull_request:
|
|
release:
|
|
types: [ published ]
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
|
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
|
|
|
jobs:
|
|
# Check if the code changes and we need to run ci build
|
|
# Cannot use paths filter in the on-event since we want this workflow to run even when there are no code changes, to register the commit chain
|
|
check-paths:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
pull-requests: read
|
|
outputs:
|
|
code_changed: ${{ steps.filter.outputs.code }}
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 2 # Needed for push commit comparison
|
|
- uses: dorny/paths-filter@v4
|
|
id: filter
|
|
with:
|
|
filters: |
|
|
code:
|
|
- 'src/**'
|
|
- 'examples/**'
|
|
- 'lib/**'
|
|
- 'hw/**'
|
|
- 'test/hil/**'
|
|
- 'tools/build.py'
|
|
- 'tools/get_deps.py'
|
|
- '.github/actions/**'
|
|
- '.github/workflows/build.yml'
|
|
- '.github/workflows/build_util.yml'
|
|
- '.github/workflows/ci_set_matrix.py'
|
|
|
|
set-matrix:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
json: ${{ steps.set-matrix-json.outputs.matrix }}
|
|
hil_json: ${{ steps.set-matrix-json.outputs.hil_matrix }}
|
|
steps:
|
|
- name: Checkout TinyUSB
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Generate matrix json
|
|
id: set-matrix-json
|
|
run: |
|
|
# build matrix
|
|
MATRIX_JSON=$(python .github/workflows/ci_set_matrix.py)
|
|
echo "matrix=$MATRIX_JSON"
|
|
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
|
|
|
|
# HIL matrix (merged from tinyusb + hifiphile configs)
|
|
HIL_MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/tinyusb.json test/hil/hfp.json)
|
|
echo "hil_matrix=$HIL_MATRIX_JSON"
|
|
echo "hil_matrix=$HIL_MATRIX_JSON" >> $GITHUB_OUTPUT
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# CMake build: only one board per family (first alphabetically). Full build is done by CircleCI in PR
|
|
# Note:
|
|
# For Make and IAR build: will be done on CircleCI only (one random per family as well)
|
|
# ------------------------------------------------------------------------------
|
|
cmake:
|
|
needs: [ check-paths, set-matrix ]
|
|
uses: ./.github/workflows/build_util.yml
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
toolchain:
|
|
- 'aarch64-gcc'
|
|
#- 'arm-clang'
|
|
- 'arm-gcc'
|
|
#- 'esp-idf'
|
|
- 'ft9xx-gcc'
|
|
- 'msp430-gcc'
|
|
- 'riscv-gcc'
|
|
with:
|
|
build-system: 'cmake'
|
|
toolchain: ${{ matrix.toolchain }}
|
|
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.json)[matrix.toolchain]) }}
|
|
build-options: '--one-first'
|
|
upload-metrics: true
|
|
upload-artifacts: false
|
|
upload-membrowse: true
|
|
code-changed: ${{ needs.check-paths.outputs.code_changed == 'true' }}
|
|
secrets: inherit
|
|
|
|
code-metrics:
|
|
needs: [ check-paths, cmake ]
|
|
if: needs.check-paths.outputs.code_changed == 'true'
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
pull-requests: write
|
|
contents: write
|
|
steps:
|
|
- name: Checkout TinyUSB
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-tags: ${{ github.event_name == 'release' }}
|
|
|
|
- name: Download Artifacts
|
|
uses: actions/download-artifact@v5
|
|
with:
|
|
pattern: metrics-*
|
|
path: cmake-build
|
|
merge-multiple: true
|
|
|
|
- name: Aggregate Code Metrics
|
|
run: |
|
|
python tools/get_deps.py
|
|
python tools/metrics.py combine -j -m -f tinyusb/src cmake-build/*/metrics.json
|
|
|
|
- name: Upload Metrics Artifact
|
|
if: github.event_name == 'push' || github.event_name == 'release'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: metrics-tinyusb
|
|
path: metrics.json
|
|
|
|
- name: Download Base Branch Metrics
|
|
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
|
|
uses: dawidd6/action-download-artifact@v11
|
|
with:
|
|
workflow: build.yml
|
|
workflow_conclusion: ''
|
|
branch: ${{ github.base_ref }}
|
|
name: metrics-tinyusb
|
|
path: base-metrics
|
|
continue-on-error: true
|
|
|
|
- name: Download Previous Release Asset
|
|
if: github.event_name == 'release'
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
PREV_TAG=$(git tag --sort=-creatordate | head -n 2 | tail -n 1)
|
|
echo "Previous Release: $PREV_TAG"
|
|
echo "PREV_TAG=$PREV_TAG" >> $GITHUB_ENV
|
|
|
|
mkdir -p base-metrics
|
|
gh release download $PREV_TAG -p metrics.json -D base-metrics || echo "No metrics.json found in $PREV_TAG release"
|
|
|
|
- name: Compare with Base Branch
|
|
if: github.event_name != 'push'
|
|
run: |
|
|
if [ -f base-metrics/metrics.json ]; then
|
|
python tools/metrics.py compare -m -f tinyusb/src base-metrics/metrics.json metrics.json
|
|
cat metrics_compare.md
|
|
else
|
|
echo "No base metrics found, skipping comparison"
|
|
cp metrics.md metrics_compare.md
|
|
fi
|
|
|
|
- name: Upload Release Assets
|
|
if: github.event_name == 'release'
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
CURR_TAG=${{ github.event.release.tag_name }}
|
|
COMPARE_FILE="metrics_compare_${CURR_TAG}-${PREV_TAG}.md"
|
|
mv metrics_compare.md $COMPARE_FILE
|
|
gh release upload $CURR_TAG metrics.json $COMPARE_FILE
|
|
|
|
- name: Save PR number
|
|
if: github.event_name == 'pull_request'
|
|
run: echo ${{ github.event.number }} > pr_number.txt
|
|
|
|
- name: Upload Metrics Comment Artifact
|
|
if: github.event_name == 'pull_request'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: metrics-comment
|
|
path: |
|
|
metrics_compare.md
|
|
metrics.json
|
|
pr_number.txt
|
|
|
|
- name: Post Code Metrics as PR Comment
|
|
if: (github.event_name == 'workflow_dispatch') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false)
|
|
uses: marocchino/sticky-pull-request-comment@v2
|
|
with:
|
|
header: code-metrics
|
|
path: metrics_compare.md
|
|
|
|
# ---------------------------------------
|
|
# Keep the metrics baseline available on no-code-change pushes
|
|
# The code-metrics job only runs (and uploads metrics-tinyusb) when code changed, so a
|
|
# workflow/docs-only push to master would leave the latest run without a baseline for PRs
|
|
# to compare against. Carry the previous artifact forward so the baseline is never missing.
|
|
# ---------------------------------------
|
|
metrics-carry-forward:
|
|
needs: [ check-paths ]
|
|
if: github.event_name == 'push' && needs.check-paths.outputs.code_changed != 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Download previous metrics baseline from this branch
|
|
uses: dawidd6/action-download-artifact@v11
|
|
with:
|
|
workflow: build.yml
|
|
workflow_conclusion: '' # any conclusion, matching the PR-side baseline download
|
|
search_artifacts: true # scan back past runs that lack the artifact (e.g. earlier no-code pushes)
|
|
branch: ${{ github.ref_name }}
|
|
name: metrics-tinyusb
|
|
path: .
|
|
if_no_artifact_found: warn
|
|
continue-on-error: true # best-effort: never make a no-code push red
|
|
|
|
- name: Re-publish baseline so the latest run keeps it
|
|
if: hashFiles('metrics.json') != ''
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: metrics-tinyusb
|
|
path: metrics.json
|
|
|
|
# ---------------------------------------
|
|
# Build Make/CMake on Windows/MacOS
|
|
# ---------------------------------------
|
|
build-os:
|
|
needs: [ check-paths ]
|
|
if: needs.check-paths.outputs.code_changed == 'true'
|
|
uses: ./.github/workflows/build_util.yml
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ windows-latest, macos-latest ]
|
|
build-system: [ 'make', 'cmake' ]
|
|
with:
|
|
os: ${{ matrix.os }}
|
|
build-system: ${{ matrix.build-system }}
|
|
toolchain: 'arm-gcc-${{ matrix.os }}'
|
|
build-args: '["stm32h7rs"]'
|
|
build-options: '--one-random'
|
|
|
|
# ---------------------------------------
|
|
# Zephyr
|
|
# ---------------------------------------
|
|
zephyr:
|
|
needs: [ check-paths ]
|
|
# skip zephyr build due to failed build, fix later
|
|
if: false
|
|
#if: needs.check-paths.outputs.code_changed == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout TinyUSB
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Setup Zephyr project
|
|
uses: zephyrproject-rtos/action-zephyr-setup@v1
|
|
with:
|
|
app-path: examples
|
|
toolchains: arm-zephyr-eabi
|
|
|
|
- name: Build
|
|
run: |
|
|
west build -b nrf52840dk -d examples/device/cdc_msc/build examples/device/cdc_msc -- -DRTOS=zephyr
|
|
west build -b nrf52840dk -d examples/device/msc_dual_lun/build examples/device/msc_dual_lun -- -DRTOS=zephyr
|
|
|
|
# ---------------------------------------
|
|
# Hardware in the loop (HIL)
|
|
# Run on PR only (hil-tinyusb), hil-hfp-iar only run on non-forked PR
|
|
# ---------------------------------------
|
|
hil-build:
|
|
needs: [ check-paths, set-matrix ]
|
|
if: needs.check-paths.outputs.code_changed == 'true' && github.repository_owner == 'hathach'
|
|
uses: ./.github/workflows/build_util.yml
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
toolchain:
|
|
- 'arm-gcc'
|
|
- 'esp-idf'
|
|
with:
|
|
build-system: 'cmake'
|
|
toolchain: ${{ matrix.toolchain }}
|
|
build-args: ${{ toJSON(fromJSON(needs.set-matrix.outputs.hil_json)[matrix.toolchain]) }}
|
|
upload-artifacts: true
|
|
|
|
# ---------------------------------------
|
|
# Hardware in the loop (HIL)
|
|
# self-hosted on local VM, for attached hardware checkout HIL_JSON
|
|
# ---------------------------------------
|
|
hil-tinyusb:
|
|
needs: hil-build
|
|
name: hil-tinyusb (${{ matrix.display }})
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- display: tinyusb.json
|
|
runner: [ self-hosted, X64, hathach, hardware-in-the-loop ]
|
|
hil_json: test/hil/tinyusb.json
|
|
- display: hfp.json
|
|
runner: [ self-hosted, Linux, X64, hifiphile ]
|
|
hil_json: test/hil/hfp.json
|
|
runs-on: ${{ matrix.runner }}
|
|
env:
|
|
HIL_JSON: ${{ matrix.hil_json }}
|
|
steps:
|
|
- name: Set HIL report dir (sibling of workspace; persists across run attempts)
|
|
run: echo "HIL_REPORT_DIR=$(dirname "$GITHUB_WORKSPACE")/hil-report" >> "$GITHUB_ENV"
|
|
|
|
- name: Get Skip Boards from previous run
|
|
if: github.run_attempt != '1'
|
|
run: |
|
|
if [ -f "${{ env.HIL_JSON }}.skip" ]; then
|
|
SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip")
|
|
else
|
|
SKIP_BOARDS=""
|
|
fi
|
|
echo "SKIP_BOARDS=$SKIP_BOARDS"
|
|
echo "SKIP_BOARDS=$SKIP_BOARDS" >> $GITHUB_ENV
|
|
|
|
- name: Clean workspace
|
|
run: |
|
|
echo "Cleaning up for the first run"
|
|
rm -rf "${{ github.workspace }}"
|
|
mkdir -p "${{ github.workspace }}"
|
|
|
|
- name: Checkout TinyUSB
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Download Artifacts
|
|
uses: actions/download-artifact@v5
|
|
with:
|
|
pattern: binaries-*
|
|
path: cmake-build
|
|
merge-multiple: true
|
|
|
|
- name: Test on actual hardware
|
|
run: |
|
|
python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS || \
|
|
(if [ -f "${{ env.HIL_JSON }}.skip" ]; then
|
|
SKIP_BOARDS=$(cat "${{ env.HIL_JSON }}.skip")
|
|
echo "Re-running with SKIP_BOARDS=$SKIP_BOARDS"
|
|
python3 test/hil/hil_test.py ${{ env.HIL_JSON }} $SKIP_BOARDS
|
|
else
|
|
exit 1
|
|
fi)
|
|
|
|
- name: Upload HIL report
|
|
if: always() && github.event_name == 'pull_request'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: hil-report-${{ matrix.display }}
|
|
path: ${{ env.HIL_REPORT_DIR }}/hil_report.md
|
|
if-no-files-found: ignore
|
|
overwrite: true
|
|
|
|
# ---------------------------------------
|
|
# Hardware in the loop (HIL)
|
|
# self-hosted by HFP, build with IAR toolchain, for attached hardware checkout test/hil/hfp.json
|
|
# Since IAR Token secret is not passed to forked PR, only build non-forked PR
|
|
# ---------------------------------------
|
|
hil-hfp-iar:
|
|
needs: [ check-paths ]
|
|
if: |
|
|
needs.check-paths.outputs.code_changed == 'true' &&
|
|
github.repository_owner == 'hathach' &&
|
|
!(github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true)
|
|
runs-on: [ self-hosted, Linux, X64, hifiphile ]
|
|
timeout-minutes: 30
|
|
env:
|
|
IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }}
|
|
PYTHONUNBUFFERED: '1'
|
|
steps:
|
|
- name: Clean workspace
|
|
run: |
|
|
echo "Cleaning up previous run"
|
|
rm -rf "${{ github.workspace }}"
|
|
mkdir -p "${{ github.workspace }}"
|
|
|
|
- name: Toolchain version
|
|
run: |
|
|
iccarm --version
|
|
|
|
- name: Checkout TinyUSB
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Get build boards
|
|
run: |
|
|
MATRIX_JSON=$(python test/hil/hil_ci_set_matrix.py test/hil/hfp.json)
|
|
BUILD_ARGS=$(echo $MATRIX_JSON | jq -r '.["arm-gcc"] | join(" ")')
|
|
echo "BUILD_ARGS=$BUILD_ARGS"
|
|
echo "BUILD_ARGS=$BUILD_ARGS" >> $GITHUB_ENV
|
|
|
|
- name: Get Dependencies
|
|
run: python3 tools/get_deps.py $BUILD_ARGS
|
|
|
|
- name: Build
|
|
run: python3 tools/build.py --toolchain iar $BUILD_ARGS
|
|
|
|
- name: Test on actual hardware (hardware in the loop)
|
|
run: |
|
|
python3 test/hil/hil_test.py hfp.json
|
|
|
|
- name: Upload HIL report
|
|
if: always() && github.event_name == 'pull_request'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: hil-report-hfp-iar
|
|
path: hil_report.md
|
|
if-no-files-found: ignore
|
|
overwrite: true
|
|
|
|
# ---------------------------------------
|
|
# Combine HIL results from the rigs into a single sticky PR comment (one table per rig)
|
|
# ---------------------------------------
|
|
hil-report:
|
|
needs: [ hil-tinyusb, hil-hfp-iar ]
|
|
if: |
|
|
always() &&
|
|
(needs.hil-tinyusb.result != 'skipped' || needs.hil-hfp-iar.result != 'skipped') &&
|
|
github.event_name == 'pull_request' &&
|
|
github.repository_owner == 'hathach' &&
|
|
github.event.pull_request.head.repo.fork == false
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
pull-requests: write
|
|
steps:
|
|
- name: Download HIL reports
|
|
uses: actions/download-artifact@v5
|
|
with:
|
|
pattern: hil-report-*
|
|
path: hil-reports
|
|
|
|
- name: Combine rig reports (one table per rig)
|
|
run: |
|
|
{
|
|
echo "## Hardware-in-the-loop (HIL) Test Report"
|
|
echo
|
|
for d in hil-reports/hil-report-*; do
|
|
[ -d "$d" ] || continue
|
|
echo "### ${d#hil-reports/hil-report-}"
|
|
echo
|
|
cat "$d/hil_report.md" 2>/dev/null || echo "_no report produced_"
|
|
echo
|
|
done
|
|
} > hil_combined.md
|
|
cat hil_combined.md
|
|
|
|
- name: Post HIL report as sticky PR comment
|
|
uses: marocchino/sticky-pull-request-comment@v2
|
|
with:
|
|
header: hil-report
|
|
path: hil_combined.md
|