From 79162646d8deac2a3fe3d89817d7df4eba9213ec Mon Sep 17 00:00:00 2001 From: Sourabh Mehta Date: Wed, 7 Jan 2026 14:54:46 +0100 Subject: [PATCH] Improved CI workflow with concurrenct setup/installation and updates --- .github/scripts/run-tests.sh | 195 ++++++++++++++++++ .github/test-matrix.json | 23 +++ .../workflows/hello-ci-ubuntu-2404-arm.yml | 73 ++----- .github/workflows/hello-ci.yml | 75 ++----- 4 files changed, 257 insertions(+), 109 deletions(-) create mode 100644 .github/scripts/run-tests.sh create mode 100644 .github/test-matrix.json diff --git a/.github/scripts/run-tests.sh b/.github/scripts/run-tests.sh new file mode 100644 index 0000000..f65b934 --- /dev/null +++ b/.github/scripts/run-tests.sh @@ -0,0 +1,195 @@ +#!/bin/bash +set -e # Exit on error + +# Script to run all test configurations +# Usage: ./run-tests.sh + +CONFIG_FILE="${1:-.github/workflows/test-matrix.json}" + +# Initialize counters and tracking +total=0 +passed=0 +failed=0 +declare -a failed_configs +declare -a failed_log_dirs + +# Initialize GitHub Summary if running in GitHub Actions +if [ -n "$GITHUB_STEP_SUMMARY" ]; then + echo "# Build and Execution Test Results" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "| # | Configuration | Status | Details |" >> "$GITHUB_STEP_SUMMARY" + echo "|---|---------------|--------|---------|" >> "$GITHUB_STEP_SUMMARY" +fi + +# Function to add result to summary +add_to_summary() { + local num=$1 + local config=$2 + local status=$3 + local details=$4 + + if [ -n "$GITHUB_STEP_SUMMARY" ]; then + echo "| $num | $config | $status | $details |" >> "$GITHUB_STEP_SUMMARY" + fi +} + +# Function to build, execute and verify a configuration +test_configuration() { + local compiler=$1 + local ext=$2 + local target=$3 + local model=$4 + local uart=$5 + local build=$6 + + local config_name="$build+$target with $compiler" + local failure_reason="" + local log_file="./logs/${target}_${compiler}_${build}.log" + + # Create logs directory + mkdir -p "./logs" + + # Initialize log file with header + echo "=========================================" > "$log_file" + echo "Configuration: $config_name" >> "$log_file" + echo "Date: $(date)" >> "$log_file" + echo "=========================================" >> "$log_file" + echo "" >> "$log_file" + + echo "" + echo "==========================================" + echo "[$total/60] Testing: $config_name" + echo "==========================================" + + # Build + echo "▶ Building..." + echo "=========================================" >> "$log_file" + echo "BUILD OUTPUT" >> "$log_file" + echo "=========================================" >> "$log_file" + if ! cbuild Hello.csolution.yml --packs \ + --context "Hello.$build+$target" \ + --toolchain "$compiler" --rebuild 2>&1 | tee -a "$log_file"; then + failure_reason="Build failed" + echo "✗ $failure_reason" + echo "" >> "$log_file" + echo "Result: FAILED - $failure_reason" >> "$log_file" + failed=$((failed + 1)) + failed_configs+=("[$total] $config_name - $failure_reason") + failed_log_dirs+=("$log_file") + add_to_summary "$total" "$config_name" "❌ Failed" "$failure_reason" + return 1 + fi + echo "✅ Build successful" + + # Execute + echo "▶ Executing on $model..." + echo "" >> "$log_file" + echo "=========================================" >> "$log_file" + echo "EXECUTION OUTPUT" >> "$log_file" + echo "=========================================" >> "$log_file" + if ! "$model" \ + -a "./out/Hello/$target/$build/$compiler/Hello.$ext" \ + -f "./FVP/$model/fvp_config.txt" \ + -C "$uart.out_file=./out/Hello/$target/$build/$compiler/fvp_stdout.log" \ + --simlimit 60 --stat 2>&1 | tee -a "$log_file"; then + failure_reason="Execution failed" + echo "❌ $failure_reason" + echo "" >> "$log_file" + echo "Result: FAILED - $failure_reason" >> "$log_file" + failed=$((failed + 1)) + failed_configs+=("[$total] $config_name - $failure_reason") + failed_log_dirs+=("$log_file") + add_to_summary "$total" "$config_name" "❌ Failed" "$failure_reason" + return 1 + fi + echo "✅ Execution successful" + + echo "Actual UART output:" + cat "./out/Hello/$target/$build/$compiler/fvp_stdout.log" || echo "Could not read log file" + + if grep -q "Hello World 100" "./out/Hello/$target/$build/$compiler/fvp_stdout.log"; then + echo "✅ Test PASSED" + passed=$((passed + 1)) + add_to_summary "$total" "$config_name" "✅ Passed" "" + # Clean up log for passed test + rm -f "$log_file" + return 0 + else + failure_reason="Verification failed - 'Hello World 100' not found" + echo "❌ $failure_reason" + + # Add UART output to log file + echo "" >> "$log_file" + echo "=========================================" >> "$log_file" + echo "UART OUTPUT" >> "$log_file" + echo "=========================================" >> "$log_file" + cat "./out/Hello/$target/$build/$compiler/fvp_stdout.log" >> "$log_file" 2>/dev/null || echo "Could not read UART log" >> "$log_file" + echo "" >> "$log_file" + echo "Result: FAILED - $failure_reason" >> "$log_file" + + failed=$((failed + 1)) + failed_configs+=("[$total] $config_name - $failure_reason") + failed_log_dirs+=("$log_file") + add_to_summary "$total" "$config_name" "❌ Failed" "$failure_reason" + return 1 + fi +} + +# Main execution loop +echo "Reading configurations from: $CONFIG_FILE" + +# Generate all combinations from compilers × targets × builds +while IFS= read -r compiler_data; do + compiler=$(echo "$compiler_data" | jq -r '.name') + ext=$(echo "$compiler_data" | jq -r '.ext') + + while IFS= read -r target_data; do + target=$(echo "$target_data" | jq -r '.type') + model=$(echo "$target_data" | jq -r '.model') + uart=$(echo "$target_data" | jq -r '.uart') + + while IFS= read -r build; do + total=$((total + 1)) + test_configuration "$compiler" "$ext" "$target" "$model" "$uart" "$build" || true + done < <(jq -r '.builds[]' "$CONFIG_FILE") + + done < <(jq -c '.targets[]' "$CONFIG_FILE") + +done < <(jq -c '.compilers[]' "$CONFIG_FILE") + +# Add summary statistics to GitHub Summary +if [ -n "$GITHUB_STEP_SUMMARY" ]; then + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "## Summary" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "- **Total Configurations:** $total" >> "$GITHUB_STEP_SUMMARY" + echo "- **✅ Passed:** $passed" >> "$GITHUB_STEP_SUMMARY" + echo "- **❌ Failed:** $failed" >> "$GITHUB_STEP_SUMMARY" +fi + +# Print comprehensive summary +echo "" +echo "==========================================" +echo " FINAL SUMMARY" +echo "==========================================" +echo "Total configurations: $total" +echo "Passed: $passed" +echo "Failed: $failed" +echo "" + +if [ $failed -gt 0 ]; then + echo "❌ FAILED CONFIGURATIONS:" + echo "==========================================" + for fail_info in "${failed_configs[@]}"; do + echo "$fail_info" + done + echo "==========================================" + echo "" + echo "Logs for failed configurations saved in: ./logs/" + echo "Total failed log files: ${#failed_log_dirs[@]}" + exit 1 +else + echo "✅ All tests passed!" + # Clean up logs directory if all tests passed + rm -rf ./logs +fi diff --git a/.github/test-matrix.json b/.github/test-matrix.json new file mode 100644 index 0000000..b8094ef --- /dev/null +++ b/.github/test-matrix.json @@ -0,0 +1,23 @@ +{ + "compilers": [ + {"name": "AC6", "ext": "axf"}, + {"name": "GCC", "ext": "elf"} + ], + "targets": [ + {"type": "CM0", "model": "FVP_MPS2_Cortex-M0", "uart": "fvp_mps2.UART0"}, + {"type": "CM0plus", "model": "FVP_MPS2_Cortex-M0plus", "uart": "fvp_mps2.UART0"}, + {"type": "CM3", "model": "FVP_MPS2_Cortex-M3", "uart": "fvp_mps2.UART0"}, + {"type": "CM4", "model": "FVP_MPS2_Cortex-M4", "uart": "fvp_mps2.UART0"}, + {"type": "CM4_FP", "model": "FVP_MPS2_Cortex-M4", "uart": "fvp_mps2.UART0"}, + {"type": "CM7", "model": "FVP_MPS2_Cortex-M7", "uart": "fvp_mps2.UART0"}, + {"type": "CM7_SP", "model": "FVP_MPS2_Cortex-M7", "uart": "fvp_mps2.UART0"}, + {"type": "CM7_DP", "model": "FVP_MPS2_Cortex-M7", "uart": "fvp_mps2.UART0"}, + {"type": "CM23", "model": "FVP_MPS2_Cortex-M23", "uart": "fvp_mps2.UART0"}, + {"type": "CM33", "model": "FVP_MPS2_Cortex-M33", "uart": "fvp_mps2.UART0"}, + {"type": "CM33_FP", "model": "FVP_MPS2_Cortex-M33", "uart": "fvp_mps2.UART0"}, + {"type": "CS300", "model": "FVP_Corstone_SSE-300", "uart": "mps3_board.uart0"}, + {"type": "CS310", "model": "FVP_Corstone_SSE-310", "uart": "mps3_board.uart0"}, + {"type": "CS315", "model": "FVP_Corstone_SSE-315", "uart": "mps4_board.uart0"} + ], + "builds": ["Release", "Debug"] +} diff --git a/.github/workflows/hello-ci-ubuntu-2404-arm.yml b/.github/workflows/hello-ci-ubuntu-2404-arm.yml index 061828e..e2d03a1 100644 --- a/.github/workflows/hello-ci-ubuntu-2404-arm.yml +++ b/.github/workflows/hello-ci-ubuntu-2404-arm.yml @@ -14,41 +14,17 @@ env: GIT_TRACE: True GIT_SSH_COMMAND: ssh -vvv +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true # Cancel previous runs on new push + jobs: install_build_execute: runs-on: ubuntu-24.04-arm - strategy: - matrix: - compiler: [ - {name: AC6, ext: axf}, - {name: GCC, ext: elf} - ] - target: [ - {type: CM0, model: FVP_MPS2_Cortex-M0, uart: fvp_mps2.UART0}, - {type: CM0plus, model: FVP_MPS2_Cortex-M0plus, uart: fvp_mps2.UART0}, - {type: CM3, model: FVP_MPS2_Cortex-M3, uart: fvp_mps2.UART0}, - {type: CM4, model: FVP_MPS2_Cortex-M4, uart: fvp_mps2.UART0}, - {type: CM4_FP, model: FVP_MPS2_Cortex-M4, uart: fvp_mps2.UART0}, - {type: CM7, model: FVP_MPS2_Cortex-M7, uart: fvp_mps2.UART0}, - {type: CM7_SP, model: FVP_MPS2_Cortex-M7, uart: fvp_mps2.UART0}, - {type: CM7_DP, model: FVP_MPS2_Cortex-M7, uart: fvp_mps2.UART0}, - {type: CM23, model: FVP_MPS2_Cortex-M23, uart: fvp_mps2.UART0}, - {type: CM33, model: FVP_MPS2_Cortex-M33, uart: fvp_mps2.UART0}, - {type: CM33_FP, model: FVP_MPS2_Cortex-M33, uart: fvp_mps2.UART0}, - {type: CS300, model: FVP_Corstone_SSE-300, uart: mps3_board.uart0}, - {type: CS310, model: FVP_Corstone_SSE-310, uart: mps3_board.uart0}, - {type: CS315, model: FVP_Corstone_SSE-315, uart: mps4_board.uart0}, - {type: CS320, model: FVP_Corstone_SSE-320, uart: mps4_board.uart0} - ] - build: [ - {type: Release}, - {type: Debug} - ] - steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install tools uses: ARM-software/cmsis-actions/vcpkg@v1 @@ -57,34 +33,23 @@ jobs: uses: ARM-software/cmsis-actions/armlm@v1 - name: Cache packs - uses: actions/cache@v4 + uses: actions/cache@v5 with: - key: cmsis-packs + key: cmsis-packs-${{ hashFiles('*.csolution.yml', '*.cproject.yml') }} + restore-keys: | + cmsis-packs- path: /home/runner/.cache/arm/packs - - name: Build context Hello.${{ matrix.build.type }}+${{ matrix.target.type }} with ${{ matrix.compiler.name }} + - name: Build and Execute All Configurations working-directory: ./ run: | - cbuild Hello.csolution.yml --packs \ - --context Hello.${{ matrix.build.type }}+${{ matrix.target.type }} \ - --toolchain ${{ matrix.compiler.name }} --rebuild + chmod +x .github/scripts/run-tests.sh + .github/scripts/run-tests.sh .github/test-matrix.json - - name: Execute context Hello.${{ matrix.build.type }}+${{ matrix.target.type }} with ${{ matrix.compiler.name }} - working-directory: ./ - run: | - ${{ matrix.target.model }} \ - -a ./out/Hello/${{ matrix.target.type }}/${{ matrix.build.type }}/${{ matrix.compiler.name }}/Hello.${{ matrix.compiler.ext }} \ - -f ./FVP/${{ matrix.target.model }}/fvp_config.txt \ - -C ${{ matrix.target.uart }}.out_file=./out/Hello/${{ matrix.target.type }}/${{ matrix.build.type }}/${{ matrix.compiler.name }}/fvp_stdout.log \ - --simlimit 60 --stat - - echo " Show simulation UART output" - cat ./out/Hello/${{ matrix.target.type }}/${{ matrix.build.type }}/${{ matrix.compiler.name }}/fvp_stdout.log - - echo "Checking simulation UART output" - if [ "$(grep -c "Hello World 100" ./out/Hello/${{ matrix.target.type }}/${{ matrix.build.type }}/${{ matrix.compiler.name }}/fvp_stdout.log)" -eq 1 ] - then - exit 0 - else - exit 1 - fi + - name: Upload Failed Test Logs + if: failure() + uses: actions/upload-artifact@v6 + with: + name: failed-test-logs-${{ github.workflow }} + path: logs/ + retention-days: 30 diff --git a/.github/workflows/hello-ci.yml b/.github/workflows/hello-ci.yml index 098899e..52e5acc 100644 --- a/.github/workflows/hello-ci.yml +++ b/.github/workflows/hello-ci.yml @@ -9,41 +9,17 @@ on: schedule: - cron: '0 6 * * 1' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true # Cancel previous runs on new push + jobs: - install_build_execute: + build_and_test: runs-on: ubuntu-latest - strategy: - matrix: - compiler: [ - {name: AC6, ext: axf}, - {name: GCC, ext: elf} - ] - target: [ - {type: CM0, model: FVP_MPS2_Cortex-M0, uart: fvp_mps2.UART0}, - {type: CM0plus, model: FVP_MPS2_Cortex-M0plus, uart: fvp_mps2.UART0}, - {type: CM3, model: FVP_MPS2_Cortex-M3, uart: fvp_mps2.UART0}, - {type: CM4, model: FVP_MPS2_Cortex-M4, uart: fvp_mps2.UART0}, - {type: CM4_FP, model: FVP_MPS2_Cortex-M4, uart: fvp_mps2.UART0}, - {type: CM7, model: FVP_MPS2_Cortex-M7, uart: fvp_mps2.UART0}, - {type: CM7_SP, model: FVP_MPS2_Cortex-M7, uart: fvp_mps2.UART0}, - {type: CM7_DP, model: FVP_MPS2_Cortex-M7, uart: fvp_mps2.UART0}, - {type: CM23, model: FVP_MPS2_Cortex-M23, uart: fvp_mps2.UART0}, - {type: CM33, model: FVP_MPS2_Cortex-M33, uart: fvp_mps2.UART0}, - {type: CM33_FP, model: FVP_MPS2_Cortex-M33, uart: fvp_mps2.UART0}, - {type: CS300, model: FVP_Corstone_SSE-300, uart: mps3_board.uart0}, - {type: CS310, model: FVP_Corstone_SSE-310, uart: mps3_board.uart0}, - {type: CS315, model: FVP_Corstone_SSE-315, uart: mps4_board.uart0}, - {type: CS320, model: FVP_Corstone_SSE-320, uart: mps4_board.uart0} - ] - build: [ - {type: Release}, - {type: Debug} - ] - steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install tools uses: ARM-software/cmsis-actions/vcpkg@v1 @@ -52,34 +28,23 @@ jobs: uses: ARM-software/cmsis-actions/armlm@v1 - name: Cache packs - uses: actions/cache@v4 + uses: actions/cache@v5 with: - key: cmsis-packs + key: cmsis-packs-${{ hashFiles('*.csolution.yml', '*.cproject.yml') }} + restore-keys: | + cmsis-packs- path: /home/runner/.cache/arm/packs - - name: Build context Hello.${{ matrix.build.type }}+${{ matrix.target.type }} with ${{ matrix.compiler.name }} + - name: Build and Execute All Configurations working-directory: ./ run: | - cbuild Hello.csolution.yml --packs \ - --context Hello.${{ matrix.build.type }}+${{ matrix.target.type }} \ - --toolchain ${{ matrix.compiler.name }} --rebuild + chmod +x .github/scripts/run-tests.sh + .github/scripts/run-tests.sh .github/test-matrix.json - - name: Execute context Hello.${{ matrix.build.type }}+${{ matrix.target.type }} with ${{ matrix.compiler.name }} - working-directory: ./ - run: | - ${{ matrix.target.model }} \ - -a ./out/Hello/${{ matrix.target.type }}/${{ matrix.build.type }}/${{ matrix.compiler.name }}/Hello.${{ matrix.compiler.ext }} \ - -f ./FVP/${{ matrix.target.model }}/fvp_config.txt \ - -C ${{ matrix.target.uart }}.out_file=./out/Hello/${{ matrix.target.type }}/${{ matrix.build.type }}/${{ matrix.compiler.name }}/fvp_stdout.log \ - --simlimit 60 --stat - - echo " Show simulation UART output" - cat ./out/Hello/${{ matrix.target.type }}/${{ matrix.build.type }}/${{ matrix.compiler.name }}/fvp_stdout.log - - echo "Checking simulation UART output" - if [ "$(grep -c "Hello World 100" ./out/Hello/${{ matrix.target.type }}/${{ matrix.build.type }}/${{ matrix.compiler.name }}/fvp_stdout.log)" -eq 1 ] - then - exit 0 - else - exit 1 - fi + - name: Upload Failed Test Logs + if: failure() + uses: actions/upload-artifact@v6 + with: + name: failed-test-logs-${{ github.workflow }} + path: logs/ + retention-days: 30