From 2906a4a93ba515633924483e55462d9cde2efad5 Mon Sep 17 00:00:00 2001 From: VPRamon Date: Fri, 8 May 2026 19:05:14 +0200 Subject: [PATCH 1/5] feat(ci): add CPack configuration for packaging DEB and RPM files docs: update README with deployment instructions for package installation --- .github/workflows/ci.yml | 126 ++++++++++++++++++++++++++++++++++++++- CMakeLists.txt | 33 ++++++++++ README.md | 54 +++++++++++++++++ 3 files changed, 212 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d38998f..01fe376 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ concurrency: cancel-in-progress: true permissions: - contents: read + contents: write checks: write pull-requests: write @@ -268,3 +268,127 @@ jobs: - name: Publish to Job Summary shell: bash run: cat code-coverage-results.md >> "$GITHUB_STEP_SUMMARY" + + # --------------------------------------------------------------------------- + # Package: build .deb and .rpm via CPack + # --------------------------------------------------------------------------- + package: + name: Package (DEB + RPM) + needs: build-test-docs + runs-on: ubuntu-22.04 + env: + CARGO_TERM_COLOR: always + CMAKE_BUILD_PARALLEL_LEVEL: 2 + steps: + - name: Checkout (with submodules) + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Install system dependencies + shell: bash + run: | + set -euo pipefail + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + ninja-build \ + pkg-config \ + libssl-dev \ + rpm + + - name: Set up Rust (stable) + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Cache cargo + build artifacts + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + qtty/target + qtty/qtty-ffi/target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Configure (CMake, Release) + shell: bash + run: | + set -euo pipefail + cmake -S . -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DQTTY_BUILD_DOCS=OFF + + - name: Build + shell: bash + run: cmake --build build --target test_ffi + + - name: Install to staging prefix + shell: bash + run: cmake --install build --prefix build/staging + + - name: Copy shared libraries to staging + shell: bash + run: | + set -euo pipefail + mkdir -p build/staging/lib + cp qtty/target/release/libqtty_ffi.so \ + build/staging/lib/ || true + + - name: Generate packages (CPack) + shell: bash + run: | + set -euo pipefail + cd build + cpack --config CPackConfig.cmake -G "DEB;RPM" -B packages + ls -lh packages/ + + - name: Upload DEB package + uses: actions/upload-artifact@v4 + with: + name: qtty-cpp-deb + path: build/packages/*.deb + retention-days: 30 + + - name: Upload RPM package + uses: actions/upload-artifact@v4 + with: + name: qtty-cpp-rpm + path: build/packages/*.rpm + retention-days: 30 + + # --------------------------------------------------------------------------- + # Release: create GitHub Release and attach packages (tag pushes only) + # --------------------------------------------------------------------------- + release: + name: GitHub Release + needs: package + if: startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-22.04 + permissions: + contents: write + steps: + - name: Download DEB artifact + uses: actions/download-artifact@v4 + with: + name: qtty-cpp-deb + path: dist/ + + - name: Download RPM artifact + uses: actions/download-artifact@v4 + with: + name: qtty-cpp-rpm + path: dist/ + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: dist/* + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b91a05..6f0fe56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -308,6 +308,39 @@ install(EXPORT qtty_cppTargets DESTINATION lib/cmake/qtty_cpp ) +# --------------------------------------------------------------------------- +# Packaging (CPack — DEB and RPM) +# --------------------------------------------------------------------------- +set(CPACK_PACKAGE_NAME "qtty-cpp") +set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") +set(CPACK_PACKAGE_VENDOR "Siderust") +set(CPACK_PACKAGE_CONTACT "VPRamon ") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "C++ wrapper for the qtty unit-safe physical quantities library") +set(CPACK_PACKAGE_DESCRIPTION + "qtty-cpp provides a header-only C++17 API over the qtty Rust\n" + "quantities library via the qtty-ffi C ABI. It bundles the pre-built\n" + "shared library (qtty_ffi) together with the C++ headers and CMake\n" + "package config.") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/Siderust/qtty-cpp") + +# -- DEB ----------------------------------------------------------------------- +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "VPRamon ") +set(CPACK_DEBIAN_PACKAGE_SECTION "libs") +set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17), libstdc++6 (>= 9)") +set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + +# -- RPM ----------------------------------------------------------------------- +set(CPACK_RPM_PACKAGE_LICENSE "AGPL-3.0") +set(CPACK_RPM_PACKAGE_GROUP "Development/Libraries") +set(CPACK_RPM_PACKAGE_REQUIRES "glibc >= 2.17, libstdc++ >= 9") +set(CPACK_RPM_FILE_NAME RPM-DEFAULT) + +set(CPACK_GENERATOR "DEB;RPM") + +include(CPack) + # Generate unit files (if needed) add_custom_target( gen_units diff --git a/README.md b/README.md index 95d1d23..ca6feb2 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,60 @@ find_package(qtty_cpp REQUIRED) target_link_libraries(your_target PRIVATE qtty::qtty_cpp) ``` +## Deployment + +Packages for Debian/Ubuntu (`.deb`) and RHEL/Fedora/openSUSE (`.rpm`) are built +with CPack. + +### Prerequisites + +```bash +# Debian/Ubuntu +sudo apt-get install cmake ninja-build rpm + +# RHEL/Fedora +sudo dnf install cmake ninja-build dpkg +``` + +### Build the packages + +```bash +git clone --recurse-submodules +cd qtty-cpp + +cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DQTTY_BUILD_DOCS=OFF +cmake --build build --parallel + +# Install headers + cmake config to a staging prefix +cmake --install build --prefix build/staging + +# Generate .deb and .rpm in build/packages/ +cd build +cpack --config CPackConfig.cmake -G "DEB;RPM" -B packages +ls packages/ +``` + +### Install on the target system + +```bash +# Debian/Ubuntu +sudo dpkg -i packages/qtty-cpp-*.deb + +# RHEL/Fedora/openSUSE +sudo rpm -i packages/qtty-cpp-*.rpm +``` + +After installation, headers land in `/usr/local/include/qtty/` and the +shared library in `/usr/local/lib/`. CMake consumers can then use: + +```cmake +find_package(qtty_cpp REQUIRED) +target_link_libraries(your_target PRIVATE qtty::qtty_cpp) +``` + +> **Note:** Pre-built `.deb` and `.rpm` packages are also automatically attached +> to every [GitHub Release](https://github.com/Siderust/qtty-cpp/releases). + ## License This repository wraps the upstream `qtty` project (git submodule in `qtty/`). See `qtty/LICENSE` for licensing details. From e9d280dbe1fbc3ff33c630057fa80ee4caa7160c Mon Sep 17 00:00:00 2001 From: VPRamon Date: Fri, 8 May 2026 21:50:48 +0200 Subject: [PATCH 2/5] feat: add dimensionless units and corresponding tests --- CHANGELOG.md | 30 +++++++++++++++++ CMakeLists.txt | 1 + gen_cpp_units/src/main.rs | 3 ++ include/qtty/literals.hpp | 1 + include/qtty/qtty.hpp | 1 + include/qtty/units/dimensionless.hpp | 49 ++++++++++++++++++++++++++++ qtty | 2 +- tests/test_extended_inventory.cpp | 28 ++++++++++++++++ 8 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 include/qtty/units/dimensionless.hpp diff --git a/CHANGELOG.md b/CHANGELOG.md index f14c278..79b7aaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,36 @@ All notable changes to `qtty-cpp` are documented in this file. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.4.1] - 2026-05-08 + +### Added +- Expose named dimensionless units in the C++ wrapper: `OpticalDepth`, + `Airmass`, `Transmittance`, `Albedo`, `IlluminationFraction`, and + `Refractivity`. A generated header `include/qtty/units/dimensionless.hpp` + provides tag types and type aliases for these units and `include/qtty/qtty.hpp` + includes the new header so the units are available with a single include. +- Add FFI discriminants and identifiers for the new dimensionless units and + dimension: `DIMENSION_ID_DIMENSIONLESS = 33` and + `UNIT_ID_OPTICAL_DEPTH = 330000` … `UNIT_ID_REFRACTIVITY = 330005` in the + generated `qtty_ffi.h` so the units are available across the C ABI. + +### Changed +- `gen_cpp_units` generator: include `Dimensionless` in the `DIMENSIONS` + constant and map discriminant code `33` to the `Dimensionless` group so + `dimensionless.hpp` is generated automatically from `discriminants.csv`. + `literals.hpp` was regenerated (no user-defined literals for these units as + they have empty symbols). +- `CMakeLists.txt` and the generator invocation updated to include the new + generated `dimensionless.hpp` so it is installed and packaged like other + generated headers. +- Tests: added `DimensionlessUnits` coverage in + `tests/test_extended_inventory.cpp` to verify construction and cross-unit + conversions for the new named dimensionless units. + +### Notes +- The generator output and ABI remain backward compatible: new discriminant + values were appended and existing values were not changed. + ## [0.4.0] - 2026-05-04 ### Added diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b91a05..4a4180b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,7 @@ set(GENERATED_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/qtty/units/magnetic_flux.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/qtty/units/magnetic_flux_density.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/qtty/units/density.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/include/qtty/units/dimensionless.hpp ${CMAKE_CURRENT_SOURCE_DIR}/include/qtty/literals.hpp ) diff --git a/gen_cpp_units/src/main.rs b/gen_cpp_units/src/main.rs index a95510d..75595e9 100644 --- a/gen_cpp_units/src/main.rs +++ b/gen_cpp_units/src/main.rs @@ -67,6 +67,7 @@ const DIMENSIONS: &[(&str, &str, u32)] = &[ ("MagneticFlux", "magnetic_flux.hpp", 30), ("MagneticFluxDensity", "magnetic_flux_density.hpp", 31), ("Density", "density.hpp", 32), + ("Dimensionless", "dimensionless.hpp", 33), ]; // --------------------------------------------------------------------------- @@ -216,6 +217,7 @@ fn parse_csv(path: &Path) -> Vec { 30 => "MagneticFlux", 31 => "MagneticFluxDensity", 32 => "Density", + 33 => "Dimensionless", _ => { eprintln!( "Warning: unknown dimension code {dim_code} for discriminant {discriminant}" @@ -381,6 +383,7 @@ fn generate_literals(by_dim: &HashMap<&str, Vec<&UnitDef>>, _order: &[&str]) -> writeln!(s, "#include \"units/magnetic_flux.hpp\"").unwrap(); writeln!(s, "#include \"units/magnetic_flux_density.hpp\"").unwrap(); writeln!(s, "#include \"units/density.hpp\"").unwrap(); + writeln!(s, "#include \"units/dimensionless.hpp\"").unwrap(); writeln!(s).unwrap(); writeln!(s, "namespace qtty {{").unwrap(); writeln!(s).unwrap(); diff --git a/include/qtty/literals.hpp b/include/qtty/literals.hpp index 41a7b71..c0cc9df 100644 --- a/include/qtty/literals.hpp +++ b/include/qtty/literals.hpp @@ -35,6 +35,7 @@ #include "units/magnetic_flux.hpp" #include "units/magnetic_flux_density.hpp" #include "units/density.hpp" +#include "units/dimensionless.hpp" namespace qtty { diff --git a/include/qtty/qtty.hpp b/include/qtty/qtty.hpp index 75d5edf..6ee397c 100644 --- a/include/qtty/qtty.hpp +++ b/include/qtty/qtty.hpp @@ -53,6 +53,7 @@ #include "units/charge.hpp" #include "units/current.hpp" #include "units/density.hpp" +#include "units/dimensionless.hpp" #include "units/energy.hpp" #include "units/force.hpp" #include "units/frequency.hpp" diff --git a/include/qtty/units/dimensionless.hpp b/include/qtty/units/dimensionless.hpp new file mode 100644 index 0000000..7d23c5b --- /dev/null +++ b/include/qtty/units/dimensionless.hpp @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (C) 2026 Vallés Puig, Ramon + +#pragma once + +#include "../ffi_core.hpp" + +namespace qtty { + +struct OpticalDepthTag {}; +struct AirmassTag {}; +struct TransmittanceTag {}; +struct AlbedoTag {}; +struct IlluminationFractionTag {}; +struct RefractivityTag {}; + +template <> struct UnitTraits { + static constexpr UnitId unit_id() { return UNIT_ID_OPTICAL_DEPTH; } + static constexpr std::string_view symbol() { return ""; } +}; +template <> struct UnitTraits { + static constexpr UnitId unit_id() { return UNIT_ID_AIRMASS; } + static constexpr std::string_view symbol() { return ""; } +}; +template <> struct UnitTraits { + static constexpr UnitId unit_id() { return UNIT_ID_TRANSMITTANCE; } + static constexpr std::string_view symbol() { return ""; } +}; +template <> struct UnitTraits { + static constexpr UnitId unit_id() { return UNIT_ID_ALBEDO; } + static constexpr std::string_view symbol() { return ""; } +}; +template <> struct UnitTraits { + static constexpr UnitId unit_id() { return UNIT_ID_ILLUMINATION_FRACTION; } + static constexpr std::string_view symbol() { return ""; } +}; +template <> struct UnitTraits { + static constexpr UnitId unit_id() { return UNIT_ID_REFRACTIVITY; } + static constexpr std::string_view symbol() { return ""; } +}; + +using OpticalDepth = Quantity; +using Airmass = Quantity; +using Transmittance = Quantity; +using Albedo = Quantity; +using IlluminationFraction = Quantity; +using Refractivity = Quantity; + +} // namespace qtty diff --git a/qtty b/qtty index abb94d0..ee52adb 160000 --- a/qtty +++ b/qtty @@ -1 +1 @@ -Subproject commit abb94d077767cb964e5f79dd995eef4c4cf9abcf +Subproject commit ee52adbb9f4e1e3ee470eab83541708a09f794bf diff --git a/tests/test_extended_inventory.cpp b/tests/test_extended_inventory.cpp index 104ab42..058ff6c 100644 --- a/tests/test_extended_inventory.cpp +++ b/tests/test_extended_inventory.cpp @@ -46,3 +46,31 @@ TEST_F(QttyTest, RadiometryAndPhotometryConversions) { Lux lx = Millilux(1000.0).to(); EXPECT_NEAR(lx.value(), 1.0, 1e-12); } + +TEST_F(QttyTest, DimensionlessUnits) { + // All dimensionless units have ratio 1.0, so conversion is identity. + OpticalDepth tau(0.5); + EXPECT_NEAR(tau.value(), 0.5, 1e-15); + + Airmass X(1.2); + EXPECT_NEAR(X.value(), 1.2, 1e-15); + + Transmittance T(0.8); + EXPECT_NEAR(T.value(), 0.8, 1e-15); + + Albedo A(0.3); + EXPECT_NEAR(A.value(), 0.3, 1e-15); + + IlluminationFraction k(0.75); + EXPECT_NEAR(k.value(), 0.75, 1e-15); + + Refractivity n(2.7e-4); + EXPECT_NEAR(n.value(), 2.7e-4, 1e-18); + + // Conversion between dimensionless units is identity (same dimension, ratio 1). + Airmass from_tau = tau.to(); + EXPECT_NEAR(from_tau.value(), 0.5, 1e-15); + + Transmittance from_albedo = A.to(); + EXPECT_NEAR(from_albedo.value(), 0.3, 1e-15); +} From 794cc56c71a773c1a5db4fef06dc105768b866d5 Mon Sep 17 00:00:00 2001 From: VPRamon Date: Fri, 8 May 2026 22:26:13 +0200 Subject: [PATCH 3/5] feat: add CI workflows for linting, testing, coverage, packaging, and release --- .github/workflows/ci-build-test-docs.yml | 99 ++++++ .github/workflows/ci-coverage.yml | 96 ++++++ .github/workflows/ci-lint.yml | 73 +++++ .github/workflows/ci-package.yml | 94 ++++++ .github/workflows/ci-release.yml | 79 +++++ .github/workflows/ci.yml | 371 +---------------------- 6 files changed, 447 insertions(+), 365 deletions(-) create mode 100644 .github/workflows/ci-build-test-docs.yml create mode 100644 .github/workflows/ci-coverage.yml create mode 100644 .github/workflows/ci-lint.yml create mode 100644 .github/workflows/ci-package.yml create mode 100644 .github/workflows/ci-release.yml diff --git a/.github/workflows/ci-build-test-docs.yml b/.github/workflows/ci-build-test-docs.yml new file mode 100644 index 0000000..4698580 --- /dev/null +++ b/.github/workflows/ci-build-test-docs.yml @@ -0,0 +1,99 @@ +name: CI Build Test Docs + +on: + workflow_call: + +jobs: + build-test-docs: + name: Build + Test + Docs + runs-on: ubuntu-22.04 + env: + CARGO_TERM_COLOR: always + CMAKE_BUILD_PARALLEL_LEVEL: 2 + steps: + - name: Checkout (with submodules) + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Show selected dependency revisions + shell: bash + run: | + set -euo pipefail + git submodule status --recursive + echo + echo "qtty: $(git -C qtty rev-parse HEAD) ($(git -C qtty describe --tags --always 2>/dev/null || true))" + echo "qtty-ffi: $(git -C qtty/qtty-ffi rev-parse HEAD) ($(git -C qtty/qtty-ffi describe --tags --always 2>/dev/null || true))" + + - name: Install system dependencies + shell: bash + run: | + set -euo pipefail + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + ninja-build \ + pkg-config \ + libssl-dev \ + graphviz + + - name: Install Doxygen 1.16.1 + shell: bash + run: | + set -euo pipefail + DOXYGEN_VERSION="1.16.1" + curl -fsSL "https://github.com/doxygen/doxygen/releases/download/Release_1_16_1/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz" -o /tmp/doxygen.tar.gz + sudo tar -xzf /tmp/doxygen.tar.gz -C /opt + sudo ln -sf "/opt/doxygen-${DOXYGEN_VERSION}/bin/doxygen" /usr/local/bin/doxygen + rm -f /tmp/doxygen.tar.gz + doxygen --version + + - name: Set up Rust (stable) + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Cache cargo + build artifacts + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + qtty/target + qtty/qtty-ffi/target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Validate required submodules exist + shell: bash + run: | + set -euo pipefail + test -f qtty/Cargo.toml + test -f qtty/qtty-ffi/Cargo.toml + + - name: Configure (CMake) + shell: bash + run: | + set -euo pipefail + cmake -S . -B build -G Ninja -DQTTY_BUILD_DOCS=ON + + - name: Build + shell: bash + run: | + set -euo pipefail + cmake --build build --target test_ffi + + - name: Test (ctest) + shell: bash + run: | + set -euo pipefail + ctest --test-dir build --output-on-failure -L qtty_cpp + + - name: Build docs (Doxygen) + shell: bash + run: | + set -euo pipefail + cmake --build build --target docs diff --git a/.github/workflows/ci-coverage.yml b/.github/workflows/ci-coverage.yml new file mode 100644 index 0000000..771349e --- /dev/null +++ b/.github/workflows/ci-coverage.yml @@ -0,0 +1,96 @@ +name: CI Coverage + +on: + workflow_call: + +jobs: + coverage: + name: Test & Coverage + runs-on: ubuntu-22.04 + env: + CARGO_TERM_COLOR: always + steps: + - name: Checkout (with submodules) + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Install system dependencies + shell: bash + run: | + set -euo pipefail + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + ninja-build \ + pkg-config \ + libssl-dev \ + gcovr + + - name: Set up Rust (stable) + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Configure (CMake, coverage) + shell: bash + run: | + set -euo pipefail + cmake -S . -B build-coverage -G Ninja \ + -DQTTY_BUILD_DOCS=OFF \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_FLAGS="--coverage" \ + -DCMAKE_EXE_LINKER_FLAGS="--coverage" + + - name: Build tests + shell: bash + run: | + set -euo pipefail + cmake --build build-coverage --target test_ffi + + - name: Run tests + shell: bash + run: | + set -euo pipefail + ctest --test-dir build-coverage --output-on-failure -L qtty_cpp + + - name: Coverage (Cobertura XML) + shell: bash + run: | + set -euo pipefail + gcovr \ + --root . \ + --exclude 'build-coverage/.*' \ + --exclude 'qtty/.*' \ + --exclude 'tests/.*' \ + --exclude 'examples/.*' \ + --xml \ + --output coverage.xml + + - name: Coverage (HTML) + shell: bash + run: | + set -euo pipefail + mkdir -p coverage_html + gcovr \ + --root . \ + --exclude 'build-coverage/.*' \ + --exclude 'qtty/.*' \ + --exclude 'tests/.*' \ + --exclude 'examples/.*' \ + --html-details \ + --output coverage_html/index.html + + - name: Build coverage summary (Markdown) + uses: irongut/CodeCoverageSummary@v1.3.0 + with: + filename: coverage.xml + badge: true + format: markdown + output: file + + - name: Publish to Job Summary + shell: bash + run: cat code-coverage-results.md >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml new file mode 100644 index 0000000..ace7a0e --- /dev/null +++ b/.github/workflows/ci-lint.yml @@ -0,0 +1,73 @@ +name: CI Lint + +on: + workflow_call: + +jobs: + lint-cpp: + name: C++ Lint (clang-format + clang-tidy) + runs-on: ubuntu-22.04 + env: + CARGO_TERM_COLOR: always + steps: + - name: Checkout (with submodules) + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Install system dependencies + shell: bash + run: | + set -euo pipefail + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + cmake \ + ninja-build \ + clang-tidy + + - name: Install clang-format 18 + shell: bash + run: | + set -euo pipefail + wget -qO /tmp/llvm.sh https://apt.llvm.org/llvm.sh + sudo bash /tmp/llvm.sh 18 + sudo apt-get install -y --no-install-recommends clang-format-18 + sudo ln -sf /usr/bin/clang-format-18 /usr/local/bin/clang-format + clang-format --version + + - name: Set up Rust (stable) + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Configure (CMake, compile commands) + shell: bash + run: | + set -euo pipefail + cmake -S . -B build -G Ninja -DQTTY_BUILD_DOCS=OFF -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + + - name: clang-format check + shell: bash + run: | + set -euo pipefail + mapfile -t files < <(git ls-files '*.hpp' '*.cpp') + if [ ${#files[@]} -eq 0 ]; then + echo "No C++ files found." + exit 0 + fi + clang-format --dry-run --Werror "${files[@]}" + + - name: clang-tidy check + shell: bash + run: | + set -euo pipefail + mapfile -t cpp_files < <(git ls-files '*.cpp') + if [ ${#cpp_files[@]} -eq 0 ]; then + echo "No C++ source files found." + exit 0 + fi + for file in "${cpp_files[@]}"; do + echo "Running clang-tidy on ${file}" + clang-tidy -p build --warnings-as-errors='*' "${file}" + done diff --git a/.github/workflows/ci-package.yml b/.github/workflows/ci-package.yml new file mode 100644 index 0000000..4b07861 --- /dev/null +++ b/.github/workflows/ci-package.yml @@ -0,0 +1,94 @@ +name: CI Package + +on: + workflow_call: + +jobs: + package: + name: Package (DEB + RPM) + runs-on: ubuntu-22.04 + env: + CARGO_TERM_COLOR: always + CMAKE_BUILD_PARALLEL_LEVEL: 2 + steps: + - name: Checkout (with submodules) + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Install system dependencies + shell: bash + run: | + set -euo pipefail + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + build-essential \ + cmake \ + ninja-build \ + pkg-config \ + libssl-dev \ + rpm + + - name: Set up Rust (stable) + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + + - name: Cache cargo + build artifacts + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + qtty/target + qtty/qtty-ffi/target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-cargo- + + - name: Configure (CMake, Release) + shell: bash + run: | + set -euo pipefail + cmake -S . -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DQTTY_BUILD_DOCS=OFF + + - name: Build + shell: bash + run: cmake --build build --target test_ffi + + - name: Install to staging prefix + shell: bash + run: cmake --install build --prefix build/staging + + - name: Copy shared libraries to staging + shell: bash + run: | + set -euo pipefail + mkdir -p build/staging/lib + cp qtty/target/release/libqtty_ffi.so \ + build/staging/lib/ || true + + - name: Generate packages (CPack) + shell: bash + run: | + set -euo pipefail + cd build + cpack --config CPackConfig.cmake -G "DEB;RPM" -B packages + ls -lh packages/ + + - name: Upload DEB package + uses: actions/upload-artifact@v4 + with: + name: qtty-cpp-deb + path: build/packages/*.deb + retention-days: 30 + + - name: Upload RPM package + uses: actions/upload-artifact@v4 + with: + name: qtty-cpp-rpm + path: build/packages/*.rpm + retention-days: 30 diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml new file mode 100644 index 0000000..61d94e9 --- /dev/null +++ b/.github/workflows/ci-release.yml @@ -0,0 +1,79 @@ +name: CI Release + +on: + workflow_call: + secrets: + GITHUB_TOKEN: + required: false + +jobs: + release: + name: GitHub Release + APT/RPM repositories + runs-on: ubuntu-22.04 + + permissions: + contents: write + + steps: + - name: Download DEB artifact + uses: actions/download-artifact@v4 + with: + name: qtty-cpp-deb + path: dist/ + + - name: Download RPM artifact + uses: actions/download-artifact@v4 + with: + name: qtty-cpp-rpm + path: dist/ + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: dist/* + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install repository tools + shell: bash + run: | + set -euo pipefail + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + dpkg-dev \ + createrepo-c + + - name: Generate APT repository + shell: bash + run: | + set -euo pipefail + mkdir -p site/apt + cp dist/*.deb site/apt/ + + cd site/apt + dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz + + - name: Generate RPM repository + shell: bash + run: | + set -euo pipefail + mkdir -p site/rpm + cp dist/*.rpm site/rpm/ + + createrepo_c site/rpm + + - name: Add custom domain + if: ${{ vars.PAGES_DOMAIN != '' }} + shell: bash + run: | + echo "${{ vars.PAGES_DOMAIN }}" > site/CNAME + + - name: Publish APT/RPM repositories to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_branch: gh-pages + publish_dir: ./site + keep_files: true + cname: ${{ vars.PAGES_DOMAIN }} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01fe376..4a2d2e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,380 +15,21 @@ permissions: jobs: lint-cpp: - name: C++ Lint (clang-format + clang-tidy) - runs-on: ubuntu-22.04 - env: - CARGO_TERM_COLOR: always - steps: - - name: Checkout (with submodules) - uses: actions/checkout@v4 - with: - submodules: recursive - fetch-depth: 0 - - - name: Install system dependencies - shell: bash - run: | - set -euo pipefail - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - cmake \ - ninja-build \ - clang-tidy - - - name: Install clang-format 18 - shell: bash - run: | - set -euo pipefail - wget -qO /tmp/llvm.sh https://apt.llvm.org/llvm.sh - sudo bash /tmp/llvm.sh 18 - sudo apt-get install -y --no-install-recommends clang-format-18 - sudo ln -sf /usr/bin/clang-format-18 /usr/local/bin/clang-format - clang-format --version - - - name: Set up Rust (stable) - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - - - name: Configure (CMake, compile commands) - shell: bash - run: | - set -euo pipefail - cmake -S . -B build -G Ninja -DQTTY_BUILD_DOCS=OFF -DCMAKE_EXPORT_COMPILE_COMMANDS=ON - - - name: clang-format check - shell: bash - run: | - set -euo pipefail - mapfile -t files < <(git ls-files '*.hpp' '*.cpp') - if [ ${#files[@]} -eq 0 ]; then - echo "No C++ files found." - exit 0 - fi - clang-format --dry-run --Werror "${files[@]}" - - - name: clang-tidy check - shell: bash - run: | - set -euo pipefail - mapfile -t cpp_files < <(git ls-files '*.cpp') - if [ ${#cpp_files[@]} -eq 0 ]; then - echo "No C++ source files found." - exit 0 - fi - for file in "${cpp_files[@]}"; do - echo "Running clang-tidy on ${file}" - clang-tidy -p build --warnings-as-errors='*' "${file}" - done + uses: ./.github/workflows/ci-lint.yml build-test-docs: - name: Build + Test + Docs - runs-on: ubuntu-22.04 - env: - CARGO_TERM_COLOR: always - CMAKE_BUILD_PARALLEL_LEVEL: 2 - steps: - - name: Checkout (with submodules) - uses: actions/checkout@v4 - with: - submodules: recursive - fetch-depth: 0 - - - name: Show selected dependency revisions - shell: bash - run: | - set -euo pipefail - git submodule status --recursive - echo - echo "qtty: $(git -C qtty rev-parse HEAD) ($(git -C qtty describe --tags --always 2>/dev/null || true))" - echo "qtty-ffi: $(git -C qtty/qtty-ffi rev-parse HEAD) ($(git -C qtty/qtty-ffi describe --tags --always 2>/dev/null || true))" - - - name: Install system dependencies - shell: bash - run: | - set -euo pipefail - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - build-essential \ - cmake \ - ninja-build \ - pkg-config \ - libssl-dev \ - graphviz - - - name: Install Doxygen 1.16.1 - shell: bash - run: | - set -euo pipefail - DOXYGEN_VERSION="1.16.1" - curl -fsSL "https://github.com/doxygen/doxygen/releases/download/Release_1_16_1/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz" -o /tmp/doxygen.tar.gz - sudo tar -xzf /tmp/doxygen.tar.gz -C /opt - sudo ln -sf "/opt/doxygen-${DOXYGEN_VERSION}/bin/doxygen" /usr/local/bin/doxygen - rm -f /tmp/doxygen.tar.gz - doxygen --version - - - name: Set up Rust (stable) - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - - - name: Cache cargo + build artifacts - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - qtty/target - qtty/qtty-ffi/target - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo- - - - name: Validate required submodules exist - shell: bash - run: | - set -euo pipefail - test -f qtty/Cargo.toml - test -f qtty/qtty-ffi/Cargo.toml - - - name: Configure (CMake) - shell: bash - run: | - set -euo pipefail - cmake -S . -B build -G Ninja -DQTTY_BUILD_DOCS=ON - - - name: Build - shell: bash - run: | - set -euo pipefail - cmake --build build --target test_ffi - - - name: Test (ctest) - shell: bash - run: | - set -euo pipefail - ctest --test-dir build --output-on-failure -L qtty_cpp - - - name: Build docs (Doxygen) - shell: bash - run: | - set -euo pipefail - cmake --build build --target docs + uses: ./.github/workflows/ci-build-test-docs.yml coverage: - name: Test & Coverage if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} - runs-on: ubuntu-22.04 - env: - CARGO_TERM_COLOR: always - - steps: - - name: Checkout (with submodules) - uses: actions/checkout@v4 - with: - submodules: recursive - fetch-depth: 0 - - - name: Install system dependencies - shell: bash - run: | - set -euo pipefail - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - build-essential \ - cmake \ - ninja-build \ - pkg-config \ - libssl-dev \ - gcovr - - - name: Set up Rust (stable) - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable + uses: ./.github/workflows/ci-coverage.yml - - name: Configure (CMake, coverage) - shell: bash - run: | - set -euo pipefail - cmake -S . -B build-coverage -G Ninja \ - -DQTTY_BUILD_DOCS=OFF \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_CXX_FLAGS="--coverage" \ - -DCMAKE_EXE_LINKER_FLAGS="--coverage" - - - name: Build tests - shell: bash - run: | - set -euo pipefail - cmake --build build-coverage --target test_ffi - - - name: Run tests - shell: bash - run: | - set -euo pipefail - ctest --test-dir build-coverage --output-on-failure -L qtty_cpp - - - name: Coverage (Cobertura XML) - shell: bash - run: | - set -euo pipefail - gcovr \ - --root . \ - --exclude 'build-coverage/.*' \ - --exclude 'qtty/.*' \ - --exclude 'tests/.*' \ - --exclude 'examples/.*' \ - --xml \ - --output coverage.xml - - - name: Coverage (HTML) - shell: bash - run: | - set -euo pipefail - mkdir -p coverage_html - gcovr \ - --root . \ - --exclude 'build-coverage/.*' \ - --exclude 'qtty/.*' \ - --exclude 'tests/.*' \ - --exclude 'examples/.*' \ - --html-details \ - --output coverage_html/index.html - - - name: Build coverage summary (Markdown) - uses: irongut/CodeCoverageSummary@v1.3.0 - with: - filename: coverage.xml - badge: true - format: markdown - output: file - - - name: Publish to Job Summary - shell: bash - run: cat code-coverage-results.md >> "$GITHUB_STEP_SUMMARY" - - # --------------------------------------------------------------------------- - # Package: build .deb and .rpm via CPack - # --------------------------------------------------------------------------- package: - name: Package (DEB + RPM) needs: build-test-docs - runs-on: ubuntu-22.04 - env: - CARGO_TERM_COLOR: always - CMAKE_BUILD_PARALLEL_LEVEL: 2 - steps: - - name: Checkout (with submodules) - uses: actions/checkout@v4 - with: - submodules: recursive - fetch-depth: 0 - - - name: Install system dependencies - shell: bash - run: | - set -euo pipefail - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - build-essential \ - cmake \ - ninja-build \ - pkg-config \ - libssl-dev \ - rpm - - - name: Set up Rust (stable) - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: stable - - - name: Cache cargo + build artifacts - uses: actions/cache@v4 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - qtty/target - qtty/qtty-ffi/target - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo- + uses: ./.github/workflows/ci-package.yml - - name: Configure (CMake, Release) - shell: bash - run: | - set -euo pipefail - cmake -S . -B build -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DQTTY_BUILD_DOCS=OFF - - - name: Build - shell: bash - run: cmake --build build --target test_ffi - - - name: Install to staging prefix - shell: bash - run: cmake --install build --prefix build/staging - - - name: Copy shared libraries to staging - shell: bash - run: | - set -euo pipefail - mkdir -p build/staging/lib - cp qtty/target/release/libqtty_ffi.so \ - build/staging/lib/ || true - - - name: Generate packages (CPack) - shell: bash - run: | - set -euo pipefail - cd build - cpack --config CPackConfig.cmake -G "DEB;RPM" -B packages - ls -lh packages/ - - - name: Upload DEB package - uses: actions/upload-artifact@v4 - with: - name: qtty-cpp-deb - path: build/packages/*.deb - retention-days: 30 - - - name: Upload RPM package - uses: actions/upload-artifact@v4 - with: - name: qtty-cpp-rpm - path: build/packages/*.rpm - retention-days: 30 - - # --------------------------------------------------------------------------- - # Release: create GitHub Release and attach packages (tag pushes only) - # --------------------------------------------------------------------------- release: - name: GitHub Release needs: package if: startsWith(github.ref, 'refs/tags/v') - runs-on: ubuntu-22.04 - permissions: - contents: write - steps: - - name: Download DEB artifact - uses: actions/download-artifact@v4 - with: - name: qtty-cpp-deb - path: dist/ - - - name: Download RPM artifact - uses: actions/download-artifact@v4 - with: - name: qtty-cpp-rpm - path: dist/ - - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - with: - files: dist/* - generate_release_notes: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/ci-release.yml + secrets: inherit From 76dd7bb0b4cd2d984033eae17e4e046d64ad030f Mon Sep 17 00:00:00 2001 From: VPRamon Date: Fri, 8 May 2026 22:39:17 +0200 Subject: [PATCH 4/5] fix(ci): update secrets handling for release workflow --- .github/workflows/ci-release.yml | 12 +++++++----- .github/workflows/ci.yml | 4 +++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index 61d94e9..f9a8aa9 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -5,6 +5,8 @@ on: secrets: GITHUB_TOKEN: required: false + PAGES_DEPLOY_TOKEN: + required: true jobs: release: @@ -64,16 +66,16 @@ jobs: createrepo_c site/rpm - name: Add custom domain - if: ${{ vars.PAGES_DOMAIN != '' }} shell: bash run: | - echo "${{ vars.PAGES_DOMAIN }}" > site/CNAME + echo "siderust.org" > site/CNAME - - name: Publish APT/RPM repositories to GitHub Pages + - name: Publish repositories to siderust.github.io uses: peaceiris/actions-gh-pages@v4 with: - github_token: ${{ secrets.GITHUB_TOKEN }} + personal_token: ${{ secrets.PAGES_DEPLOY_TOKEN }} + external_repository: Siderust/siderust.github.io publish_branch: gh-pages publish_dir: ./site keep_files: true - cname: ${{ vars.PAGES_DOMAIN }} \ No newline at end of file + cname: siderust.org \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a2d2e9..97dc669 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,4 +32,6 @@ jobs: needs: package if: startsWith(github.ref, 'refs/tags/v') uses: ./.github/workflows/ci-release.yml - secrets: inherit + secrets: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAGES_DEPLOY_TOKEN: ${{ secrets.PAGES_DEPLOY_TOKEN }} \ No newline at end of file From e114156c11dfd11f294b428d8555eb2ec03347c7 Mon Sep 17 00:00:00 2001 From: VPRamon Date: Fri, 8 May 2026 22:47:36 +0200 Subject: [PATCH 5/5] fix(ci): correct indentation for PAGES_DEPLOY_TOKEN in CI workflow --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 97dc669..bdca350 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,4 +34,4 @@ jobs: uses: ./.github/workflows/ci-release.yml secrets: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PAGES_DEPLOY_TOKEN: ${{ secrets.PAGES_DEPLOY_TOKEN }} \ No newline at end of file + PAGES_DEPLOY_TOKEN: ${{ secrets.PAGES_DEPLOY_TOKEN }} \ No newline at end of file