Skip to content

Commit 918322d

Browse files
ci:Python script for executable logic
- Create python script - Integrate with GitHub Actions Signed-off-by: Shamitha Shashidhara <[email protected]>
1 parent ab0d433 commit 918322d

24 files changed

+445
-401
lines changed

.bash_history

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
python3 .ci/format.py
2+
python3 .ci/format.py
3+
python3 .ci/format.py
4+
clear
5+
python3 .ci/format.py
6+
exit
7+
python3 .ci/build.py "posix" "gcc" "14"
8+
ln --symbolic cmake-build-posix-gcc cmake-build-posix
9+
python3 .ci/pytest.py

.ci/build.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import shutil
2+
from pathlib import Path
3+
import subprocess
4+
import sys
5+
import os
6+
7+
def get_full_command_path(command):
8+
if (cmd := shutil.which(command)) is None:
9+
print(f"ERROR: Compiler command {command} not found!")
10+
sys.exit(1)
11+
return cmd
12+
13+
def get_environment_variables(platform, compiler):
14+
env = dict(os.environ)
15+
if platform == "s32k148" and compiler == "gcc":
16+
env["CC"] = get_full_command_path("arm-none-eabi-gcc")
17+
env["CXX"] = get_full_command_path("arm-none-eabi-gcc")
18+
elif platform == "posix" and compiler == "clang":
19+
env["CC"] = get_full_command_path("clang")
20+
env["CXX"] = get_full_command_path("clang++")
21+
elif platform == "s32k148" and compiler == "clang":
22+
env["CC"] = get_full_command_path("/usr/bin/llvm-arm/bin/clang")
23+
env["CXX"] = get_full_command_path("/usr/bin/llvm-arm/bin/clang++")
24+
elif platform == "posix" and compiler == "gcc":
25+
env["CC"] = get_full_command_path("gcc")
26+
env["CXX"] = get_full_command_path("gcc")
27+
return env
28+
29+
def configure_and_build(platform, compiler, cpp_standard):
30+
build_dir = Path(f"cmake-build-{platform}-{compiler}")
31+
if build_dir.exists():
32+
shutil.rmtree(build_dir)
33+
34+
cmake_command = [
35+
"cmake",
36+
"-B", build_dir,
37+
"-S", "executables/referenceApp",
38+
f"-DCMAKE_CXX_STANDARD={cpp_standard}",
39+
f"-DBUILD_TARGET_PLATFORM={'POSIX' if platform == 'posix' else 'S32K148EVB'}",
40+
f"-DCMAKE_TOOLCHAIN_FILE={'../../admin/cmake/ArmNoneEabi-' + compiler + '.cmake' if platform == 's32k148' else ''}"
41+
]
42+
subprocess.run(cmake_command, check=True, env=get_environment_variables(platform, compiler))
43+
subprocess.run(["cmake", "--build", build_dir, "--target", "app.referenceApp", "-j"], check=True, env=get_environment_variables(platform, compiler))
44+
45+
def main():
46+
if len(sys.argv) != 4:
47+
print("ERROR: Usage: build.py <platform> <compiler> <cpp_standard>")
48+
sys.exit(1)
49+
50+
platform = sys.argv[1]
51+
compiler = sys.argv[2]
52+
cpp_standard = sys.argv[3]
53+
54+
configure_and_build(platform, compiler, cpp_standard)
55+
56+
if __name__ == "__main__":
57+
main()

.ci/build_matrix.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import subprocess
2+
3+
platforms = ["posix", "s32k148"]
4+
compilers = ["clang", "gcc"]
5+
cpp_standards = ["14", "17", "20", "23"]
6+
7+
def main():
8+
for platform in platforms:
9+
for compiler in compilers:
10+
for cpp_standard in cpp_standards:
11+
print(f"Running build for platform={platform}, compiler={compiler}, cpp_standard={cpp_standard}")
12+
subprocess.run(
13+
["python3", ".ci/build.py", platform, compiler, str(cpp_standard)],
14+
check=True
15+
)
16+
print("All combinations have been processed.")
17+
18+
if __name__ == "__main__":
19+
main()

.ci/code_coverage.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import subprocess
2+
from pathlib import Path
3+
import shutil
4+
import sys
5+
import re
6+
7+
def configure_cmake(build_type):
8+
9+
unit_tests_build_dir = Path("cmake-build-unit-tests")
10+
if unit_tests_build_dir.exists():
11+
shutil.rmtree(unit_tests_build_dir)
12+
13+
subprocess.run([
14+
"cmake", "-B", "cmake-build-unit-tests", "-S", "executables/unitTest",
15+
"-DBUILD_UNIT_TESTS=ON",
16+
f"-DCMAKE_BUILD_TYPE={build_type}",
17+
"-DCMAKE_C_COMPILER_LAUNCHER=sccache",
18+
"-DCMAKE_CXX_COMPILER_LAUNCHER=sccache"
19+
], check=True)
20+
21+
def build_with_cmake():
22+
subprocess.run(["cmake", "--build", "cmake-build-unit-tests", "-j4"], check=True)
23+
24+
def run_tests():
25+
subprocess.run(["ctest", "--test-dir", "cmake-build-unit-tests", "-j4"], check=True)
26+
27+
def generate_coverage():
28+
# Capture coverage data
29+
subprocess.run([
30+
"lcov", "--no-external", "--capture", "--directory", ".",
31+
"--output-file", "cmake-build-unit-tests/coverage_unfiltered.info"
32+
], check=True)
33+
34+
# Remove unwanted paths from coverage
35+
subprocess.run([
36+
"lcov", "--remove", "cmake-build-unit-tests/coverage_unfiltered.info",
37+
"*libs/3rdparty/googletest/*", "*/mock/*", "*/gmock/*", "*/gtest/*", "*/test/*",
38+
"--output-file", "cmake-build-unit-tests/coverage.info"
39+
], check=True)
40+
41+
# Generate HTML report
42+
subprocess.run([
43+
"genhtml", "cmake-build-unit-tests/coverage.info",
44+
"--output-directory", "cmake-build-unit-tests/coverage"
45+
], check=True)
46+
47+
def generate_badges():
48+
result = subprocess.run(
49+
["lcov", "--summary", "cmake-build-unit-tests/coverage.info"],
50+
capture_output=True, text=True, check=True
51+
)
52+
summary = result.stdout
53+
54+
line_percentage = re.search(r"lines\.*:\s+(\d+\.\d+)%", summary)
55+
function_percentage = re.search(r"functions\.*:\s+(\d+\.\d+)%", summary)
56+
57+
if line_percentage:
58+
line_value = line_percentage.group(1)
59+
print(f"Line Percentage: {line_value}%")
60+
subprocess.run([
61+
"wget", f"https://img.shields.io/badge/coverage-{line_value}%25-brightgreen.svg",
62+
"-O", "line_coverage_badge.svg"
63+
], check=True)
64+
65+
if function_percentage:
66+
function_value = function_percentage.group(1)
67+
print(f"Function Percentage: {function_value}%")
68+
subprocess.run([
69+
"wget", f"https://img.shields.io/badge/coverage-{function_value}%25-brightgreen.svg",
70+
"-O", "function_coverage_badge.svg"
71+
], check=True)
72+
73+
if __name__ == "__main__":
74+
try:
75+
configure_cmake("Debug")
76+
build_with_cmake()
77+
run_tests()
78+
generate_coverage()
79+
generate_badges()
80+
except subprocess.CalledProcessError as e:
81+
print(f"Command failed with exit code {e.returncode}")
82+
sys.exit(e.returncode)

.ci/doxygen-docs.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import subprocess
2+
import os
3+
import shutil
4+
from pathlib import Path
5+
import sys
6+
7+
def clean_build():
8+
build_dir = Path("doc/doxygenOut")
9+
if build_dir.exists():
10+
shutil.rmtree(build_dir)
11+
file_path_doc_coverage = Path("doc/doc-coverage.info")
12+
if os.path.exists(file_path_doc_coverage):
13+
os.remove(file_path_doc_coverage)
14+
file_path_warning = Path("doc/DoxygenWarningLog.txt")
15+
if os.path.exists(file_path_warning):
16+
os.remove(file_path_warning)
17+
18+
def run_doxygen():
19+
os.chdir("./doc")
20+
subprocess.run(["doxygen", "Doxyfile"], check=True)
21+
22+
def print_doxygen_warning_log():
23+
with open("DoxygenWarningLog.txt", "r") as file:
24+
print(file.read())
25+
26+
def run_coverxygen():
27+
subprocess.run(["python3", "-m", "coverxygen", "--format", "summary", "--xml-dir", "doxygenOut/xml/", "--src-dir", "..", "--output", "doc-coverage.info"], check=True)
28+
29+
def print_doc_coverage():
30+
with open("doc-coverage.info", "r") as file:
31+
print(file.read())
32+
33+
if __name__ == "__main__":
34+
try:
35+
clean_build()
36+
run_doxygen()
37+
print_doxygen_warning_log()
38+
run_coverxygen()
39+
print_doc_coverage()
40+
except subprocess.CalledProcessError as e:
41+
print(f"Command failed with exit code {e.returncode}")
42+
sys.exit(e.returncode)
43+
44+

.ci/format.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import subprocess
2+
import sys
3+
4+
def check_code_format():
5+
subprocess.run(["treefmt", "--no-cache"], check=True)
6+
subprocess.run(["git", "diff", "--exit-code"], check=True)
7+
8+
if __name__ == "__main__":
9+
try:
10+
check_code_format()
11+
except subprocess.CalledProcessError as e:
12+
print(f"Command failed with exit code {e.returncode}")
13+
sys.exit(e.returncode)

.ci/pytest.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import subprocess
2+
import os
3+
import sys
4+
5+
def build_reference_app():
6+
subprocess.run(["cmake", "-B", "cmake-build-posix", "-S", "executables/referenceApp"], check=True)
7+
subprocess.run(["cmake", "--build", "cmake-build-posix", "--target", "app.referenceApp", "-j"], check=True)
8+
9+
def run_pytest():
10+
os.chdir("./test/pyTest")
11+
subprocess.run(['pytest', '--target=posix'], check=True)
12+
13+
if __name__ == "__main__":
14+
try:
15+
build_reference_app()
16+
run_pytest()
17+
except subprocess.CalledProcessError as e:
18+
print(f"Command failed with exit code {e.returncode}")
19+
sys.exit(e.returncode)

.ci/sphinx-docs.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import os
2+
import subprocess
3+
import shutil
4+
from pathlib import Path
5+
import sys
6+
7+
def build_sphinx_docs():
8+
build_dir = Path("doc/build")
9+
if build_dir.exists():
10+
shutil.rmtree(build_dir)
11+
os.chdir("./doc")
12+
subprocess.run(["make", "html", "OFFICIAL_BUILD=1"], check=True)
13+
14+
if __name__ == "__main__":
15+
try:
16+
build_sphinx_docs()
17+
except subprocess.CalledProcessError as e:
18+
print(f"Command failed with exit code {e.returncode}")
19+
sys.exit(e.returncode)

.github/workflows/build.yml

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,35 @@
11
name: Build S32k and posix platform
22

3-
on: [workflow_call, push, pull_request]
3+
on: [workflow_call, pull_request, push]
44

55
jobs:
66
run-command:
77
runs-on: ubuntu-latest
88
strategy:
9-
matrix:
9+
matrix:
1010
platform: [posix, s32k148]
1111
compiler: [clang, gcc]
1212
cpp-standard: [14, 17, 20, 23]
1313

1414
steps:
1515
- name: Checkout repository
1616
uses: actions/checkout@v4
17+
1718
- name: Cache CMake files
1819
id: cache-cmake
19-
uses: actions/cache@v4
20+
uses: actions/cache@v3
2021
with:
2122
path: cmake-build-${{ matrix.platform }}-${{ matrix.compiler }}
2223
key: ${{ runner.os }}-cmake-${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.cpp-standard }}-${{ hashFiles('**/*.cpp', '**/*.h', '**/*.cmake', '**/*.txt', '**/*.c', '**/*.s') }}
2324
restore-keys: |
2425
${{ runner.os }}-cmake-${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.cpp-standard }}-
2526
26-
- name: Set up CMake
27-
uses: jwlawson/actions-setup-cmake@v2
28-
with:
29-
cmake-version: '3.22.x'
30-
31-
- name: Install ARM GCC
32-
if: ${{ matrix.platform == 's32k148' && matrix.compiler == 'gcc' }}
33-
uses: carlosperate/arm-none-eabi-gcc-action@v1
34-
with:
35-
release: '10.3-2021.10'
36-
37-
- name: Install POSIX LLVM
38-
if: ${{ matrix.platform == 'posix' && matrix.compiler == 'clang' }}
39-
uses: KyleMayes/install-llvm-action@v2
40-
with:
41-
version: "17"
42-
env: true
43-
44-
- name: Install ARM LLVM
45-
if: ${{ matrix.platform == 's32k148' && matrix.compiler == 'clang' }}
46-
uses: stellar-aria/[email protected]
47-
with:
48-
release: "19.1.1"
49-
50-
- name: Set environment variables for ARM LLVM
51-
if: ${{ matrix.platform == 's32k148' && matrix.compiler == 'clang' }}
52-
run: |
53-
echo "CC=$(which clang)" >> "${GITHUB_ENV}"
54-
echo "CXX=$(which clang++)" >> "${GITHUB_ENV}"
55-
56-
- name: Configure CMake for ${{ matrix.platform }} with ${{ matrix.compiler }}
27+
- name: Build the docker image
5728
if: steps.cache-cmake.outputs.cache-hit != 'true'
5829
run: |
59-
rm -rf cmake-build-${{ matrix.platform }}-${{ matrix.compiler }}
60-
cmake \
61-
-B cmake-build-${{ matrix.platform }}-${{ matrix.compiler }} \
62-
-S executables/referenceApp \
63-
-DCMAKE_CXX_STANDARD=${{ matrix.cpp-standard }} \
64-
-DBUILD_TARGET_PLATFORM=${{ matrix.platform == 'posix' && 'POSIX' || 'S32K148EVB' }} \
65-
-DCMAKE_TOOLCHAIN_FILE=${{ matrix.platform == 's32k148' && format('../../admin/cmake/ArmNoneEabi-{0}.cmake', matrix.compiler) || '' }}
30+
docker build -f docker/Dockerfile.dev -t dev .
6631
67-
- name: Build ${{ matrix.platform }} with ${{ matrix.compiler }}
32+
- name: Run the build.py inside the docker container
6833
if: steps.cache-cmake.outputs.cache-hit != 'true'
69-
run: cmake --build cmake-build-${{ matrix.platform }}-${{ matrix.compiler }} --target app.referenceApp -j
34+
run: |
35+
docker run --rm -v "$PWD:/home/jenkins" -w /home/jenkins --user $(id -u):4996 dev python3 .ci/build.py "${{ matrix.platform }}" "${{ matrix.compiler }}" "${{ matrix.cpp-standard }}"

0 commit comments

Comments
 (0)