Skip to content

Commit bfaded7

Browse files
ci: add support for running out of tree compliance checks
Add support for running compliance checks on code contributed to the example repository, as a demonstration for how to implement custom compliance checks on top of those Zephyr provides Signed-off-by: Daniel DeGrasse <daniel.degrasse@analog.com>
1 parent 03d5bd6 commit bfaded7

2 files changed

Lines changed: 159 additions & 0 deletions

File tree

.github/workflows/compliance.yml

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
name: Compliance Checks
2+
3+
on: pull_request
4+
5+
permissions:
6+
contents: read
7+
8+
jobs:
9+
check_compliance:
10+
runs-on: ubuntu-24.04
11+
name: Run compliance checks on patch series (PR)
12+
steps:
13+
- name: Set up Python
14+
uses: actions/setup-python@v5
15+
with:
16+
python-version: 3.12
17+
18+
- name: Checkout the code
19+
uses: actions/checkout@v4
20+
with:
21+
ref: ${{ github.event.pull_request.head.sha }}
22+
path: example-application
23+
fetch-depth: 0
24+
25+
- name: Rebase onto the target branch
26+
working-directory: example-application
27+
env:
28+
BASE_REF: ${{ github.base_ref }}
29+
run: |
30+
git config --global user.email "you@example.com"
31+
git config --global user.name "Your Name"
32+
git config --global --add safe.directory $PWD
33+
git remote -v
34+
# Ensure there's no merge commits in the PR
35+
[[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \
36+
(echo "::error ::Merge commits not allowed, rebase instead";false)
37+
rm -fr ".git/rebase-apply"
38+
rm -fr ".git/rebase-merge"
39+
git rebase origin/${BASE_REF}
40+
git clean -f -d
41+
# debug
42+
git log --pretty=oneline | head -n 10
43+
44+
- name: Install west
45+
shell: bash
46+
run: |
47+
if ! command -v west &> /dev/null; then
48+
echo "west could not be found, installing..."
49+
python -m pip install west==1.5.0
50+
fi
51+
52+
- name: Initialize west workspace
53+
shell: bash
54+
run: |
55+
west init -l example-application
56+
57+
- name: Update west workspace
58+
shell: bash
59+
run: |
60+
west update -o=--depth=1 -n
61+
62+
- name: Install Python dependencies
63+
shell: bash
64+
run: |
65+
pip install -r zephyr/scripts/requirements-compliance.txt
66+
67+
- name: Run Compliance Tests
68+
continue-on-error: true
69+
id: compliance
70+
working-directory: example-application
71+
env:
72+
BASE_REF: ${{ github.base_ref }}
73+
UNDEF_KCONFIG_OUTSIDE_ALLOWLIST_FILE:
74+
${{ github.workspace }}/example-application/scripts/undef_kconfig_allowlist.txt
75+
run: |
76+
export ZEPHYR_BASE=$PWD/../zephyr
77+
# debug
78+
ls -la
79+
git log --pretty=oneline | head -n 10
80+
./scripts/repo_compliance.py --annotate -e SysbuildKconfig \
81+
-c origin/${BASE_REF}..
82+
83+
- name: upload-results
84+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
85+
continue-on-error: true
86+
with:
87+
name: example-application/compliance.xml
88+
path: example-application/compliance.xml
89+
90+
- name: check-warns
91+
shell: bash
92+
working-directory: example-application
93+
run: |
94+
if [[ ! -s "compliance.xml" ]]; then
95+
exit 1;
96+
fi
97+
98+
warns=("ClangFormat" "LicenseAndCopyrightCheck")
99+
files=($(./scripts/repo_compliance.py -l))
100+
101+
for file in "${files[@]}"; do
102+
f="${file}.txt"
103+
if [[ -s $f ]]; then
104+
results=$(cat $f)
105+
results="${results//'%'/'%25'}"
106+
results="${results//$'\n'/'%0A'}"
107+
results="${results//$'\r'/'%0D'}"
108+
if [[ "${warns[@]}" =~ "${file}" ]]; then
109+
echo "::warning file=${f}::$results"
110+
else
111+
echo "::error file=${f}::$results"
112+
exit=1
113+
fi
114+
fi
115+
done
116+
117+
if [ "${exit}" == "1" ]; then
118+
exit 1;
119+
fi

scripts/repo_compliance.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/env python3
2+
# Copyright (c) 2026 Analog Devices, Inc.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
# This script runs compliance checks on the repository for coding standards.
6+
# It imports logic from Zephyr's own check_compliance.py script, but overrides
7+
# checks that are specific to Zephyr's own repository structure
8+
9+
import os
10+
import sys
11+
from pathlib import Path
12+
13+
ZEPHYR_BASE = os.environ.get("ZEPHYR_BASE", str(Path(__file__).resolve().parents[2] / "zephyr"))
14+
sys.path.insert(0, str(Path(ZEPHYR_BASE) / "scripts" / "ci"))
15+
16+
import check_compliance # noqa: E402
17+
18+
19+
class SampleCheck(check_compliance.ComplianceTest):
20+
"""
21+
Example of a custom compliance check that can be added to the CI checks run in this repo.
22+
This check simply passes when run, unless a file in the root of the repo
23+
called "fail.txt" exists. If present, the check will fail and print a message to the console.
24+
"""
25+
26+
name = "SampleCheck"
27+
doc = "Sample check that fails if fail.txt exists in the root of the repo"
28+
29+
def run(self):
30+
"""
31+
Run the sample check.
32+
"""
33+
fail_file = Path(check_compliance.GIT_TOP) / "fail.txt"
34+
if fail_file.exists():
35+
self.failure("SampleCheck failed because fail.txt exists in the root of the repo.")
36+
return False
37+
38+
39+
# Run compliance checks using Zephyr's check_compliance.py script
40+
check_compliance.main(sys.argv[1:])

0 commit comments

Comments
 (0)