summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCYFS <[email protected]>2026-06-26 11:05:32 +0800
committerRbb666 <[email protected]>2026-06-26 16:40:09 +0800
commit64651f968a2eafc9c92bfb5c567cfa21f5ddca4f (patch)
tree279c84bd92671d5ec9605290b61e77367f7a4180
parentc374e529c4e04b31cb4505f57f7abd217e6b62ae (diff)
ci: optimize membrowse target filtering
-rw-r--r--.github/membrowse-targets.json129
-rw-r--r--.github/workflows/membrowse-report.yml43
-rw-r--r--tools/ci/membrowse_filter_targets.py116
3 files changed, 267 insertions, 21 deletions
diff --git a/.github/membrowse-targets.json b/.github/membrowse-targets.json
index dae01eac5b..1e60c22bce 100644
--- a/.github/membrowse-targets.json
+++ b/.github/membrowse-targets.json
@@ -6,7 +6,12 @@
"elf": "bsp/stm32/stm32f407-rt-spark/rt-thread.elf",
"ld": "bsp/stm32/stm32f407-rt-spark/board/linker_scripts/link.lds",
"map_file": "bsp/stm32/stm32f407-rt-spark/rt-thread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/stm32/stm32f407-rt-spark",
+ "bsp/stm32/libraries",
+ "bsp/stm32/tools"
+ ]
},
{
"target_name": "stm32l475-atk-pandora-llvm",
@@ -16,7 +21,12 @@
"elf": "bsp/stm32/stm32l475-atk-pandora/rt-thread.elf",
"ld": "bsp/stm32/stm32l475-atk-pandora/board/linker_scripts/link.lds",
"map_file": "bsp/stm32/stm32l475-atk-pandora/rt-thread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/stm32/stm32l475-atk-pandora",
+ "bsp/stm32/libraries",
+ "bsp/stm32/tools"
+ ]
},
{
"target_name": "raspberry-pico-rp2040",
@@ -25,7 +35,12 @@
"elf": "bsp/raspberry-pico/RP2040/rtthread-pico.elf",
"ld": "bsp/raspberry-pico/RP2040/link.ld",
"map_file": "bsp/raspberry-pico/RP2040/rt-thread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/raspberry-pico/RP2040",
+ "bsp/raspberry-pico/libraries",
+ "bsp/raspberry-pico/tools"
+ ]
},
{
"target_name": "at32f415-start",
@@ -34,7 +49,12 @@
"elf": "bsp/at32/at32f415-start/rtthread.elf",
"ld": "bsp/at32/at32f415-start/board/linker_scripts/link.lds",
"map_file": "bsp/at32/at32f415-start/rt-thread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/at32/at32f415-start",
+ "bsp/at32/libraries",
+ "bsp/at32/tools"
+ ]
},
{
"target_name": "gd32105r-start",
@@ -43,7 +63,12 @@
"elf": "bsp/gd32/arm/gd32105r-start/rtthread.elf",
"ld": "bsp/gd32/arm/gd32105r-start/board/linker_scripts/link.ld",
"map_file": "bsp/gd32/arm/gd32105r-start/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/gd32/arm/gd32105r-start",
+ "bsp/gd32/arm/libraries",
+ "bsp/gd32/arm/tools"
+ ]
},
{
"target_name": "hc32f334",
@@ -52,7 +77,13 @@
"elf": "bsp/hc32/ev_hc32f334_lqfp64/rtthread.elf",
"ld": "bsp/hc32/ev_hc32f334_lqfp64/board/linker_scripts/link.ld",
"map_file": "bsp/hc32/ev_hc32f334_lqfp64/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/hc32/ev_hc32f334_lqfp64",
+ "bsp/hc32/libraries",
+ "bsp/hc32/platform",
+ "bsp/hc32/tools"
+ ]
},
{
"target_name": "nxp-lpc1114",
@@ -61,7 +92,10 @@
"elf": "bsp/nxp/lpc/lpc1114/rtthread-lpc1114.elf",
"ld": "bsp/nxp/lpc/lpc1114/link.lds",
"map_file": "bsp/nxp/lpc/lpc1114/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/nxp/lpc/lpc1114"
+ ]
},
{
"target_name": "nordic-nrf51822",
@@ -70,7 +104,12 @@
"elf": "bsp/nrf5x/nrf51822/rt-thread.elf",
"ld": "bsp/nrf5x/nrf51822/board/linker_scripts/link.lds",
"map_file": "bsp/nrf5x/nrf51822/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/nrf5x/nrf51822",
+ "bsp/nrf5x/libraries",
+ "bsp/nrf5x/tools"
+ ]
},
{
"target_name": "nuvoton-m487",
@@ -79,7 +118,12 @@
"elf": "bsp/nuvoton/numaker-iot-m487/rtthread.elf",
"ld": "bsp/nuvoton/numaker-iot-m487/linking_scripts/m480_link.ld",
"map_file": "bsp/nuvoton/numaker-iot-m487/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/nuvoton/numaker-iot-m487",
+ "bsp/nuvoton/libraries",
+ "bsp/nuvoton/tools"
+ ]
},
{
"target_name": "infineon-psoc6",
@@ -88,7 +132,12 @@
"elf": "bsp/Infineon/psoc6-cy8ckit-062s4/rt-thread.elf",
"ld": "bsp/Infineon/psoc6-cy8ckit-062s4/board/linker_scripts/link.ld",
"map_file": "bsp/Infineon/psoc6-cy8ckit-062s4/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/Infineon/psoc6-cy8ckit-062s4",
+ "bsp/Infineon/libraries",
+ "bsp/Infineon/tools"
+ ]
},
{
"target_name": "renesas-ra2l1",
@@ -97,7 +146,12 @@
"elf": "bsp/renesas/ra2l1-cpk/rtthread.elf",
"ld": "bsp/renesas/ra2l1-cpk/script/fsp.ld",
"map_file": "bsp/renesas/ra2l1-cpk/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/renesas/ra2l1-cpk",
+ "bsp/renesas/libraries",
+ "bsp/renesas/tools"
+ ]
},
{
"target_name": "qemu-virt64-aarch64",
@@ -106,7 +160,10 @@
"elf": "bsp/qemu-virt64-aarch64/rtthread.elf",
"ld": "libcpu/aarch64/link.lds",
"map_file": "bsp/qemu-virt64-aarch64/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/qemu-virt64-aarch64"
+ ]
},
{
"target_name": "wch-ch32v208w-r0",
@@ -115,7 +172,12 @@
"elf": "bsp/wch/risc-v/ch32v208w-r0/rtthread.elf",
"ld": "bsp/wch/risc-v/ch32v208w-r0/board/linker_scripts/link.lds",
"map_file": "bsp/wch/risc-v/ch32v208w-r0/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/wch/risc-v/ch32v208w-r0",
+ "bsp/wch/risc-v/Libraries",
+ "bsp/wch/risc-v/tools"
+ ]
},
{
"target_name": "hpmicro-hpm5301evklite",
@@ -124,7 +186,12 @@
"elf": "bsp/hpmicro/hpm5301evklite/rtthread.elf",
"ld": "bsp/hpmicro/hpm5301evklite/board/linker_scripts/gcc/flash_rtt.ld",
"map_file": "",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/hpmicro/hpm5301evklite",
+ "bsp/hpmicro/libraries",
+ "bsp/hpmicro/tools"
+ ]
},
{
"target_name": "xuantie-e901plus",
@@ -133,7 +200,12 @@
"elf": "bsp/xuantie/smartl/e901plus/rtthread.elf",
"ld": "bsp/xuantie/libraries/xuantie_libraries/chip_riscv_dummy/gcc_flash_smartl_lite.ld",
"map_file": "bsp/xuantie/smartl/e901plus/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/xuantie/smartl/e901plus",
+ "bsp/xuantie/libraries",
+ "bsp/xuantie/tools"
+ ]
},
{
"target_name": "esp32-c3",
@@ -142,7 +214,12 @@
"elf": "bsp/ESP/ESP32_C3/rtthread.elf",
"ld": "bsp/ESP/ESP32_C3/idf_port/ld/memory.ld bsp/ESP/ESP32_C3/idf_port/ld/sections.ld",
"map_file": "bsp/ESP/ESP32_C3/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/ESP/ESP32_C3",
+ "bsp/ESP/libraries",
+ "bsp/ESP/tools"
+ ]
},
{
"target_name": "k230",
@@ -151,7 +228,10 @@
"elf": "bsp/k230/rtthread.elf",
"ld": "bsp/k230/link.lds.generated",
"map_file": "bsp/k230/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/k230"
+ ]
},
{
"target_name": "loongson-ls1cdev",
@@ -160,7 +240,10 @@
"elf": "bsp/loongson/ls1cdev/rtthread.elf",
"ld": "bsp/loongson/ls1cdev/ls1c_ram.lds",
"map_file": "bsp/loongson/ls1cdev/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/loongson/ls1cdev"
+ ]
},
{
"target_name": "x86",
@@ -169,7 +252,10 @@
"elf": "bsp/x86/rtthread.elf",
"ld": "bsp/x86/x86_ram.lds",
"map_file": "bsp/x86/rtthread.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/x86"
+ ]
},
{
"target_name": "simulator",
@@ -178,6 +264,9 @@
"elf": "bsp/simulator/rtthread",
"ld": "bsp/simulator/gcc_elf64.ld",
"map_file": "bsp/simulator/rtthread-linux.map",
- "linker_vars": ""
+ "linker_vars": "",
+ "watch_paths": [
+ "bsp/simulator"
+ ]
}
]
diff --git a/.github/workflows/membrowse-report.yml b/.github/workflows/membrowse-report.yml
index 98ea34ea86..79c88db841 100644
--- a/.github/workflows/membrowse-report.yml
+++ b/.github/workflows/membrowse-report.yml
@@ -2,9 +2,35 @@ name: MemBrowse Memory Report
on:
pull_request:
+ paths:
+ - '.github/membrowse-targets.json'
+ - '.github/workflows/membrowse-report.yml'
+ - 'Kconfig'
+ - 'bsp/**'
+ - 'components/**'
+ - 'include/**'
+ - 'libcpu/**'
+ - 'src/**'
+ - 'tools/**'
+ - '!**/README*'
+ - '!**/readme*'
+ - '!bsp/**/docs/**'
push:
branches:
- master
+ paths:
+ - '.github/membrowse-targets.json'
+ - '.github/workflows/membrowse-report.yml'
+ - 'Kconfig'
+ - 'bsp/**'
+ - 'components/**'
+ - 'include/**'
+ - 'libcpu/**'
+ - 'src/**'
+ - 'tools/**'
+ - '!**/README*'
+ - '!**/readme*'
+ - '!bsp/**/docs/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.sha || github.ref }}
@@ -15,16 +41,31 @@ jobs:
runs-on: ubuntu-22.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
+ target_count: ${{ steps.set-matrix.outputs.target_count }}
steps:
- name: Checkout repository
uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+
+ - name: Collect changed files
+ run: |
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
+ git diff --name-only origin/${{ github.base_ref }}...HEAD > changed_files.txt
+ elif [ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ]; then
+ git diff --name-only ${{ github.event.before }} ${{ github.sha }} > changed_files.txt
+ else
+ git diff --name-only origin/${{ github.event.repository.default_branch }}...HEAD > changed_files.txt
+ fi
+ cat changed_files.txt
- name: Load target matrix
id: set-matrix
- run: echo "matrix=$(jq -c '.' .github/membrowse-targets.json)" >> $GITHUB_OUTPUT
+ run: python3 tools/ci/membrowse_filter_targets.py --targets .github/membrowse-targets.json --changed-files changed_files.txt
analyze:
needs: load-targets
+ if: ${{ needs.load-targets.outputs.target_count != '0' }}
runs-on: ubuntu-22.04
strategy:
fail-fast: false
diff --git a/tools/ci/membrowse_filter_targets.py b/tools/ci/membrowse_filter_targets.py
new file mode 100644
index 0000000000..626adade8e
--- /dev/null
+++ b/tools/ci/membrowse_filter_targets.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2026, RT-Thread Development Team
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+import argparse
+import json
+import os
+
+
+GLOBAL_FILES = {
+ ".github/membrowse-targets.json",
+ ".github/workflows/membrowse-report.yml",
+ "Kconfig",
+}
+
+GLOBAL_PREFIXES = (
+ "components/",
+ "include/",
+ "libcpu/",
+ "src/",
+ "tools/",
+)
+
+def normalize_path(path):
+ return path.replace("\\", "/").strip().lstrip("./")
+
+
+def is_ignored_change(path):
+ name = path.rsplit("/", 1)[-1]
+ return name.lower().startswith("readme") or (path.startswith("bsp/") and "/docs/" in path)
+
+
+def is_under(path, prefix):
+ path = normalize_path(path)
+ prefix = normalize_path(prefix).rstrip("/")
+ return path == prefix or path.startswith(prefix + "/")
+
+
+def read_changed_files(path):
+ with open(path, "r", encoding="utf-8") as file:
+ return [
+ changed_file
+ for changed_file in (normalize_path(line) for line in file if line.strip())
+ if not is_ignored_change(changed_file)
+ ]
+
+
+def is_global_change(path):
+ return path in GLOBAL_FILES or any(path.startswith(prefix) for prefix in GLOBAL_PREFIXES)
+
+
+def target_related_prefixes(target):
+ return [
+ normalize_path(prefix)
+ for prefix in target.get("watch_paths", [target["bsp_path"]])
+ ]
+
+
+def select_targets(targets, changed_files):
+ if not changed_files:
+ return []
+
+ if any(is_global_change(path) for path in changed_files):
+ return targets
+
+ selected = []
+ for target in targets:
+ related_prefixes = target_related_prefixes(target)
+ if any(
+ is_under(changed_file, related_prefix)
+ for changed_file in changed_files
+ for related_prefix in related_prefixes
+ ):
+ selected.append(target)
+
+ return selected
+
+
+def write_github_output(matrix, output_path):
+ if not output_path:
+ return
+
+ with open(output_path, "a", encoding="utf-8") as output:
+ output.write("matrix={}\n".format(json.dumps(matrix, separators=(",", ":"))))
+ output.write("target_count={}\n".format(len(matrix)))
+
+
+def main():
+ parser = argparse.ArgumentParser(description="Filter MemBrowse targets by changed files.")
+ parser.add_argument("--targets", required=True, help="Path to membrowse-targets.json.")
+ parser.add_argument("--changed-files", required=True, help="Path to a newline-delimited changed file list.")
+ args = parser.parse_args()
+
+ with open(args.targets, "r", encoding="utf-8") as file:
+ targets = json.load(file)
+
+ changed_files = read_changed_files(args.changed_files)
+ selected_targets = select_targets(targets, changed_files)
+
+ print("Changed files:")
+ for changed_file in changed_files:
+ print(" {}".format(changed_file))
+
+ print("Selected MemBrowse targets:")
+ for target in selected_targets:
+ print(" {}".format(target["target_name"]))
+
+ print("Selected {}/{} MemBrowse targets".format(len(selected_targets), len(targets)))
+ write_github_output(selected_targets, os.getenv("GITHUB_OUTPUT"))
+
+
+if __name__ == "__main__":
+ main()