diff --git a/.github/workflows/develop-pr-regression.yml b/.github/workflows/develop-pr-regression.yml new file mode 100644 index 0000000000..8e65ef2265 --- /dev/null +++ b/.github/workflows/develop-pr-regression.yml @@ -0,0 +1,54 @@ +# SPDX-FileCopyrightText: 2024 3mdeb +# +# SPDX-License-Identifier: Apache-2.0 + +name: Smoke tests on selected platforms + +# Only try to run if a robot file or a lib was modified in the PR +on: + pull_request: + branches: + - develop + paths: + - '**.robot' + - 'lib/**' + +concurrency: + group: shared-resource-lock + cancel-in-progress: false + +jobs: + build: + runs-on: self-hosted + + steps: + - name: Checkout repository and submodules + uses: actions/checkout@v2 + with: + submodules: 'recursive' + fetch-depth: 0 + + - name: Fetch develop branch + run: git fetch origin develop + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.11' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Execute robot command + run: | + scripts/ci/develop_pr_auto_regression.sh + + - name: Upload HTML files as artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: HTML-Reports + path: | + logs/ diff --git a/.github/workflows/qemu-self-test.yml b/.github/workflows/qemu-self-test.yml index 6a5be9d37d..6af363e3e6 100644 --- a/.github/workflows/qemu-self-test.yml +++ b/.github/workflows/qemu-self-test.yml @@ -19,7 +19,6 @@ on: - 'scripts/ci/qemu-self-test.sh' - 'scripts/ci/qemu-run.sh' - 'requirements.txt' - workflow_dispatch: jobs: qemu: diff --git a/scripts/ci/develop_pr_auto_regression.sh b/scripts/ci/develop_pr_auto_regression.sh new file mode 100755 index 0000000000..eee8c706eb --- /dev/null +++ b/scripts/ci/develop_pr_auto_regression.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2025 3mdeb +# +# SPDX-License-Identifier: Apache-2.0 + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +echo "Comparing $(git rev-parse HEAD) with develop branch. Changed files:" +git diff --name-only origin/develop + +mapfile -t commands < <(${SCRIPT_DIR}/regression-scope/osfv_regression_scope.py commands --compare_to origin/develop) +echo "Commands to run:" +echo "${commands[@]}" +printf "\n" + +if [[ ${#commands[@]} -eq 0 ]]; then + echo "No tests required to run for these changes." +fi + +pids=() +statuses=() +LOGS_DIR="./logs" +mkdir $LOGS_DIR/ || true +i=1 +for command in "${commands[@]}"; do + ( + echo "Executing: ${command}" + eval ${command} > "$LOGS_DIR/run_${i}.log" 2>&1 + ) & + pids[${i}]=$! + (( i++ )) +done + +sleep 1 + +for idx in "${!pids[@]}"; do + echo "Waiting for run $idx to finish..." + if wait ${pids[$idx]}; then + statuses[idx]=0 + echo "run $idx is done." + else + statuses[idx]=$? + echo "run $idx failed." + fi +done + + +exit_code=0 +i=0 +for code in "${statuses[@]}"; do + if [[ "$code" -ne 0 ]]; then + echo "Run ${i} failed with exit code ${code}. Check $LOGS_DIR/run_${i}.log for details." + exit_code=1 + fi + (( i++)) +done + +exit $exit_code diff --git a/scripts/ci/regression-scope/lib/parser_manager.py b/scripts/ci/regression-scope/lib/parser_manager.py index ae70d7d022..5681cfce6f 100644 --- a/scripts/ci/regression-scope/lib/parser_manager.py +++ b/scripts/ci/regression-scope/lib/parser_manager.py @@ -36,14 +36,15 @@ def _assemble_commands_from_runs_data(self, runs_data): """ commands = [] for data in runs_data: + run = [] if len(data["env"]) > 0: - commands.append(data["env"]) + run.extend(data["env"]) + run.append("&&") if len(data["files"]) > 0: - commands.append( - self._assemble_robot_command(data["files"], data["args"]) - ) + run.extend(self._assemble_robot_command(data["files"], data["args"])) else: - commands.append(data["command"]) + run.extend(data["command"]) + commands.append(run) return commands def _uniqeuify_runs_data(self, parser_runs_data, by=["env", "args"]): @@ -86,7 +87,8 @@ def commands(self): Each line is one command. """ uniquified = self._uniqeuify_runs_data(self.runs_data, ["env", "args"]) - return self._assemble_commands_from_runs_data(uniquified) + commands = self._assemble_commands_from_runs_data(uniquified) + return commands def wrapper_args(self): """ diff --git a/scripts/ci/regression-scope/osfv_regression_scope.py b/scripts/ci/regression-scope/osfv_regression_scope.py index 26510f42cb..301b2d81c7 100755 --- a/scripts/ci/regression-scope/osfv_regression_scope.py +++ b/scripts/ci/regression-scope/osfv_regression_scope.py @@ -62,7 +62,8 @@ def commands( self.changed_files = get_changed_files(compare_to) parser = ParserManager(self.rules, self.changed_files) parser.parse() - print(" ".join(cmd for sublist in parser.commands() for cmd in sublist)) + for command in parser.commands(): + print(" ".join(command)) def robot_args( self, rules_file="scripts/ci/regression-scope/rules.json", compare_to="HEAD" diff --git a/scripts/ci/regression-scope/regression_scope_selftests.py b/scripts/ci/regression-scope/regression_scope_selftests.py index ffe4a53b05..c52f270065 100755 --- a/scripts/ci/regression-scope/regression_scope_selftests.py +++ b/scripts/ci/regression-scope/regression_scope_selftests.py @@ -176,8 +176,7 @@ def test_single_module_single_change(self): "FW_FILE=scripts/ci/qemu_q35.rom", "export", "CONFIG=qemu", - ], - [ + "&&", "scripts/run.sh", "dasharo-compatibility/audio-subsystem.robot", "--", @@ -214,8 +213,7 @@ def test_single_module_multiple_changes(self): "FW_FILE=scripts/ci/qemu_q35.rom", "export", "CONFIG=qemu", - ], - [ + "&&", "scripts/run.sh", "dasharo-compatibility/audio-subsystem.robot", "dasharo-compatibility/cpu-status.robot", diff --git a/scripts/ci/regression-scope/rules.json b/scripts/ci/regression-scope/rules.json index 655abfc185..95a2f4ffba 100644 --- a/scripts/ci/regression-scope/rules.json +++ b/scripts/ci/regression-scope/rules.json @@ -6,14 +6,25 @@ "run": [ { "env_vars": { - "RTE_IP": "127.0.0.1", - "FW_FILE": "scripts/ci/qemu_q35.rom", - "CONFIG": "qemu" + "RTE_IP": "192.168.10.199", + "SONOFF_IP": "192.168.10.169", + "PIKVM_IP": "192.168.10.120", + "SNIPEIT_NO": "true", + "CONFIG": "msi-pro-z690-a-wifi-ddr4" }, "files": { "mode": "${FULL_FILENAME_MATCH}" + } + }, + { + "env_vars": { + "RTE_IP": "192.168.10.171", + "SNIPEIT_NO": "true", + "CONFIG": "pcengines-apu3" }, - "snipeit": "no" + "files": { + "mode": "${FULL_FILENAME_MATCH}" + } } ] }, @@ -23,15 +34,27 @@ "run": [ { "env_vars": { - "RTE_IP": "127.0.0.1", - "FW_FILE": "scripts/ci/qemu_q35.rom", - "CONFIG": "qemu" + "RTE_IP": "192.168.10.199", + "SNIPEIT_NO": "true", + "SONOFF_IP": "192.168.10.169", + "PIKVM_IP": "192.168.10.16", + "CONFIG": "msi-pro-z690-a-wifi-ddr4" }, "files": { "mode": "${FILE_CONTAINS_MATCH}", "search_in": ["dasharo-compatibility", "dasharo-security", "dasharo-performance", "dasharo-stability"] + } + }, + { + "env_vars": { + "RTE_IP": "192.168.10.171", + "SNIPEIT_NO": "true", + "CONFIG": "pcengines-apu3" }, - "snipeit": "no" + "files": { + "mode": "${FILE_CONTAINS_MATCH}", + "search_in": ["dasharo-compatibility", "dasharo-security", "dasharo-performance", "dasharo-stability"] + } } ] }