name: Reusable build util on: workflow_call: inputs: os: required: false type: string default: 'ubuntu-latest' build-system: required: true type: string toolchain: required: true type: string build-args: required: true type: string build-options: required: false default: '' type: string upload-artifacts: required: false default: false type: boolean upload-metrics: required: false default: false type: boolean upload-membrowse: required: false default: false type: boolean code-changed: required: false default: true type: boolean jobs: family: # PR-scoped HIL selection can produce an empty build-args list for a toolchain # (e.g. a dwc2-only change with no riscv boards affected); an empty matrix # vector fails the job outright ("Matrix vector 'arg' does not contain any # values"), so skip cleanly instead. # # Why that is safe for callers: GitHub SKIPS the dependents of a skipped # `needs:` job, so this only works because the caller (hil-build) is itself a # *matrix* job - a matrix with one skipped leg and one successful leg # aggregates to success, and its dependents run. # # NOT covered: if every leg is empty the whole caller job skips, and so does # everything that needs it. That is fine only because an all-empty selection # means no board was selected for those rigs, so the rig jobs would have had # nothing to run anyway (see the invariant on hil-build in build.yml). if: inputs.build-args != '[]' runs-on: ${{ inputs.os }} strategy: fail-fast: false matrix: arg: ${{ fromJSON(inputs.build-args) }} steps: - name: Checkout TinyUSB uses: actions/checkout@v6 with: fetch-depth: ${{ !inputs.upload-membrowse && 1 || 0 }} - name: Setup Toolchain id: setup-toolchain uses: ./.github/actions/setup_toolchain with: toolchain: ${{ inputs.toolchain }} - name: Get Dependencies uses: ./.github/actions/get_deps with: arg: ${{ matrix.arg }} - name: Build if: ${{ inputs.code-changed }} env: IAR_LMS_BEARER_TOKEN: ${{ secrets.IAR_LMS_BEARER_TOKEN }} run: | if [ "${{ inputs.toolchain }}" == "esp-idf" ]; then docker run --rm -e MEMBROWSE_API_KEY="$MEMBROWSE_API_KEY" -e CI="$CI" -v $PWD:/project -w /project espressif/idf:tinyusb python tools/build.py --target all ${{ matrix.arg }} else BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }} --target all" if [ "${{ inputs.upload-metrics }}" = "true" ]; then BUILD_PY_ARGS="$BUILD_PY_ARGS --target tinyusb_metrics" fi python tools/build.py $BUILD_PY_ARGS ${{ matrix.arg }} fi shell: bash - name: Membrowse Upload if: inputs.toolchain != 'esp-idf' && inputs.upload-membrowse == true continue-on-error: true env: MEMBROWSE_API_KEY: ${{ secrets.MEMBROWSE_API_KEY }} run: | # if code-changed is false --> there is no elf -> membrowse target upload with --identical flag BUILD_PY_ARGS="-s ${{ inputs.build-system }} ${{ steps.setup-toolchain.outputs.build_option }} ${{ inputs.build-options }}" python tools/build.py $BUILD_PY_ARGS --target examples-membrowse-upload -j 1 ${{ matrix.arg }} shell: bash - name: Upload Artifacts for Metrics if: inputs.upload-metrics == true && inputs.code-changed == true uses: actions/upload-artifact@v7 with: name: metrics-${{ matrix.arg }} path: cmake-build/cmake-build-*/metrics.json - name: Upload Artifacts for Hardware Testing if: inputs.upload-artifacts == true && inputs.code-changed == true uses: actions/upload-artifact@v7 with: name: binaries-${{ inputs.toolchain }}-${{ matrix.arg }} path: | cmake-build/cmake-build-*/*/*/*.elf cmake-build/cmake-build-*/*/*/*.bin cmake-build/cmake-build-*/*/*/*.bin cmake-build/cmake-build-*/*/*/bootloader/bootloader.bin cmake-build/cmake-build-*/*/*/partition_table/partition-table.bin cmake-build/cmake-build-*/*/*/config.env cmake-build/cmake-build-*/*/*/flash_args cmake-build/hw/mcu/**/*.ld