Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3231950
Initial plan
Copilot Nov 23, 2025
fd602b9
Add GitHub Actions CI workflow with clang-format, clang-tidy, and bui…
Copilot Nov 23, 2025
650762a
Address code review feedback: include .cc files and improve dependenc…
Copilot Nov 23, 2025
85ed613
Add explicit GITHUB_TOKEN permissions for security best practices
Copilot Nov 23, 2025
9e147bf
Update build CI to use GCC-14 and LLVM-19 with C++23 support and libc++
Copilot Nov 23, 2025
d19bf14
Replace deprecated apt-key with modern gpg key management
Copilot Nov 23, 2025
a45ddd4
Fix clang-format errors and add llvm-config for LLVM-19 builds
Copilot Nov 23, 2025
5725665
Add CodeQL security analysis job to CI workflow
Copilot Nov 23, 2025
17e0e19
Merge remote-tracking branch 'origin/main' into copilot/add-github-ac…
Copilot Nov 23, 2025
f85ac0f
Merge main branch and fix clang-format errors in utils files
Copilot Nov 23, 2025
dac414c
Fix clang-tidy CI job by adding LLVM package for llvm-config
Copilot Nov 23, 2025
a3934db
Fix LLVM-19 build by adding lld-19 linker package
Copilot Nov 23, 2025
11877f0
Change spdlog to INTERFACE library with custom configuration
Copilot Nov 23, 2025
b941c07
Add spdlog::spdlog alias to fix target linking errors
Copilot Nov 23, 2025
806503b
Exclude third_party headers from clang-tidy analysis
Copilot Nov 23, 2025
a5ef8af
Disable C++ modules in clang-tidy to fix analysis errors
Copilot Nov 23, 2025
acd9f69
Use C++20 standard for clang-tidy to avoid C++23 module issues
Copilot Nov 23, 2025
a3ea660
Use GCC-14 for clang-tidy to fix include path issues
Copilot Nov 23, 2025
258ffeb
Add --system-headers=false to completely exclude third_party from cla…
Copilot Nov 23, 2025
64aae62
Remove CMAKE_CXX_STANDARD overrides from CI jobs
Copilot Nov 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
243 changes: 243 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
---
name: CI

on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
workflow_dispatch:

permissions:
contents: read

jobs:
codeql:
name: CodeQL Security Analysis
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
actions: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive

- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: cpp
queries: security-and-quality

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
cmake \
ninja-build \
libudev-dev \
libsystemd-dev \
pkg-config \
gcc-14 \
g++-14

- name: Build for CodeQL
run: |
mkdir -p build
cd build
cmake .. -GNinja \
-DCMAKE_BUILD_TYPE=Release
ninja
env:
CC: gcc-14
CXX: g++-14

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:cpp"

clang-format:
name: Code Formatting Check
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install clang-format
run: |
sudo apt-get update
sudo apt-get install -y clang-format

- name: Run clang-format check
run: |
# Find all C++ source files and check formatting
find src -type f \( -name "*.cpp" -o -name "*.cc" \
-o -name "*.h" -o -name "*.hpp" \) -print0 | \
xargs -0 clang-format --dry-run --Werror
shell: bash

clang-tidy:
name: Static Analysis (clang-tidy)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
clang-tidy \
gcc-14 \
g++-14 \
cmake \
ninja-build \
libudev-dev \
libsystemd-dev \
pkg-config

- name: Cache clang-tidy results
uses: actions/cache@v4
with:
path: .clang-tidy-cache
key: >-
clang-tidy-${{ runner.os }}-${{
hashFiles('**/*.cpp', '**/*.cc', '**/*.h', '**/*.hpp',
'.clang-tidy') }}
restore-keys: |
clang-tidy-${{ runner.os }}-

- name: Configure CMake for clang-tidy
run: |
mkdir -p build
cd build
cmake .. -GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
env:
CC: gcc-14
CXX: g++-14

- name: Run clang-tidy
run: |
# Create cache directory if it doesn't exist
mkdir -p .clang-tidy-cache

# Find all C++ source files and run clang-tidy
# Exclude third_party directory from analysis
find src -type f \( -name "*.cpp" -o -name "*.cc" \) | \
while read file; do
echo "Analyzing $file..."
clang-tidy "$file" \
-p build \
--warnings-as-errors='*' \
--header-filter='^(?!.*third_party).*$' \
--system-headers=false || exit 1
done
shell: bash

build:
name: Build and Publish Artifacts
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
matrix:
compiler:
- {cc: gcc-14, cxx: g++-14, name: gcc-14, stdlib: libstdc++}
- {cc: clang-19, cxx: clang++-19, name: llvm-19, stdlib: libc++}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
submodules: recursive

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
cmake \
ninja-build \
libudev-dev \
libsystemd-dev \
pkg-config

- name: Install compiler toolchain
run: |
if [ "${{ matrix.compiler.name }}" = "gcc-14" ]; then
sudo apt-get install -y gcc-14 g++-14
elif [ "${{ matrix.compiler.name }}" = "llvm-19" ]; then
# Install LLVM 19 with libc++
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | \
sudo tee /etc/apt/trusted.gpg.d/llvm.asc
sudo add-apt-repository -y \
'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main'
sudo apt-get update
sudo apt-get install -y \
clang-19 \
llvm-19 \
llvm-19-dev \
lld-19 \
libc++-19-dev \
libc++abi-19-dev
fi

- name: Configure CMake
run: |
mkdir -p build
cd build
# Configure with C++23 support
if [ "${{ matrix.compiler.stdlib }}" = "libc++" ]; then
# For LLVM with libc++
cmake .. -GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_LTO=ON \
-DCMAKE_CXX_FLAGS="-stdlib=libc++" \
-DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++ -lc++abi" \
-DLLVM_CONFIG=/usr/bin/llvm-config-19
else
# For GCC with libstdc++
cmake .. -GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_LTO=ON
fi
env:
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}

- name: Build
run: |
cd build
ninja -v

- name: Collect executables
run: |
mkdir -p artifacts
# Find all executables in src directories
# (exclude CMake test artifacts and temporary files)
find build/src -type f -executable \
-not -path "*/CMakeFiles/*" \
-not -name "*.so*" \
-not -name "*.a" \
-exec cp {} artifacts/ \;

# List what we collected
echo "Collected artifacts:"
ls -lh artifacts/

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: binaries-${{ matrix.compiler.name }}
path: artifacts/*
if-no-files-found: error
retention-days: 30
103 changes: 51 additions & 52 deletions src/proxy/org/freedesktop/ModemManager1/ModemManager1_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,58 @@
namespace org {
namespace freedesktop {

class ModemManager1_proxy
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.ModemManager1";

protected:
ModemManager1_proxy(sdbus::IProxy& proxy)
: m_proxy(proxy)
{
}

ModemManager1_proxy(const ModemManager1_proxy&) = delete;
ModemManager1_proxy& operator=(const ModemManager1_proxy&) = delete;
ModemManager1_proxy(ModemManager1_proxy&&) = delete;
ModemManager1_proxy& operator=(ModemManager1_proxy&&) = delete;

~ModemManager1_proxy() = default;

void registerProxy()
{
}

public:
void ScanDevices()
{
m_proxy.callMethod("ScanDevices").onInterface(INTERFACE_NAME);
}

void SetLogging(const std::string& level)
{
m_proxy.callMethod("SetLogging").onInterface(INTERFACE_NAME).withArguments(level);
}

void ReportKernelEvent(const std::map<std::string, sdbus::Variant>& properties)
{
m_proxy.callMethod("ReportKernelEvent").onInterface(INTERFACE_NAME).withArguments(properties);
}

void InhibitDevice(const std::string& uid, const bool& inhibit)
{
m_proxy.callMethod("InhibitDevice").onInterface(INTERFACE_NAME).withArguments(uid, inhibit);
}

public:
std::string Version()
{
return m_proxy.getProperty("Version").onInterface(INTERFACE_NAME).get<std::string>();
}

private:
sdbus::IProxy& m_proxy;
class ModemManager1_proxy {
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.ModemManager1";

protected:
ModemManager1_proxy(sdbus::IProxy& proxy) : m_proxy(proxy) {}

ModemManager1_proxy(const ModemManager1_proxy&) = delete;
ModemManager1_proxy& operator=(const ModemManager1_proxy&) = delete;
ModemManager1_proxy(ModemManager1_proxy&&) = delete;
ModemManager1_proxy& operator=(ModemManager1_proxy&&) = delete;

~ModemManager1_proxy() = default;

void registerProxy() {}

public:
void ScanDevices() {
m_proxy.callMethod("ScanDevices").onInterface(INTERFACE_NAME);
}

void SetLogging(const std::string& level) {
m_proxy.callMethod("SetLogging")
.onInterface(INTERFACE_NAME)
.withArguments(level);
}

void ReportKernelEvent(
const std::map<std::string, sdbus::Variant>& properties) {
m_proxy.callMethod("ReportKernelEvent")
.onInterface(INTERFACE_NAME)
.withArguments(properties);
}

void InhibitDevice(const std::string& uid, const bool& inhibit) {
m_proxy.callMethod("InhibitDevice")
.onInterface(INTERFACE_NAME)
.withArguments(uid, inhibit);
}

public:
std::string Version() {
return m_proxy.getProperty("Version")
.onInterface(INTERFACE_NAME)
.get<std::string>();
}

private:
sdbus::IProxy& m_proxy;
};

}} // namespaces
} // namespace freedesktop
} // namespace org

#endif
14 changes: 6 additions & 8 deletions src/utils/utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -476,10 +476,9 @@ std::string Utils::scalarToString(const glz::generic& val) {
double d = val.get<double>();
// Check if the number is an integer to preserve precision
// Only convert to int64 if it's within a safe range
constexpr double kMaxSafeInt64 = 9007199254740992.0; // 2^53
constexpr double kMinSafeInt64 = -9007199254740992.0; // -2^53
if (d >= kMinSafeInt64 && d <= kMaxSafeInt64 &&
d == std::floor(d)) {
constexpr double kMaxSafeInt64 = 9007199254740992.0; // 2^53
constexpr double kMinSafeInt64 = -9007199254740992.0; // -2^53
if (d >= kMinSafeInt64 && d <= kMaxSafeInt64 && d == std::floor(d)) {
return std::to_string(static_cast<int64_t>(d));
}
return std::to_string(d);
Expand All @@ -490,8 +489,7 @@ std::string Utils::scalarToString(const glz::generic& val) {
}

// NOLINTNEXTLINE(clang-tidy)
std::string Utils::elementToLines(const glz::generic& el,
const int indent) {
std::string Utils::elementToLines(const glz::generic& el, const int indent) {
std::string out;
const std::string pad(indent * 2, ' ');

Expand Down Expand Up @@ -532,12 +530,12 @@ std::string Utils::parseDescriptionJson(const std::string& json) {
if (json.empty()) {
return "<empty>";
}

glz::generic doc;
auto ec = glz::read_json(doc, json);
if (ec) {
return std::string("json_error: ") + glz::format_error(ec, json);
}

return elementToLines(doc, 0);
}
Loading
Loading