From 1814b2e3d91f81c565fc40fd19992f7fd378c4bd Mon Sep 17 00:00:00 2001
From: Sopwit <131982697+Sopwit@users.noreply.github.com>
Date: Mon, 30 Mar 2026 17:43:51 +0300
Subject: [PATCH 1/2] release: bump version to 0.2.1
---
CHANGELOG.md | 6 +++
CMakeLists.txt | 2 +-
...github.projectroasd.rocontrol.metainfo.xml | 2 +-
docs/man/ro-control.1 | 2 +-
packaging/rpm/README.md | 2 +-
packaging/rpm/ro-control.spec | 6 ++-
tests/test_cli.cpp | 38 +++++++++----------
tests/test_metadata.cpp | 2 +-
8 files changed, 35 insertions(+), 25 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce25c79..9b553b6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [0.2.1] - 2026-03-30
+
+### Changed
+- GitHub Releases now publish only `x86_64`, `aarch64`, `noarch`, and `src` RPM outputs
+- Shared desktop assets and metadata now ship in a dedicated `noarch` companion RPM
+
## [0.2.0] - 2026-03-30
### Changed
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aa7e9a0..2fe8cf1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.22)
project(ro-control
- VERSION 0.2.0
+ VERSION 0.2.1
DESCRIPTION "Smart NVIDIA Driver Manager & System Monitor for Linux"
HOMEPAGE_URL "https://github.com/Project-Ro-ASD/ro-Control"
LANGUAGES CXX
diff --git a/data/icons/io.github.projectroasd.rocontrol.metainfo.xml b/data/icons/io.github.projectroasd.rocontrol.metainfo.xml
index 6f23ec8..9ec21cf 100644
--- a/data/icons/io.github.projectroasd.rocontrol.metainfo.xml
+++ b/data/icons/io.github.projectroasd.rocontrol.metainfo.xml
@@ -38,7 +38,7 @@
-
+
diff --git a/docs/man/ro-control.1 b/docs/man/ro-control.1
index 343741c..e3c1af2 100644
--- a/docs/man/ro-control.1
+++ b/docs/man/ro-control.1
@@ -1,4 +1,4 @@
-.TH RO-CONTROL 1 "March 2026" "ro-control 0.2.0" "User Commands"
+.TH RO-CONTROL 1 "March 2026" "ro-control 0.2.1" "User Commands"
.SH NAME
ro-control \- NVIDIA driver management and diagnostics CLI
.SH SYNOPSIS
diff --git a/packaging/rpm/README.md b/packaging/rpm/README.md
index 78fa82b..82a1008 100644
--- a/packaging/rpm/README.md
+++ b/packaging/rpm/README.md
@@ -40,7 +40,7 @@ macro explicitly:
```bash
rpmbuild -ba packaging/rpm/ro-control.spec \
- --define "upstream_version 0.2.0"
+ --define "upstream_version 0.2.1"
```
If you build from a Git checkout instead of a published source archive, create
diff --git a/packaging/rpm/ro-control.spec b/packaging/rpm/ro-control.spec
index ca617f1..3b56978 100644
--- a/packaging/rpm/ro-control.spec
+++ b/packaging/rpm/ro-control.spec
@@ -1,4 +1,4 @@
-%global upstream_version %{!?upstream_version:0.2.0}%{?upstream_version}
+%global upstream_version %{!?upstream_version:0.2.1}%{?upstream_version}
%global debug_package %{nil}
Name: ro-control
@@ -89,6 +89,10 @@ tar -xzf %{SOURCE0} --strip-components=1
%{_datadir}/polkit-1/actions/io.github.ProjectRoASD.rocontrol.policy
%changelog
+* Mon Mar 30 2026 ro-Control Maintainers - 0.2.1-1
+- Limit release outputs to x86_64, aarch64, noarch, and src RPM artifacts
+- Split shared desktop assets into a noarch companion package
+
* Mon Mar 30 2026 ro-Control Maintainers - 0.2.0-1
- Fix installed helper path resolution for privileged operations on system installs
- Activate saved KDE-friendly interface preferences and theme switching in the UI
diff --git a/tests/test_cli.cpp b/tests/test_cli.cpp
index bd47489..89851ca 100644
--- a/tests/test_cli.cpp
+++ b/tests/test_cli.cpp
@@ -12,7 +12,7 @@ private slots:
RoControlCli::parseArguments({QStringLiteral("ro-control"),
QStringLiteral("--help")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::PrintHelp);
QVERIFY(command.payload.contains(QStringLiteral("driver install")));
@@ -24,10 +24,10 @@ private slots:
RoControlCli::parseArguments({QStringLiteral("ro-control"),
QStringLiteral("--version")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::PrintVersion);
- QCOMPARE(command.payload, QStringLiteral("0.2.0"));
+ QCOMPARE(command.payload, QStringLiteral("0.2.1"));
}
void testJsonRequiresDiagnostics() {
@@ -35,7 +35,7 @@ private slots:
RoControlCli::parseArguments({QStringLiteral("ro-control"),
QStringLiteral("--json")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::Invalid);
QVERIFY(command.payload.contains(QStringLiteral("--json")));
@@ -46,7 +46,7 @@ private slots:
RoControlCli::parseArguments({QStringLiteral("ro-control"),
QStringLiteral("status")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::PrintStatusText);
}
@@ -57,7 +57,7 @@ private slots:
QStringLiteral("status"),
QStringLiteral("--json")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::PrintStatusJson);
}
@@ -67,7 +67,7 @@ private slots:
RoControlCli::parseArguments({QStringLiteral("ro-control"),
QStringLiteral("diagnostics")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::PrintDiagnosticsText);
}
@@ -78,7 +78,7 @@ private slots:
QStringLiteral("diagnostics"),
QStringLiteral("--json")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::PrintDiagnosticsJson);
}
@@ -89,7 +89,7 @@ private slots:
QStringLiteral("--diagnostics"),
QStringLiteral("--json")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::PrintDiagnosticsJson);
}
@@ -100,7 +100,7 @@ private slots:
QStringLiteral("driver"),
QStringLiteral("install")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action,
RoControlCli::CommandAction::InstallProprietaryDriver);
@@ -114,7 +114,7 @@ private slots:
QStringLiteral("install"),
QStringLiteral("--open-source")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action,
RoControlCli::CommandAction::InstallOpenSourceDriver);
@@ -128,7 +128,7 @@ private slots:
QStringLiteral("--proprietary"),
QStringLiteral("--accept-license")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action,
RoControlCli::CommandAction::InstallProprietaryDriver);
@@ -141,7 +141,7 @@ private slots:
QStringLiteral("driver"),
QStringLiteral("update")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::UpdateDriver);
}
@@ -153,7 +153,7 @@ private slots:
QStringLiteral("install"),
QStringLiteral("--json")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::Invalid);
QVERIFY(command.payload.contains(QStringLiteral("--json")));
@@ -167,7 +167,7 @@ private slots:
QStringLiteral("--proprietary"),
QStringLiteral("--open-source")},
QStringLiteral("ro-control"),
- QStringLiteral("0.2.0"),
+ QStringLiteral("0.2.1"),
QStringLiteral("CLI test"));
QCOMPARE(command.action, RoControlCli::CommandAction::Invalid);
QVERIFY(command.payload.contains(QStringLiteral("cannot be used together")));
@@ -176,7 +176,7 @@ private slots:
void testRenderDiagnosticsText() {
RoControlCli::DiagnosticsSnapshot snapshot;
snapshot.applicationName = QStringLiteral("ro-control");
- snapshot.applicationVersion = QStringLiteral("0.2.0");
+ snapshot.applicationVersion = QStringLiteral("0.2.1");
snapshot.locale = QStringLiteral("en_US");
snapshot.gpuFound = true;
snapshot.gpuName = QStringLiteral("Example GPU");
@@ -193,7 +193,7 @@ private slots:
void testRenderStatusText() {
RoControlCli::DiagnosticsSnapshot snapshot;
snapshot.applicationName = QStringLiteral("ro-control");
- snapshot.applicationVersion = QStringLiteral("0.2.0");
+ snapshot.applicationVersion = QStringLiteral("0.2.1");
snapshot.activeDriver = QStringLiteral("Proprietary");
snapshot.updateAvailable = true;
@@ -206,7 +206,7 @@ private slots:
void testRenderDiagnosticsJsonObject() {
RoControlCli::DiagnosticsSnapshot snapshot;
snapshot.applicationName = QStringLiteral("ro-control");
- snapshot.applicationVersion = QStringLiteral("0.2.0");
+ snapshot.applicationVersion = QStringLiteral("0.2.1");
snapshot.gpuFound = true;
snapshot.ramUsagePercent = 42;
@@ -221,7 +221,7 @@ private slots:
void testRenderStatusJsonObject() {
RoControlCli::DiagnosticsSnapshot snapshot;
snapshot.applicationName = QStringLiteral("ro-control");
- snapshot.applicationVersion = QStringLiteral("0.2.0");
+ snapshot.applicationVersion = QStringLiteral("0.2.1");
snapshot.updateAvailable = true;
const QJsonObject object = RoControlCli::renderStatusJsonObject(snapshot);
diff --git a/tests/test_metadata.cpp b/tests/test_metadata.cpp
index bbd237c..c409c9f 100644
--- a/tests/test_metadata.cpp
+++ b/tests/test_metadata.cpp
@@ -75,7 +75,7 @@ private slots:
"data/icons/io.github.projectroasd.rocontrol.metainfo.xml"));
QVERIFY(!metainfo.isEmpty());
QVERIFY(metainfo.contains(
- QStringLiteral("")));
+ QStringLiteral("")));
}
void testCliDocumentationAssetsExist() {
From d5251084a4e115166c264deb57b365ab597246d1 Mon Sep 17 00:00:00 2001
From: Sopwit <131982697+Sopwit@users.noreply.github.com>
Date: Mon, 30 Mar 2026 17:46:38 +0300
Subject: [PATCH 2/2] style: apply clang-format to backend sources
---
src/backend/monitor/gpumonitor.cpp | 33 +++++++++++------------
src/backend/nvidia/detector.cpp | 9 +++----
src/backend/nvidia/detector.h | 4 +--
src/backend/system/capabilityprobe.cpp | 5 ++--
src/backend/system/systeminfoprovider.cpp | 19 ++++++-------
src/backend/system/systeminfoprovider.h | 3 ++-
6 files changed, 36 insertions(+), 37 deletions(-)
diff --git a/src/backend/monitor/gpumonitor.cpp b/src/backend/monitor/gpumonitor.cpp
index d92b139..dd86ff1 100644
--- a/src/backend/monitor/gpumonitor.cpp
+++ b/src/backend/monitor/gpumonitor.cpp
@@ -71,14 +71,14 @@ bool readIntegerFile(const QString &path, qint64 *value) {
}
bool readFirstTemperatureFromHwmon(const QString &basePath, int *value) {
- const QFileInfoList hwmonEntries =
- QDir(basePath).entryInfoList({QStringLiteral("hwmon*")},
- QDir::Dirs | QDir::NoDotAndDotDot,
- QDir::Name);
+ const QFileInfoList hwmonEntries = QDir(basePath).entryInfoList(
+ {QStringLiteral("hwmon*")}, QDir::Dirs | QDir::NoDotAndDotDot,
+ QDir::Name);
for (const QFileInfo &entry : hwmonEntries) {
- const QFileInfoList inputs = QDir(entry.absoluteFilePath())
- .entryInfoList({QStringLiteral("temp*_input")},
- QDir::Files, QDir::Name);
+ const QFileInfoList inputs =
+ QDir(entry.absoluteFilePath())
+ .entryInfoList({QStringLiteral("temp*_input")}, QDir::Files,
+ QDir::Name);
for (const QFileInfo &input : inputs) {
qint64 milliC = 0;
if (readIntegerFile(input.absoluteFilePath(), &milliC) && milliC > 0) {
@@ -94,9 +94,9 @@ bool readFirstTemperatureFromHwmon(const QString &basePath, int *value) {
bool readGenericLinuxGpuMetrics(int *temperatureC, int *utilizationPercent,
int *memoryUsedMiB, int *memoryTotalMiB) {
const QFileInfoList cardEntries =
- QDir(drmRootPath()).entryInfoList({QStringLiteral("card*")},
- QDir::Dirs | QDir::NoDotAndDotDot,
- QDir::Name);
+ QDir(drmRootPath())
+ .entryInfoList({QStringLiteral("card*")},
+ QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
bool anyMetric = false;
for (const QFileInfo &cardEntry : cardEntries) {
@@ -117,19 +117,16 @@ bool readGenericLinuxGpuMetrics(int *temperatureC, int *utilizationPercent,
if (utilizationPercent != nullptr &&
readIntegerFile(devicePath + QStringLiteral("/gpu_busy_percent"),
&busyPercent)) {
- *utilizationPercent =
- std::clamp(static_cast(busyPercent), 0, 100);
+ *utilizationPercent = std::clamp(static_cast(busyPercent), 0, 100);
anyMetric = true;
}
qint64 usedBytes = 0;
qint64 totalBytes = 0;
- const bool usedOk =
- readIntegerFile(devicePath + QStringLiteral("/mem_info_vram_used"),
- &usedBytes);
- const bool totalOk =
- readIntegerFile(devicePath + QStringLiteral("/mem_info_vram_total"),
- &totalBytes);
+ const bool usedOk = readIntegerFile(
+ devicePath + QStringLiteral("/mem_info_vram_used"), &usedBytes);
+ const bool totalOk = readIntegerFile(
+ devicePath + QStringLiteral("/mem_info_vram_total"), &totalBytes);
if (usedOk && totalOk && totalBytes > 0) {
if (memoryUsedMiB != nullptr) {
*memoryUsedMiB =
diff --git a/src/backend/nvidia/detector.cpp b/src/backend/nvidia/detector.cpp
index 499c860..ffc3c51 100644
--- a/src/backend/nvidia/detector.cpp
+++ b/src/backend/nvidia/detector.cpp
@@ -51,11 +51,10 @@ QString NvidiaDetector::activeDriver() const {
}
QString NvidiaDetector::verificationReport() const {
- const QString gpuText = m_info.found
- ? m_info.name
- : (m_info.displayAdapterName.isEmpty()
- ? tr("None")
- : m_info.displayAdapterName);
+ const QString gpuText = m_info.found ? m_info.name
+ : (m_info.displayAdapterName.isEmpty()
+ ? tr("None")
+ : m_info.displayAdapterName);
const QString versionText =
m_info.driverVersion.isEmpty() ? tr("None") : m_info.driverVersion;
diff --git a/src/backend/nvidia/detector.h b/src/backend/nvidia/detector.h
index 0704bc5..d0e18ac 100644
--- a/src/backend/nvidia/detector.h
+++ b/src/backend/nvidia/detector.h
@@ -9,8 +9,8 @@ class NvidiaDetector : public QObject {
Q_PROPERTY(bool gpuFound READ gpuFound NOTIFY infoChanged)
Q_PROPERTY(QString gpuName READ gpuName NOTIFY infoChanged)
- Q_PROPERTY(QString displayAdapterName READ displayAdapterName NOTIFY
- infoChanged)
+ Q_PROPERTY(
+ QString displayAdapterName READ displayAdapterName NOTIFY infoChanged)
Q_PROPERTY(QString driverVersion READ driverVersion NOTIFY infoChanged)
Q_PROPERTY(bool driverLoaded READ driverLoaded NOTIFY infoChanged)
Q_PROPERTY(bool nouveauActive READ nouveauActive NOTIFY infoChanged)
diff --git a/src/backend/system/capabilityprobe.cpp b/src/backend/system/capabilityprobe.cpp
index 533a50c..98d82e5 100644
--- a/src/backend/system/capabilityprobe.cpp
+++ b/src/backend/system/capabilityprobe.cpp
@@ -77,8 +77,9 @@ QString fedoraNvidiaDriverFlowSupportMessage() {
}
return QStringLiteral(
- "Fedora NVIDIA driver management is currently supported only on x86_64 "
- "and aarch64 builds. The current build architecture is %1.")
+ "Fedora NVIDIA driver management is currently supported only on "
+ "x86_64 "
+ "and aarch64 builds. The current build architecture is %1.")
.arg(normalizedCpuArchitecture());
}
diff --git a/src/backend/system/systeminfoprovider.cpp b/src/backend/system/systeminfoprovider.cpp
index f8611e6..22c34b6 100644
--- a/src/backend/system/systeminfoprovider.cpp
+++ b/src/backend/system/systeminfoprovider.cpp
@@ -3,8 +3,8 @@
#include "commandrunner.h"
#include
-#include
#include
+#include
#include
#include
@@ -67,8 +67,8 @@ QString valueFromOsRelease(const QString &key) {
}
QString value = line.mid(key.size() + 1).trimmed();
- if (value.startsWith(QLatin1Char('"')) && value.endsWith(QLatin1Char('"')) &&
- value.size() >= 2) {
+ if (value.startsWith(QLatin1Char('"')) &&
+ value.endsWith(QLatin1Char('"')) && value.size() >= 2) {
value = value.mid(1, value.size() - 2);
}
return value;
@@ -77,7 +77,7 @@ QString valueFromOsRelease(const QString &key) {
return {};
}
-} // namespace
+} // namespace
SystemInfoProvider::SystemInfoProvider(QObject *parent) : QObject(parent) {
refresh();
@@ -118,7 +118,7 @@ QString SystemInfoProvider::detectOsName() const {
QString SystemInfoProvider::detectKernelVersion() const {
#if defined(Q_OS_UNIX)
- utsname name {};
+ utsname name{};
if (uname(&name) == 0) {
return QString::fromLocal8Bit(name.release);
}
@@ -173,7 +173,8 @@ QString SystemInfoProvider::detectCpuModel() const {
}
const auto virtResult =
- runner.run(QStringLiteral("systemd-detect-virt"), {QStringLiteral("--quiet"), QStringLiteral("--vm")});
+ runner.run(QStringLiteral("systemd-detect-virt"),
+ {QStringLiteral("--quiet"), QStringLiteral("--vm")});
if (virtResult.success()) {
const auto virtName = runner.run(QStringLiteral("systemd-detect-virt"));
if (virtName.success()) {
@@ -188,9 +189,9 @@ QString SystemInfoProvider::detectCpuModel() const {
}
#elif defined(Q_OS_MACOS)
CommandRunner runner;
- const auto result =
- runner.run(QStringLiteral("sysctl"),
- {QStringLiteral("-n"), QStringLiteral("machdep.cpu.brand_string")});
+ const auto result = runner.run(
+ QStringLiteral("sysctl"),
+ {QStringLiteral("-n"), QStringLiteral("machdep.cpu.brand_string")});
if (result.success()) {
const QString value = result.stdout.trimmed();
if (!value.isEmpty()) {
diff --git a/src/backend/system/systeminfoprovider.h b/src/backend/system/systeminfoprovider.h
index 83d308d..88f72d4 100644
--- a/src/backend/system/systeminfoprovider.h
+++ b/src/backend/system/systeminfoprovider.h
@@ -7,7 +7,8 @@ class SystemInfoProvider : public QObject {
Q_OBJECT
Q_PROPERTY(QString osName READ osName NOTIFY infoChanged)
- Q_PROPERTY(QString desktopEnvironment READ desktopEnvironment NOTIFY infoChanged)
+ Q_PROPERTY(
+ QString desktopEnvironment READ desktopEnvironment NOTIFY infoChanged)
Q_PROPERTY(QString kernelVersion READ kernelVersion NOTIFY infoChanged)
Q_PROPERTY(QString cpuModel READ cpuModel NOTIFY infoChanged)