diff --git a/.jenkins_msys2 b/.jenkins_msys2 new file mode 100644 index 00000000..98c82cfd --- /dev/null +++ b/.jenkins_msys2 @@ -0,0 +1,68 @@ +#!groovy + +pipeline { + agent none + + environment { + PROJECT_TEST_CONFIG_DIR = "c:\\.ci\\repertory\\test" + } + + options { + disableConcurrentBuilds() + skipDefaultCheckout() + timestamps() + } + + stages { + stage('Build • Test') { + agent any + stages { + stage('Checkout') { + steps { + script { + int maxAttempts = 6 + int baseDelay = 10 + for (int attempt = 1; attempt <= maxAttempts; attempt++) { + try { + checkout scm + break + } catch (err) { + if (attempt == maxAttempts) { throw err } + int waitSec = baseDelay * (1 << (attempt - 1)) + echo "Checkout failed (attempt ${attempt}/${maxAttempts}). Waiting ${waitSec}s before retry..." + sleep time: waitSec, unit: 'SECONDS' + } + } + } + } + } + + stage('msys2') { + steps { + script { retryWithBackoff(2, 5) { sh 'scripts\\make_win32.cmd' } } + } + } + + stage('msys2_test') { + steps { + script { retryWithBackoff(2, 5) { sh 'scripts\\run_tests.cmd' } } + } + } + } + } + } +} + +def retryWithBackoff(int maxAttempts, int baseDelaySeconds, Closure body) { + for (int attempt = 1; attempt <= maxAttempts; attempt++) { + try { + body() + return + } catch (err) { + if (attempt == maxAttempts) { throw err } + int waitSec = baseDelaySeconds * (1 << (attempt - 1)) + echo "Step failed (attempt ${attempt}/${maxAttempts}). Waiting ${waitSec}s before retry..." + sleep time: waitSec, unit: 'SECONDS' + } + } +} diff --git a/repertory.iss.in b/repertory.iss.in index 86f6bc5a..e9b7fa7c 100644 --- a/repertory.iss.in +++ b/repertory.iss.in @@ -162,8 +162,10 @@ Source: "3rd_party\winfsp-@WINFSP_VERSION@.msi"; DestDir: "{app}"; Flags: ignore [Icons] Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Parameters: "-ui --hidden"; IconFilename: "{app}\icon.ico" -Name: "{userstartup}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Parameters: "-ui -lo --hidden"; IconFilename: "{app}\icon.ico" [Run] Filename: "msiexec.exe"; WorkingDir: "{app}"; Parameters: "/i winfsp-@WINFSP_VERSION@.msi /norestart"; \ - Flags: 64bit waituntilterminated; Components: winfsp + Flags: 64bit hidewizard waituntilterminated skipifsilent; Components: winfsp +Filename: "{app}\repertory.exe"; WorkingDir: "{app}"; Parameters: "-ui --hidden"; \ + Description: "Launch Repertory Management Portal"; \ + Flags: 64bit runhidden nowait postinstall skipifsilent; Components: full custom diff --git a/repertory/repertory/src/ui/handlers.cpp b/repertory/repertory/src/ui/handlers.cpp index 8050a1f5..9949182a 100644 --- a/repertory/repertory/src/ui/handlers.cpp +++ b/repertory/repertory/src/ui/handlers.cpp @@ -276,13 +276,16 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) static std::atomic this_server{server_}; static const auto quit_handler = [](int /* sig */) { - auto *ptr = this_server.load(); + auto *ptr = this_server.exchange(nullptr); if (ptr == nullptr) { return; } - this_server = nullptr; +#if defined(_WIN32) + std::jthread([ptr]() { ptr->stop(); }); +#else // !defined(_WIN32) ptr->stop(); +#endif // defined(_WIN32) }; std::signal(SIGINT, quit_handler); @@ -348,10 +351,7 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server) auto_mount.join(); server_->listen("127.0.0.1", config_->get_api_port()); - if (this_server != nullptr) { - this_server = nullptr; - server_->stop(); - } + quit_handler(SIGTERM); } handlers::~handlers() {