diff --git a/.github/scripts/baremetal_package.sh b/.github/scripts/baremetal_package.sh index ffdbd56..74f3fd5 100644 --- a/.github/scripts/baremetal_package.sh +++ b/.github/scripts/baremetal_package.sh @@ -8,6 +8,9 @@ # # # Just change architecture list # ./baremetal_package.sh --arch-list cortex-m0,cortex-m1,cortex-m3 +# +# # Only build MinSizeRel +# ./baremetal_package.sh --build-types MinSizeRel # Exit script on any error set -e @@ -18,6 +21,7 @@ DIR="." VERSION="latest" COMPILER_PROFILE="hal/tc/llvm" ARCH_LIST=("cortex-m3") +BUILD_TYPES=("Debug" "MinSizeRel" "Release") CONAN_VERSION=2.23.0 EXTRA_CONAN_ARGS="" @@ -44,13 +48,17 @@ while [[ $# -gt 0 ]]; do IFS=',' read -ra ARCH_LIST <<< "$2" shift 2 ;; + --build-types) + IFS=',' read -ra BUILD_TYPES <<< "$2" + shift 2 + ;; --extra-conan-args) EXTRA_CONAN_ARGS="$2" shift 2 ;; *) echo "Unknown option: $1" - echo "Usage: $0 [--dir DIR] [--version VERSION] [--compiler-profile PROFILE] [--conan-version VERSION] [--arch-list ARCH1,ARCH2,...] [--extra-conan-args ARGS]" + echo "Usage: $0 [--dir DIR] [--version VERSION] [--compiler-profile PROFILE] [--conan-version VERSION] [--arch-list ARCH1,ARCH2,...] [--build-types TYPE1,TYPE2,...] [--extra-conan-args ARGS]" exit 1 ;; esac @@ -65,6 +73,7 @@ echo "VERSION: $VERSION" echo "COMPILER_PROFILE: $COMPILER_PROFILE" echo "CONAN_VERSION: $CONAN_VERSION" echo "ARCH_LIST: ${ARCH_LIST[*]}" +echo "BUILD_TYPES: ${BUILD_TYPES[*]}" echo "EXTRA_CONAN_ARGS: $EXTRA_CONAN_ARGS" echo "========================================" @@ -77,9 +86,7 @@ conan hal setup for ARCH in "${ARCH_LIST[@]}"; do echo "Building for architecture: $ARCH" - conan create $DIR -s:h build_type=Debug -s:h os=baremetal -s:h arch=$ARCH --version $VERSION -pr:h $COMPILER_PROFILE --build=missing $EXTRA_CONAN_ARGS - - conan create $DIR -s:h build_type=MinSizeRel -s:h os=baremetal -s:h arch=$ARCH --version $VERSION -pr:h $COMPILER_PROFILE --build=missing $EXTRA_CONAN_ARGS - - conan create $DIR -s:h build_type=Release -s:h os=baremetal -s:h arch=$ARCH --version $VERSION -pr:h $COMPILER_PROFILE --build=missing $EXTRA_CONAN_ARGS + for BUILD_TYPE in "${BUILD_TYPES[@]}"; do + conan create $DIR -s:h build_type=$BUILD_TYPE -s:h os=baremetal -s:h arch=$ARCH --version $VERSION -pr:h $COMPILER_PROFILE --build=missing $EXTRA_CONAN_ARGS + done done diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b8e96e0..15e5142 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -37,6 +37,7 @@ on: jobs: docs: runs-on: ubuntu-22.04 + timeout-minutes: 15 steps: - uses: actions/checkout@v4.1.1 if: ${{ inputs.version != '' }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8e56126..dd59a27 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -37,6 +37,7 @@ on: jobs: lint: runs-on: ubuntu-22.04 + timeout-minutes: 15 steps: - uses: actions/checkout@v4.1.1 if: ${{ inputs.version != '' }} diff --git a/.github/workflows/package_and_upload.yml b/.github/workflows/package_and_upload.yml index 708d3a8..0e8097d 100644 --- a/.github/workflows/package_and_upload.yml +++ b/.github/workflows/package_and_upload.yml @@ -57,6 +57,14 @@ on: type: string default: "" description: "Extra arguments to pass to conan create commands" + build_types: + type: string + default: "Debug,MinSizeRel,Release" + description: "Comma separated list of build types to create packages for" + timeout_minutes: + type: number + default: 30 + description: "Cancel the job if it runs longer than this" secrets: conan_remote_user: @@ -67,6 +75,7 @@ jobs: package_and_upload: name: ${{ inputs.name }} runs-on: ${{ inputs.runner_os }} + timeout-minutes: ${{ inputs.timeout_minutes }} env: VERBOSE: 1 CONAN_REMOTE_USER: ${{ secrets.conan_remote_user }} @@ -106,13 +115,16 @@ jobs: - name: 📡 Perform conan hal setup run: conan hal setup - - name: 📦 Create `Debug` package for ${{ inputs.profile }} + - name: 📦 Create `Debug` package for ${{ inputs.compiler_profile }} + if: ${{ contains(format(',{0},', inputs.build_types), ',Debug,') }} run: conan create ${{ inputs.dir }} --build="${{ inputs.library }}/*" -s:h build_type=Debug -pr:a ${{ inputs.compiler_profile }} -s:h os=${{ inputs.os }} -s:h arch=${{ inputs.arch }} --version=${{ inputs.version }} --build=missing ${{ inputs.extra_conan_arguments }} - - name: 📦 Create `MinSizeRel` package for ${{ inputs.profile }} + - name: 📦 Create `MinSizeRel` package for ${{ inputs.compiler_profile }} + if: ${{ contains(format(',{0},', inputs.build_types), ',MinSizeRel,') }} run: conan create ${{ inputs.dir }} --build="${{ inputs.library }}/*" -s:h build_type=MinSizeRel -pr:a ${{ inputs.compiler_profile }} -s:h os=${{ inputs.os }} -s:h arch=${{ inputs.arch }} --version=${{ inputs.version }} --build=missing ${{ inputs.extra_conan_arguments }} - - name: 📦 Create `Release` package for ${{ inputs.profile }} + - name: 📦 Create `Release` package for ${{ inputs.compiler_profile }} + if: ${{ contains(format(',{0},', inputs.build_types), ',Release,') }} run: conan create ${{ inputs.dir }} --build="${{ inputs.library }}/*" -s:h build_type=Release -pr:a ${{ inputs.compiler_profile }} -s:h os=${{ inputs.os }} -s:h arch=${{ inputs.arch }} --version=${{ inputs.version }} --build=missing ${{ inputs.extra_conan_arguments }} - name: 📡 Sign into Conan Package Repository diff --git a/.github/workflows/package_and_upload_all.yml b/.github/workflows/package_and_upload_all.yml index 1d28332..5a61fcf 100644 --- a/.github/workflows/package_and_upload_all.yml +++ b/.github/workflows/package_and_upload_all.yml @@ -14,7 +14,12 @@ name: 📦 Conan Package & Upload (all) -# Builds packages for every device and architecture libhal supports +# Builds packages for the devices and architectures libhal supports. It runs +# in one of two modes: +# +# check (`version` is "latest", nothing is uploaded): `MinSizeRel` only and +# a sample of Cortex-M architectures. +# deploy (`version` is set): every build type and architecture. on: workflow_call: @@ -63,7 +68,58 @@ on: required: false jobs: + # Decides what the jobs below build. Check runs (version "latest", nothing + # is uploaded) build less than deploys, which build everything they upload. + plan: + name: 📋 Plan + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + build_types: ${{ steps.plan.outputs.build_types }} + cortex_m_llvm: ${{ steps.plan.outputs.cortex_m_llvm }} + cortex_m_gcc: ${{ steps.plan.outputs.cortex_m_gcc }} + steps: + - name: 📋 Choose build types and architectures + id: plan + env: + VERSION: ${{ inputs.version }} + COROUTINES: ${{ inputs.coroutine_support_needed }} + run: | + # ARMv6-M (M0, M0+, M1) is left out of the LLVM builds when + # coroutine support is needed. + if [ "$COROUTINES" = "true" ]; then + armv6m="" + else + armv6m="cortex-m0,cortex-m0plus,cortex-m1," + fi + + if [ "$VERSION" = "latest" ]; then + # Check run: one build type and a sample of Cortex-M cores + build_types="MinSizeRel" + sample="cortex-m3,cortex-m4f,cortex-m33f" + llvm_sample="${armv6m:+cortex-m0plus,}$sample" + cortex_m_llvm=$(jq -nc --arg archs "$llvm_sample" \ + '[{name: "M sample", archs: $archs}]') + cortex_m_gcc="cortex-m0plus,$sample" + else + # Deploy: every build type and Cortex-M core. LLVM splits the + # cores across two jobs because one job for all of them is slow. + build_types="Debug,MinSizeRel,Release" + older="cortex-m3,cortex-m4,cortex-m4f,cortex-m7f,cortex-m7d" + newer="cortex-m23,cortex-m33,cortex-m33f,cortex-m35pf,cortex-m55,cortex-m85" + cortex_m_llvm=$(jq -nc --arg older "$armv6m$older" --arg newer "$newer" \ + '[{name: "M0-M7", archs: $older}, {name: "M23-M85", archs: $newer}]') + cortex_m_gcc="cortex-m0,cortex-m0plus,cortex-m1,$older,$newer" + fi + + { + echo "build_types=$build_types" + echo "cortex_m_llvm=$cortex_m_llvm" + echo "cortex_m_gcc=$cortex_m_gcc" + } | tee -a "$GITHUB_OUTPUT" + linux_x86_64_llvm: + needs: plan uses: ./.github/workflows/package_and_upload.yml with: name: 🐉 LLVM 🐧 Linux x86_64 @@ -80,11 +136,13 @@ jobs: dir: ${{ inputs.dir }} remote_url: ${{ inputs.remote_url }} extra_conan_arguments: ${{ inputs.extra_conan_arguments }} + build_types: ${{ needs.plan.outputs.build_types }} secrets: conan_remote_user: ${{ secrets.conan_remote_user }} conan_remote_password: ${{ secrets.conan_remote_password }} linux_armv8_llvm: + needs: plan uses: ./.github/workflows/package_and_upload.yml with: name: 🐉 LLVM 🐧 Linux ARM64 @@ -101,11 +159,13 @@ jobs: dir: ${{ inputs.dir }} remote_url: ${{ inputs.remote_url }} extra_conan_arguments: ${{ inputs.extra_conan_arguments }} + build_types: ${{ needs.plan.outputs.build_types }} secrets: conan_remote_user: ${{ secrets.conan_remote_user }} conan_remote_password: ${{ secrets.conan_remote_password }} mac_os_x_llvm: + needs: plan uses: ./.github/workflows/package_and_upload.yml with: name: 🐉 LLVM 🍎 Mac ARM64 @@ -124,6 +184,7 @@ jobs: dir: ${{ inputs.dir }} remote_url: ${{ inputs.remote_url }} extra_conan_arguments: ${{ inputs.extra_conan_arguments }} + build_types: ${{ needs.plan.outputs.build_types }} secrets: conan_remote_user: ${{ secrets.conan_remote_user }} conan_remote_password: ${{ secrets.conan_remote_password }} @@ -131,19 +192,15 @@ jobs: # ================ ARM CORTEX LLVM ================ cortex-m_llvm: - name: 🐉 LLVM Arm Cortex ${{ matrix.group }} + name: 🐉 LLVM Arm Cortex ${{ matrix.name }} + needs: plan runs-on: ubuntu-latest - # Two parallel jobs: building every Cortex-M architecture in one job is - # slow. ARMv6-M (M0, M0+, M1) is left out when coroutine support is - # needed. + timeout-minutes: 45 strategy: fail-fast: false matrix: - include: - - group: M0-M7 - arch_list: ${{ inputs.coroutine_support_needed && 'cortex-m3,cortex-m4,cortex-m4f,cortex-m7f,cortex-m7d' || 'cortex-m0,cortex-m0plus,cortex-m1,cortex-m3,cortex-m4,cortex-m4f,cortex-m7f,cortex-m7d' }} - - group: M23-M85 - arch_list: cortex-m23,cortex-m33,cortex-m33f,cortex-m35pf,cortex-m55,cortex-m85 + # One entry per job: {name, archs}. See the plan job. + include: ${{ fromJSON(needs.plan.outputs.cortex_m_llvm) }} env: VERBOSE: 1 CONAN_REMOTE_USER: ${{ secrets.conan_remote_user }} @@ -173,7 +230,7 @@ jobs: ref: ${{ inputs.ci_ref }} path: ci-repo - - name: 📦 Build packages for Cortex ${{ matrix.group }} + - name: 📦 Build packages for Cortex ${{ matrix.name }} working-directory: target-repo run: | bash ../ci-repo/.github/scripts/baremetal_package.sh \ @@ -181,7 +238,8 @@ jobs: --version ${{ inputs.version }} \ --compiler-profile ${{ inputs.llvm_profile }} \ --conan-version ${{ inputs.conan_version }} \ - --arch-list ${{ matrix.arch_list }} \ + --arch-list ${{ matrix.archs }} \ + --build-types ${{ needs.plan.outputs.build_types }} \ --extra-conan-args "${{ inputs.extra_conan_arguments }}" - name: 📡 Add conan user remote-package-repo @@ -200,7 +258,9 @@ jobs: cortex-m_gcc: name: 🦌 GCC Arm Cortex M + needs: plan runs-on: ubuntu-latest + timeout-minutes: 45 if: ${{ inputs.modules_support_needed == false }} env: VERBOSE: 1 @@ -231,7 +291,7 @@ jobs: ref: ${{ inputs.ci_ref }} path: ci-repo - - name: 📦 Build packages for all Cortex-M architectures + - name: 📦 Build packages for Cortex-M architectures working-directory: target-repo run: | bash ../ci-repo/.github/scripts/baremetal_package.sh \ @@ -239,7 +299,8 @@ jobs: --version ${{ inputs.version }} \ --compiler-profile hal/tc/gcc \ --conan-version ${{ inputs.conan_version }} \ - --arch-list cortex-m0,cortex-m0plus,cortex-m1,cortex-m3,cortex-m4,cortex-m4f,cortex-m7f,cortex-m7d,cortex-m23,cortex-m33,cortex-m33f,cortex-m35pf,cortex-m55,cortex-m85 \ + --arch-list ${{ needs.plan.outputs.cortex_m_gcc }} \ + --build-types ${{ needs.plan.outputs.build_types }} \ --extra-conan-args "${{ inputs.extra_conan_arguments }}" - name: 📡 Add conan user remote-package-repo diff --git a/.github/workflows/self_check.yml b/.github/workflows/self_check.yml index 174eedc..142e0ea 100644 --- a/.github/workflows/self_check.yml +++ b/.github/workflows/self_check.yml @@ -56,6 +56,7 @@ jobs: package_and_upload_all: - '.github/workflows/package_and_upload_all.yml' - '.github/workflows/package_and_upload.yml' + - '.github/scripts/baremetal_package.sh' app_builder2: - '.github/workflows/app_builder2.yml' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8c51fac..16c146b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -82,6 +82,7 @@ jobs: # os: Windows runs-on: ${{ matrix.runner_os }} + timeout-minutes: 30 env: VERBOSE: 1 steps: diff --git a/README.md b/README.md index c026225..23777a4 100644 --- a/README.md +++ b/README.md @@ -338,6 +338,12 @@ Creates Conan packages for a specific platform/architecture and uploads to a rep - `compiler_profile` (string, **required**): Compiler profile path - `dir` (string): Conan package directory. Default: "." - `remote_url` (string): Conan repository URL. Default: "" +- `extra_conan_arguments` (string): Extra arguments for `conan create`. + Default: "" +- `build_types` (string): Comma separated build types to create. Default: + "Debug,MinSizeRel,Release" +- `timeout_minutes` (number): Cancel the job if it runs longer than this. + Default: 30 **Secrets:** @@ -364,7 +370,7 @@ jobs: ### package_and_upload_all.yml -Creates Conan packages for all supported platforms and architectures. +Creates Conan packages for the platforms and architectures libhal supports. **Inputs:** @@ -374,19 +380,38 @@ Creates Conan packages for all supported platforms and architectures. - `conan_version` (string): Conan version. Default: "2.22.2" - `dir` (string): Conan package directory. Default: "." - `remote_url` (string): Conan repository URL. Default: "" +- `modules_support_needed` (boolean): The package uses C++20 modules, so the + GCC Cortex-M job is skipped. Default: `false` +- `coroutine_support_needed` (boolean): The package uses coroutines, so + ARMv6-M (Cortex-M0, M0+, M1) is skipped. Default: `false` +- `llvm_profile` (string): Compiler profile for the LLVM builds, e.g. + "hal/tc/llvm-23". Default: "hal/tc/llvm" +- `extra_conan_arguments` (string): Extra arguments for `conan create`. + Default: "" +- `ci_ref` (string): Git ref of libhal/ci to take scripts from. Default: + "5.x.y" **Secrets:** - `conan_remote_user`: Username for Conan repository - `conan_remote_password`: Password for Conan repository -Builds packages for: +It runs in one of two modes, picked by `version`: -- Linux x86_64 (LLVM) -- Linux armv8 (LLVM) -- macOS armv8 (LLVM) -- Cortex-M0+, M1, M3, M4, M4F, M7F, M7D (ARM GCC) -- Cortex-M23, M33, M33F, M35PF, M55, M85 (ARM GCC) +| | Check (`version: latest`, nothing uploaded) | Deploy (`version` set) | +| --- | --- | --- | +| Build types | `MinSizeRel` | `Debug`, `MinSizeRel`, `Release` | +| Linux x86_64, Linux armv8, macOS armv8 (LLVM) | ✅ | ✅ | +| Cortex-M (LLVM) | M0+, M3, M4F, M33F in one job | M0, M0+, M1, M3, M4, M4F, M7F, M7D and M23, M33, M33F, M35PF, M55, M85 in two jobs | +| Cortex-M (GCC, when `modules_support_needed` is false) | M0+, M3, M4F, M33F | every Cortex-M architecture | + +Check mode keeps pull requests and pushes to main cheap. Deploys still build +everything they upload. A first "📋 Plan" job makes these choices in one +place and the build jobs read its outputs. ARMv6-M (M0, M0+, M1) is left out of both when +`coroutine_support_needed` is true. + +Host jobs time out after 30 minutes and Cortex-M jobs after 45, so a hung +runner can't run for hours. **Usage:** @@ -425,7 +450,9 @@ Runs unit tests on multiple platforms. Runs tests on: - Ubuntu 24.04 (x86_64, Linux) -- macOS latest (armv8, macOS) +- macOS 15 (armv8, macOS) + +Each job times out after 30 minutes. **Usage:**