From 63b30e2925eb8f34ccf98aba0405f76a6934260c Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 3 Jul 2024 17:50:58 +1000 Subject: [PATCH] Qt: Annotate unofficial release builds --- .github/workflows/rolling-release.yml | 31 +++++--- src/duckstation-qt/autoupdaterdialog.cpp | 90 +++++++++++++++++++++++- src/duckstation-qt/autoupdaterdialog.h | 1 + src/duckstation-qt/qthost.cpp | 3 + 4 files changed, 115 insertions(+), 10 deletions(-) diff --git a/.github/workflows/rolling-release.yml b/.github/workflows/rolling-release.yml index 322bde371..452e9e63b 100644 --- a/.github/workflows/rolling-release.yml +++ b/.github/workflows/rolling-release.yml @@ -48,21 +48,23 @@ jobs: DEBUG: 0 run: scripts/build-dependencies-windows-arm64.bat + - name: Initialize build tag + shell: cmd + run: | + echo #pragma once > src/scmversion/tag.h + - name: Tag as preview build if: github.ref == 'refs/heads/master' shell: cmd run: | - echo #pragma once > src/scmversion/tag.h echo #define SCM_RELEASE_ASSET "duckstation-windows-x64-release.zip" >> src/scmversion/tag.h echo #define SCM_RELEASE_TAGS {"latest", "preview"} >> src/scmversion/tag.h echo #define SCM_RELEASE_TAG "preview" >> src/scmversion/tag.h - - name: Tag as dev build if: github.ref == 'refs/heads/dev' shell: cmd run: | - echo #pragma once > src/scmversion/tag.h echo #define SCM_RELEASE_ASSET "duckstation-windows-x64-release.zip" >> src/scmversion/tag.h echo #define SCM_RELEASE_TAGS {"latest", "preview"} >> src/scmversion/tag.h echo #define SCM_RELEASE_TAG "latest" >> src/scmversion/tag.h @@ -134,11 +136,15 @@ jobs: DEBUG: 0 run: scripts/build-dependencies-windows-arm64.bat + - name: Initialize build tag + shell: cmd + run: | + echo #pragma once > src/scmversion/tag.h + - name: Tag as preview build if: github.ref == 'refs/heads/master' shell: cmd run: | - echo #pragma once > src/scmversion/tag.h echo #define SCM_RELEASE_ASSET "duckstation-windows-arm64-release.zip" >> src/scmversion/tag.h echo #define SCM_RELEASE_TAGS {"latest", "preview"} >> src/scmversion/tag.h echo #define SCM_RELEASE_TAG "preview" >> src/scmversion/tag.h @@ -147,7 +153,6 @@ jobs: if: github.ref == 'refs/heads/dev' shell: cmd run: | - echo #pragma once > src/scmversion/tag.h echo #define SCM_RELEASE_ASSET "duckstation-windows-arm64-release.zip" >> src/scmversion/tag.h echo #define SCM_RELEASE_TAGS {"latest", "preview"} >> src/scmversion/tag.h echo #define SCM_RELEASE_TAG "latest" >> src/scmversion/tag.h @@ -232,10 +237,13 @@ jobs: if: steps.cache-deps.outputs.cache-hit != 'true' run: scripts/build-dependencies-linux.sh "$HOME/deps" + - name: Initialize build tag + run: | + echo '#pragma once' > src/scmversion/tag.h + - name: Tag as preview build if: github.ref == 'refs/heads/master' run: | - echo '#pragma once' > src/scmversion/tag.h echo '#define SCM_RELEASE_ASSET "DuckStation-x64.AppImage"' >> src/scmversion/tag.h echo '#define SCM_RELEASE_TAGS {"latest", "preview"}' >> src/scmversion/tag.h echo '#define SCM_RELEASE_TAG "preview"' >> src/scmversion/tag.h @@ -243,7 +251,6 @@ jobs: - name: Tag as dev build if: github.ref == 'refs/heads/dev' run: | - echo '#pragma once' > src/scmversion/tag.h echo '#define SCM_RELEASE_ASSET "DuckStation-x64.AppImage"' >> src/scmversion/tag.h echo '#define SCM_RELEASE_TAGS {"latest", "preview"}' >> src/scmversion/tag.h echo '#define SCM_RELEASE_TAG "latest"' >> src/scmversion/tag.h @@ -283,6 +290,10 @@ jobs: shell: bash run: git config --global --add safe.directory "*" + - name: Initialize build tag + run: | + echo '#pragma once' > src/scmversion/tag.h + - name: Generate AppStream XML run: | scripts/generate-metainfo.sh scripts/flatpak @@ -356,10 +367,13 @@ jobs: if: steps.cache-deps-mac.outputs.cache-hit != 'true' run: scripts/build-dependencies-mac.sh "$HOME/deps" + - name: Initialize build tag + run: | + echo '#pragma once' > src/scmversion/tag.h + - name: Tag as preview build if: github.ref == 'refs/heads/master' run: | - echo '#pragma once' > src/scmversion/tag.h echo '#define SCM_RELEASE_ASSET "duckstation-mac-release.zip"' >> src/scmversion/tag.h echo '#define SCM_RELEASE_TAGS {"latest", "preview"}' >> src/scmversion/tag.h echo '#define SCM_RELEASE_TAG "preview"' >> src/scmversion/tag.h @@ -367,7 +381,6 @@ jobs: - name: Tag as dev build if: github.ref == 'refs/heads/dev' run: | - echo '#pragma once' > src/scmversion/tag.h echo '#define SCM_RELEASE_ASSET "duckstation-mac-release.zip"' >> src/scmversion/tag.h echo '#define SCM_RELEASE_TAGS {"latest", "preview"}' >> src/scmversion/tag.h echo '#define SCM_RELEASE_TAG "latest"' >> src/scmversion/tag.h diff --git a/src/duckstation-qt/autoupdaterdialog.cpp b/src/duckstation-qt/autoupdaterdialog.cpp index 47cdde1d4..fdce8709f 100644 --- a/src/duckstation-qt/autoupdaterdialog.cpp +++ b/src/duckstation-qt/autoupdaterdialog.cpp @@ -26,9 +26,12 @@ #include #include #include +#include +#include #include #include #include +#include // Interval at which HTTP requests are polled. static constexpr u32 HTTP_POLL_INTERVAL = 10; @@ -42,7 +45,7 @@ static constexpr u32 HTTP_POLL_INTERVAL = 10; // Logic to detect whether we can use the auto updater. // Requires that the channel be defined by the buildbot. -#if defined(__has_include) && __has_include("scmversion/tag.h") +#if __has_include("scmversion/tag.h") #include "scmversion/tag.h" #ifdef SCM_RELEASE_TAGS #define AUTO_UPDATER_SUPPORTED @@ -100,6 +103,91 @@ bool AutoUpdaterDialog::isSupported() #endif } +bool AutoUpdaterDialog::warnAboutUnofficialBuild() +{ + // + // To those distributing their own builds or packages of DuckStation, and seeing this message: + // + // This message is here for a reason. Under the terms of the license, you are within your rights to distribute your + // own builds of my application. However, it is a headache for me, as users run into broken functionality, or end up + // on untested/preview commits that have not been adequately tested, and I cannot resolve their issues. I provide + // builds for a range of platforms that covers almost all use cases, and can guarantee quality of these builds. + // + // If you must distribute builds/packages, per the GPL, modified builds should be clearly marked as such. + // This message is thus one way of meeting the requirement. See Section 5 of the GPLv3: + // https://www.gnu.org/licenses/gpl-3.0.en.html#section5 + // + // This includes building the binary with any method that does not match the official release, including dependencies, + // as it is not uncommon for differing dependency versions to create issues I cannot reproduce. + // + // You should also provide user support for your package, and not direct them to upstream, as any users that ask for + // community help will be instructed to download a supported release instead. + // +#if !__has_include("scmversion/tag.h") && !defined(_DEBUG) + constexpr const char* CONFIG_SECTION = "UI"; + constexpr const char* CONFIG_KEY = "UnofficialBuildWarningConfirmed"; + if (Host::GetBaseBoolSettingValue(CONFIG_SECTION, CONFIG_KEY, false)) + return true; + + constexpr int DELAY_SECONDS = 5; + + const QString message = QStringLiteral( + "

You are not using an official release!

If you continue to use this build, expect to run into " + "issues.

No assistance will be provided by the developers or community, as we cannot fix " + "broken functionality in builds we do not control.

We strongly recommend downloading an " + "official release from duckstation.org.

Do you want to exit and " + "open this page now?

"); + + QMessageBox mbox; + mbox.setIcon(QMessageBox::Warning); + mbox.setWindowTitle(QStringLiteral("Unofficial Build Warning")); + mbox.setWindowIcon(QtHost::GetAppIcon()); + mbox.setTextFormat(Qt::RichText); + mbox.setText(message); + + mbox.addButton(QMessageBox::Yes); + QPushButton* no = mbox.addButton(QMessageBox::No); + const QString orig_no_text = no->text(); + no->setEnabled(false); + + QCheckBox* cb = new QCheckBox(&mbox); + cb->setText(tr("Do not show again")); + mbox.setCheckBox(cb); + + int remaining_time = DELAY_SECONDS; + no->setText(QStringLiteral("%1 [%2]").arg(orig_no_text).arg(remaining_time)); + + QTimer* timer = new QTimer(&mbox); + connect(timer, &QTimer::timeout, &mbox, [no, timer, &remaining_time, &orig_no_text]() { + remaining_time--; + if (remaining_time == 0) + { + no->setText(orig_no_text); + no->setEnabled(true); + timer->stop(); + } + else + { + no->setText(QStringLiteral("%1 [%2]").arg(orig_no_text).arg(remaining_time)); + } + }); + timer->start(1000); + + if (mbox.exec() == QMessageBox::Yes) + { + QtUtils::OpenURL(nullptr, "https://duckstation.org/"); + return false; + } + + if (cb->isChecked()) + Host::SetBaseBoolSettingValue(CONFIG_SECTION, CONFIG_KEY, true); + + return true; +#else + return true; +#endif +} + QStringList AutoUpdaterDialog::getTagList() { #ifdef AUTO_UPDATER_SUPPORTED diff --git a/src/duckstation-qt/autoupdaterdialog.h b/src/duckstation-qt/autoupdaterdialog.h index 23219eeb6..166c21bd7 100644 --- a/src/duckstation-qt/autoupdaterdialog.h +++ b/src/duckstation-qt/autoupdaterdialog.h @@ -32,6 +32,7 @@ public: static QStringList getTagList(); static std::string getDefaultTag(); static void cleanupAfterUpdate(); + static bool warnAboutUnofficialBuild(); Q_SIGNALS: void updateCheckCompleted(); diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp index 256b9bdaa..d6e4a27ca 100644 --- a/src/duckstation-qt/qthost.cpp +++ b/src/duckstation-qt/qthost.cpp @@ -2520,6 +2520,9 @@ int main(int argc, char* argv[]) if (!QtHost::ParseCommandLineParametersAndInitializeConfig(app, autoboot)) return EXIT_FAILURE; + if (!AutoUpdaterDialog::warnAboutUnofficialBuild()) + return EXIT_FAILURE; + if (!QtHost::EarlyProcessStartup()) return EXIT_FAILURE;