diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index 9d1621cc4d3a9..8570feda09c03 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -60,6 +60,14 @@ jobs: west config manifest.group-filter -- +ci,-optional west update -o=--depth=1 -n 2>&1 1> west.update.log || west update -o=--depth=1 -n 2>&1 1> west.update2.log + - name: Setup Node.js + uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0 + with: + node-version: "20" + + - name: Install dependencies + run: npm i -g dts-linter@0.0.0-beta4 + - name: Run Compliance Tests continue-on-error: true id: compliance diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index d49a86077110a..84f351d26e334 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -480,6 +480,46 @@ def required_false_check(self, binding): "'required: false' is redundant, please remove" ) +class DevicetreeLintingCheck(ComplianceTest): + """ + Checks if we are introducing syntax or formatting issues to devicetree files. + """ + name = "DevicetreeLinting" + doc = "See https://docs.zephyrproject.org/latest/contribute/style/devicetree.html for more details." + + def run(self): + # Check if node is installed + if not shutil.which("node"): + self.skip("Node.js is not installed or not in PATH") + + # Check if dts-linter is installed + if not shutil.which("dts-linter"): + self.skip("dts-linter is not installed or not in PATH") + + # Get changed DTS files + dts_files = [] + for file in get_files(filter="d"): + if file.endswith((".dts", ".dtsi", ".overlay")): + dts_files.append(file) + + if not dts_files: + self.skip('No DTS') + return # No DTS files to check + + # Build command: dts-linter --outFile diff --format --files file1 --files file2 ... + cmd = ["dts-linter", "--format", "--diagnostics"] + for file in dts_files: + cmd.extend(["--files", file]) + + try: + result = subprocess.run(cmd, check=True, capture_output=True, cwd=GIT_TOP) + except subprocess.CalledProcessError as ex: + output = ex.output.decode("utf-8") + if output.strip(): + self.failure(f"dts-linter found issues:\n{output}") + else: + self.failure("dts-linter failed with no output") + class KconfigCheck(ComplianceTest): """ Checks is we are introducing any new warnings/errors with Kconfig,