From 4aa5c1313cce285f2da60e06be2a7608599379e2 Mon Sep 17 00:00:00 2001 From: MintHCM-admin Date: Fri, 9 Jan 2026 14:59:06 +0100 Subject: [PATCH 01/21] php version is dont work --- install/minthcm-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/minthcm-install.sh b/install/minthcm-install.sh index a6eed1129..ed5752da0 100644 --- a/install/minthcm-install.sh +++ b/install/minthcm-install.sh @@ -12,7 +12,7 @@ catch_errors setting_up_container network_check update_os - +PHP_VERSION="8.2" PHP_APACHE="YES" PHP_VERSION="8.2" PHP_MODULE="mysql,cli,redis" PHP_FPM="YES" setup_php setup_composer From b69ea19a3b6b7f81cb563108f611f18346d10c81 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 13:20:00 +0000 Subject: [PATCH 02/21] Delete qui (ct) after migration to ProxmoxVE (#1292) Co-authored-by: github-actions[bot] --- ct/headers/qui | 6 ---- ct/qui.sh | 58 ----------------------------------- frontend/public/json/qui.json | 35 --------------------- install/qui-install.sh | 42 ------------------------- 4 files changed, 141 deletions(-) delete mode 100644 ct/headers/qui delete mode 100644 ct/qui.sh delete mode 100644 frontend/public/json/qui.json delete mode 100644 install/qui-install.sh diff --git a/ct/headers/qui b/ct/headers/qui deleted file mode 100644 index 1f3048cf7..000000000 --- a/ct/headers/qui +++ /dev/null @@ -1,6 +0,0 @@ - ____ _ - / __ \__ __(_) - / / / / / / / / -/ /_/ / /_/ / / -\___\_\__,_/_/ - diff --git a/ct/qui.sh b/ct/qui.sh deleted file mode 100644 index 4984e1b7a..000000000 --- a/ct/qui.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/misc/build.func) -# Copyright (c) 2021-2026 community-scripts ORG -# Author: MickLesk (Canbiz) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/autobrr/qui - -APP="Qui" -var_tags="${var_tags:-torrent}" -var_disk="${var_disk:-10}" -var_cpu="${var_cpu:-1}" -var_ram="${var_ram:-1024}" -var_os="${var_os:-debian}" -var_version="${var_version:-13}" -var_unprivileged="${var_unprivileged:-1}" - -header_info "$APP" -variables -color -catch_errors - -function update_script() { - header_info - check_container_storage - check_container_resources - if [[ ! -f /usr/local/bin/qui ]]; then - msg_error "No ${APP} Installation Found!" - exit - fi - if check_for_gh_release "Qui" "autobrr/qui"; then - msg_info "Stopping Service" - systemctl stop qui - msg_ok "Stopped Service" - - fetch_and_deploy_gh_release "qui" "autobrr/qui" "prebuild" "latest" "/tmp/qui" "qui_*_linux_x86_64.tar.gz" - - msg_info "Updating qui" - mv /tmp/qui/qui /usr/local/bin/qui - chmod +x /usr/local/bin/qui - rm -rf /tmp/qui - msg_ok "Updated qui" - - msg_info "Starting Service" - systemctl start qui - msg_ok "Started Service" - msg_ok "Updated successfully!" - fi - exit -} - -start -build_container -description - -msg_ok "Completed successfully!\n" -echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" -echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:7476${CL}" diff --git a/frontend/public/json/qui.json b/frontend/public/json/qui.json deleted file mode 100644 index 1c9c8f722..000000000 --- a/frontend/public/json/qui.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "Qui", - "slug": "qui", - "categories": [ - 7 - ], - "date_created": "2026-01-13", - "type": "ct", - "updateable": true, - "privileged": false, - "interface_port": 7476, - "documentation": "https://github.com/autobrr/qui", - "website": "https://github.com/autobrr/qui", - "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/qui.webp", - "config_path": "/root/.config/qui/config.toml", - "description": "Qui is a modern, self-hosted web interface for managing multiple qBittorrent instances with support for 10k+ torrents. It provides a clean and responsive interface for monitoring and controlling your qBittorrent downloads across multiple servers.", - "install_methods": [ - { - "type": "default", - "script": "ct/qui.sh", - "resources": { - "cpu": 1, - "ram": 1024, - "hdd": 10, - "os": "debian", - "version": "13" - } - } - ], - "default_credentials": { - "username": null, - "password": null - }, - "notes": [] -} diff --git a/install/qui-install.sh b/install/qui-install.sh deleted file mode 100644 index 8e45ed000..000000000 --- a/install/qui-install.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) 2021-2026 community-scripts ORG -# Author: MickLesk (Canbiz) -# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE -# Source: https://github.com/autobrr/qui - -source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" -color -verb_ip6 -catch_errors -setting_up_container -network_check -update_os - -fetch_and_deploy_gh_release "qui" "autobrr/qui" "prebuild" "latest" "/usr/local/bin" "qui_*_linux_x86_64.tar.gz" -chmod +x /usr/local/bin/qui -ln -sf /usr/local/bin/qui /usr/bin/qui -ln -sf /usr/local/bin/qui /opt/qui - -msg_info "Creating Qui Service" -cat </etc/systemd/system/qui.service -[Unit] -Description=Qui - qBittorrent Web UI -After=network-online.target -Wants=network-online.target - -[Service] -Type=simple -ExecStart=/usr/local/bin/qui serve -Restart=on-failure -RestartSec=5s - -[Install] -WantedBy=multi-user.target -EOF -systemctl enable -q --now qui -msg_ok "Created Qui Service" - -motd_ssh -customize -cleanup_lxc From 449a9366b4ddcd6b7ae316b5625574a96c7d55f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= Date: Wed, 14 Jan 2026 16:41:28 +0000 Subject: [PATCH 03/21] First test --- ct/flatnotes.sh | 59 ++++++++++++++++++++++++++++++++++++ install/flatnotes-install.sh | 23 ++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 ct/flatnotes.sh create mode 100644 install/flatnotes-install.sh diff --git a/ct/flatnotes.sh b/ct/flatnotes.sh new file mode 100644 index 000000000..202e65ecc --- /dev/null +++ b/ct/flatnotes.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +# Copyright (c) 2021-2026 community-scripts ORG +# Author: luismco +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/technomancer702/nodecast-tv + +APP="nodecast-tv" +var_tags="${var_tags:-media}" +var_cpu="${var_cpu:-2}" +var_ram="${var_ram:-2048}" +var_disk="${var_disk:-4}" +var_os="${var_os:-debian}" +var_version="${var_version:-13}" +var_unprivileged="${var_unprivileged:-1}" + +header_info "$APP" +variables +color +catch_errors + +function update_script() { + header_info + check_container_storage + check_container_resources + if [[ ! -d /opt/nodecast-tv ]]; then + msg_error "No ${APP} Installation Found!" + exit + fi + + if check_for_gh_release "nodecast-tv" "technomancer702/nodecast-tv"; then + msg_info "Stopping Service" + systemctl stop nodecast-tv + msg_ok "Stopped Service" + + fetch_and_deploy_gh_release "nodecast-tv" "technomancer702/nodecast-tv" + + msg_info "Updating Modules" + cd /opt/nodecast-tv + $STD npm install + msg_ok "Updated Modules" + + msg_info "Starting Service" + systemctl start nodecast-tv + msg_ok "Started Service" + msg_ok "Updated successfully!" + fi + exit +} + +start +build_container +description + +msg_ok "Completed successfully!\n" +echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" +echo -e "${INFO}${YW} Access it using the following URL:${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}" + diff --git a/install/flatnotes-install.sh b/install/flatnotes-install.sh new file mode 100644 index 000000000..1ae7d204d --- /dev/null +++ b/install/flatnotes-install.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2026 community-scripts ORG +# Author: luismco +# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE +# Source: https://github.com/technomancer702/nodecast-tv + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +fetch_and_deploy_gh_release "flatnotes" "dullage/flatnotes" +setup_uv +setup_nodejs + + +motd_ssh +customize +cleanup_lxc From 73381bf5e720a0605152cedf2e67492c0db4e9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= Date: Wed, 14 Jan 2026 16:45:01 +0000 Subject: [PATCH 04/21] Correct URLs --- ct/flatnotes.sh | 2 +- misc/build.func | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/flatnotes.sh b/ct/flatnotes.sh index 202e65ecc..0194e3276 100644 --- a/ct/flatnotes.sh +++ b/ct/flatnotes.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/heads/flatnotes/misc/build.func) # Copyright (c) 2021-2026 community-scripts ORG # Author: luismco # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE diff --git a/misc/build.func b/misc/build.func index 06923e925..45c2d6085 100644 --- a/misc/build.func +++ b/misc/build.func @@ -3419,7 +3419,7 @@ chmod +x /etc/profile.d/term.sh" || true set +Eeuo pipefail # Disable ALL error handling temporarily trap - ERR # Remove ERR trap completely - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/${var_install}.sh)" + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/heads/flatnotes/${var_install}.sh)" local lxc_exit=$? set -Eeuo pipefail # Re-enable error handling From 618fd89314ec8ad627422a4831a5c13104a0943a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= Date: Wed, 14 Jan 2026 17:36:12 +0000 Subject: [PATCH 05/21] install test --- install/flatnotes-install.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/install/flatnotes-install.sh b/install/flatnotes-install.sh index 1ae7d204d..84ae21265 100644 --- a/install/flatnotes-install.sh +++ b/install/flatnotes-install.sh @@ -14,9 +14,21 @@ network_check update_os fetch_and_deploy_gh_release "flatnotes" "dullage/flatnotes" -setup_uv +USE_UVX=YES setup_uv setup_nodejs +msg_info "Installing Backend" +cd /opt/flatnotes +$STD /usr/local/bin/uv sync +$STD source .venv/bin/activate +$STD deactivate +msg_ok "Installed Backend" + +msg_info "Installing Frontend" +cd /opt/flatnotes/client +$STD npm install +$STD npm run build +msg_ok "Installed Frontend" motd_ssh customize From d14c78c22974c41b289f3611d269d004167be8a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= <48201890+luismco@users.noreply.github.com> Date: Wed, 14 Jan 2026 16:47:44 +0000 Subject: [PATCH 06/21] Update flatnotes.sh --- ct/flatnotes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ct/flatnotes.sh b/ct/flatnotes.sh index 0194e3276..04fcba899 100644 --- a/ct/flatnotes.sh +++ b/ct/flatnotes.sh @@ -5,7 +5,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/he # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE # Source: https://github.com/technomancer702/nodecast-tv -APP="nodecast-tv" +APP="flatnotes" var_tags="${var_tags:-media}" var_cpu="${var_cpu:-2}" var_ram="${var_ram:-2048}" From c997ef089670db5503efa82b0052d40cc1a6260d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= <48201890+luismco@users.noreply.github.com> Date: Wed, 14 Jan 2026 16:55:04 +0000 Subject: [PATCH 07/21] Update build.func --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 45c2d6085..007f6353c 100644 --- a/misc/build.func +++ b/misc/build.func @@ -3419,7 +3419,7 @@ chmod +x /etc/profile.d/term.sh" || true set +Eeuo pipefail # Disable ALL error handling temporarily trap - ERR # Remove ERR trap completely - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/heads/flatnotes/${var_install}.sh)" + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/heads/flatnotes/install/${var_install}.sh)" local lxc_exit=$? set -Eeuo pipefail # Re-enable error handling From eff3633f1e8e8030f8603d0ef1d699888f7e21f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= Date: Wed, 14 Jan 2026 19:12:05 +0000 Subject: [PATCH 08/21] Backup and update configured --- ct/flatnotes.sh | 39 +++++++++++++++++++++++++++--------- install/flatnotes-install.sh | 38 +++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/ct/flatnotes.sh b/ct/flatnotes.sh index 04fcba899..0e618df28 100644 --- a/ct/flatnotes.sh +++ b/ct/flatnotes.sh @@ -5,7 +5,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/he # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE # Source: https://github.com/technomancer702/nodecast-tv -APP="flatnotes" +APP="Flatnotes" var_tags="${var_tags:-media}" var_cpu="${var_cpu:-2}" var_ram="${var_ram:-2048}" @@ -23,25 +23,44 @@ function update_script() { header_info check_container_storage check_container_resources - if [[ ! -d /opt/nodecast-tv ]]; then + if [[ ! -d /opt/flatnotes ]]; then msg_error "No ${APP} Installation Found!" exit fi - if check_for_gh_release "nodecast-tv" "technomancer702/nodecast-tv"; then + if check_for_gh_release "flatnotes" "dullage/flatnotes"; then msg_info "Stopping Service" - systemctl stop nodecast-tv + systemctl stop flatnotes msg_ok "Stopped Service" - fetch_and_deploy_gh_release "nodecast-tv" "technomancer702/nodecast-tv" + msg_info "Backing up Configuration and Data" + cp /opt/flatnotes/.env /tmp/flatnotes.env.bak + cp -r /opt/flatnotes/data /tmp/flatnotes/ + msg_ok "Backed up Configuration and Data" - msg_info "Updating Modules" - cd /opt/nodecast-tv + fetch_and_deploy_gh_release "flatnotes" "dullage/flatnotes" + + msg_info "Updating Frontend" + cd /opt/flatnotes/client $STD npm install - msg_ok "Updated Modules" + $STD npm run build + msg_ok "Updated Frontend" + + msg_info "Updating Backend" + cd /opt/flatnotes + $STD /usr/local/bin/uvx migrate-to-uv + $STD /usr/local/bin/uv sync + msg_ok "Updated Backend" + + msg_info "Restoring Configuration and Data" + cp /tmp/flatnotes.env.bak /opt/flatnotes/.env + cp -r /tmp/flatnotes/data /opt/flatnotes + rm -f /tmp/flatnotes.env.bak + rm -rf /tmp/flatnotes/data + msg_ok "Restored Configuration and Data" msg_info "Starting Service" - systemctl start nodecast-tv + systemctl start flatnotes msg_ok "Started Service" msg_ok "Updated successfully!" fi @@ -55,5 +74,5 @@ description msg_ok "Completed successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW} Access it using the following URL:${CL}" -echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}" +echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}" diff --git a/install/flatnotes-install.sh b/install/flatnotes-install.sh index 84ae21265..db5acf328 100644 --- a/install/flatnotes-install.sh +++ b/install/flatnotes-install.sh @@ -19,9 +19,9 @@ setup_nodejs msg_info "Installing Backend" cd /opt/flatnotes +$STD /usr/local/bin/uvx migrate-to-uv $STD /usr/local/bin/uv sync -$STD source .venv/bin/activate -$STD deactivate +mkdir data msg_ok "Installed Backend" msg_info "Installing Frontend" @@ -30,6 +30,40 @@ $STD npm install $STD npm run build msg_ok "Installed Frontend" +msg_info "Configuring Variables" +cat </opt/flatnotes/.env +FLATNOTES_AUTH_TYPE='none' +FLATNOTES_PATH='/opt/flatnotes/data/' +#FLATNOTES_USERNAME='username' +#FLATNOTES_PASSWORD='password' +#FLATNOTES_SECRET_KEY='secret-key' +EOF +msg_ok "Configured Variables" + +msg_info "Creating Service" +cat </etc/systemd/system/flatnotes.service +[Unit] +Description=Flatnotes +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/flatnotes +EnvironmentFile=/opt/flatnotes/.env +ExecStart=/opt/flatnotes/.venv/bin/python -m uvicorn main:app --app-dir server --host 0.0.0.0 --port 8080 --proxy-headers +Restart=on-failure +RestartSec=10 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now flatnotes +msg_ok "Created Service" + motd_ssh customize cleanup_lxc + + +$STD source .venv/bin/activate +$STD deactivate From 8f2b5ff9ee96714ffa0c22d81063755a5ce3d3d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= Date: Wed, 14 Jan 2026 19:16:49 +0000 Subject: [PATCH 09/21] deleted extra lines --- install/flatnotes-install.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/install/flatnotes-install.sh b/install/flatnotes-install.sh index db5acf328..8470e015b 100644 --- a/install/flatnotes-install.sh +++ b/install/flatnotes-install.sh @@ -63,7 +63,3 @@ msg_ok "Created Service" motd_ssh customize cleanup_lxc - - -$STD source .venv/bin/activate -$STD deactivate From a7a336452989ef1f942fd91f4c25a89017feb2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= Date: Wed, 14 Jan 2026 19:56:15 +0000 Subject: [PATCH 10/21] removes lock file before upgrading --- install/flatnotes-install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install/flatnotes-install.sh b/install/flatnotes-install.sh index 8470e015b..d480a7315 100644 --- a/install/flatnotes-install.sh +++ b/install/flatnotes-install.sh @@ -53,6 +53,7 @@ EnvironmentFile=/opt/flatnotes/.env ExecStart=/opt/flatnotes/.venv/bin/python -m uvicorn main:app --app-dir server --host 0.0.0.0 --port 8080 --proxy-headers Restart=on-failure RestartSec=10 +ExecStopPost=/bin/bash -c "rm -f /opt/flatnotes/uv.lock 2>/dev/null || true" [Install] WantedBy=multi-user.target From 74b4fa59db25794ae7a625be06ff511972da9e38 Mon Sep 17 00:00:00 2001 From: luismco Date: Thu, 15 Jan 2026 08:48:04 +0000 Subject: [PATCH 11/21] debugging update function --- ct/flatnotes.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ct/flatnotes.sh b/ct/flatnotes.sh index 0e618df28..7d96136c9 100644 --- a/ct/flatnotes.sh +++ b/ct/flatnotes.sh @@ -48,6 +48,7 @@ function update_script() { msg_info "Updating Backend" cd /opt/flatnotes + rm -f uv.lock $STD /usr/local/bin/uvx migrate-to-uv $STD /usr/local/bin/uv sync msg_ok "Updated Backend" From b0bc7bf03a6ac5215dfc055142dbebfa1e322816 Mon Sep 17 00:00:00 2001 From: luismco Date: Thu, 15 Jan 2026 09:26:39 +0000 Subject: [PATCH 12/21] final test install and update --- ct/flatnotes.sh | 20 ++++++++--------- frontend/public/json/flatnotes.json | 35 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 frontend/public/json/flatnotes.json diff --git a/ct/flatnotes.sh b/ct/flatnotes.sh index 7d96136c9..f420dddca 100644 --- a/ct/flatnotes.sh +++ b/ct/flatnotes.sh @@ -3,12 +3,12 @@ source <(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/he # Copyright (c) 2021-2026 community-scripts ORG # Author: luismco # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://github.com/technomancer702/nodecast-tv +# Source: https://github.com/dullage/flatnotes APP="Flatnotes" -var_tags="${var_tags:-media}" -var_cpu="${var_cpu:-2}" -var_ram="${var_ram:-2048}" +var_tags="${var_tags:-notes}" +var_cpu="${var_cpu:-1}" +var_ram="${var_ram:-1024}" var_disk="${var_disk:-4}" var_os="${var_os:-debian}" var_version="${var_version:-13}" @@ -34,8 +34,8 @@ function update_script() { msg_ok "Stopped Service" msg_info "Backing up Configuration and Data" - cp /opt/flatnotes/.env /tmp/flatnotes.env.bak - cp -r /opt/flatnotes/data /tmp/flatnotes/ + cp /opt/flatnotes/.env /opt/.env.bak + cp -r /opt/flatnotes/data /opt/data_backup msg_ok "Backed up Configuration and Data" fetch_and_deploy_gh_release "flatnotes" "dullage/flatnotes" @@ -54,10 +54,10 @@ function update_script() { msg_ok "Updated Backend" msg_info "Restoring Configuration and Data" - cp /tmp/flatnotes.env.bak /opt/flatnotes/.env - cp -r /tmp/flatnotes/data /opt/flatnotes - rm -f /tmp/flatnotes.env.bak - rm -rf /tmp/flatnotes/data + cp /opt/.env.bak /opt/flatnotes/.env + cp -r /opt/data_backup /opt/flatnotes/data + rm -f /opt/.env.bak + rm -rf /opt/flatnotes/data_backup msg_ok "Restored Configuration and Data" msg_info "Starting Service" diff --git a/frontend/public/json/flatnotes.json b/frontend/public/json/flatnotes.json new file mode 100644 index 000000000..bd45d3d51 --- /dev/null +++ b/frontend/public/json/flatnotes.json @@ -0,0 +1,35 @@ +{ + "name": "Flatnotes", + "slug": "flatnotes", + "categories": [ + 12 + ], + "date_created": "2026-01-15", + "type": "ct", + "updateable": true, + "privileged": false, + "interface_port": 8080, + "documentation": "https://github.com/dullage/flatnotes/wiki", + "website": "https://github.com/dullage/flatnotes", + "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/flatnotes.webp", + "config_path": "/opt/flatnotes/.env", + "description": "A self-hosted, database-less note-taking web app that utilises a flat folder of markdown files for storage.", + "install_methods": [ + { + "type": "default", + "script": "ct/flatnotes.sh", + "resources": { + "cpu": 1, + "ram": 1024, + "hdd": 4, + "os": "debian", + "version": "13" + } + } + ], + "default_credentials": { + "username": null, + "password": null + }, + "notes": [] +} From 369d12eb28ecd65f0d34ecd1a209e099c42f21bf Mon Sep 17 00:00:00 2001 From: luismco Date: Thu, 15 Jan 2026 09:41:13 +0000 Subject: [PATCH 13/21] Adjust to service --- install/flatnotes-install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/install/flatnotes-install.sh b/install/flatnotes-install.sh index d480a7315..8470e015b 100644 --- a/install/flatnotes-install.sh +++ b/install/flatnotes-install.sh @@ -53,7 +53,6 @@ EnvironmentFile=/opt/flatnotes/.env ExecStart=/opt/flatnotes/.venv/bin/python -m uvicorn main:app --app-dir server --host 0.0.0.0 --port 8080 --proxy-headers Restart=on-failure RestartSec=10 -ExecStopPost=/bin/bash -c "rm -f /opt/flatnotes/uv.lock 2>/dev/null || true" [Install] WantedBy=multi-user.target From defaa643de7fe0a741d686f47be039a79bf539da Mon Sep 17 00:00:00 2001 From: luismco Date: Thu, 15 Jan 2026 09:52:45 +0000 Subject: [PATCH 14/21] backup and restore changes --- ct/flatnotes.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/flatnotes.sh b/ct/flatnotes.sh index f420dddca..e296ba1dd 100644 --- a/ct/flatnotes.sh +++ b/ct/flatnotes.sh @@ -55,9 +55,9 @@ function update_script() { msg_info "Restoring Configuration and Data" cp /opt/.env.bak /opt/flatnotes/.env - cp -r /opt/data_backup /opt/flatnotes/data + cp -r /opt/data_backup/. /opt/flatnotes/data rm -f /opt/.env.bak - rm -rf /opt/flatnotes/data_backup + rm -r /opt/data_backup msg_ok "Restored Configuration and Data" msg_info "Starting Service" From 3b609a31fc2d73a879941c328938fc14afd18125 Mon Sep 17 00:00:00 2001 From: luismco Date: Thu, 15 Jan 2026 10:13:12 +0000 Subject: [PATCH 15/21] Ready for PR --- ct/flatnotes.sh | 2 +- install/flatnotes-install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ct/flatnotes.sh b/ct/flatnotes.sh index e296ba1dd..01b8e0f27 100644 --- a/ct/flatnotes.sh +++ b/ct/flatnotes.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -source <(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/heads/flatnotes/misc/build.func) +source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func) # Copyright (c) 2021-2026 community-scripts ORG # Author: luismco # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE diff --git a/install/flatnotes-install.sh b/install/flatnotes-install.sh index 8470e015b..2ea64e0ba 100644 --- a/install/flatnotes-install.sh +++ b/install/flatnotes-install.sh @@ -3,7 +3,7 @@ # Copyright (c) 2021-2026 community-scripts ORG # Author: luismco # License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE -# Source: https://github.com/technomancer702/nodecast-tv +# Source: https://github.com/dullage/flatnotes source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color From 04386cd5b706678c6c6ecf06473338806c4ae4a0 Mon Sep 17 00:00:00 2001 From: luismco Date: Thu, 15 Jan 2026 10:14:53 +0000 Subject: [PATCH 16/21] Ready for PR --- misc/build.func | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/build.func b/misc/build.func index 007f6353c..06923e925 100644 --- a/misc/build.func +++ b/misc/build.func @@ -3419,7 +3419,7 @@ chmod +x /etc/profile.d/term.sh" || true set +Eeuo pipefail # Disable ALL error handling temporarily trap - ERR # Remove ERR trap completely - lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://raw.githubusercontent.com/luismco/ProxmoxVED/refs/heads/flatnotes/install/${var_install}.sh)" + lxc-attach -n "$CTID" -- bash -c "$(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main/install/${var_install}.sh)" local lxc_exit=$? set -Eeuo pipefail # Re-enable error handling From 8b404191e896639ebce44ef083b9edca9c46da16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= <48201890+luismco@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:54:36 +0000 Subject: [PATCH 17/21] Update flatnotes.sh --- ct/flatnotes.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ct/flatnotes.sh b/ct/flatnotes.sh index 01b8e0f27..8fd2aa101 100644 --- a/ct/flatnotes.sh +++ b/ct/flatnotes.sh @@ -34,8 +34,8 @@ function update_script() { msg_ok "Stopped Service" msg_info "Backing up Configuration and Data" - cp /opt/flatnotes/.env /opt/.env.bak - cp -r /opt/flatnotes/data /opt/data_backup + cp /opt/flatnotes/.env /opt/flatnotes.env + cp -r /opt/flatnotes/data /opt/flatnotes_data_backup msg_ok "Backed up Configuration and Data" fetch_and_deploy_gh_release "flatnotes" "dullage/flatnotes" @@ -54,10 +54,10 @@ function update_script() { msg_ok "Updated Backend" msg_info "Restoring Configuration and Data" - cp /opt/.env.bak /opt/flatnotes/.env - cp -r /opt/data_backup/. /opt/flatnotes/data - rm -f /opt/.env.bak - rm -r /opt/data_backup + cp /opt/flatnotes.env /opt/flatnotes/.env + cp -r /opt/flatnotes_data_backup/. /opt/flatnotes/data + rm -f /opt/flatnotes.env + rm -r /opt/flatnotes_data_backup msg_ok "Restored Configuration and Data" msg_info "Starting Service" From c7e8652d67370d88d2dfc6dfca018c05577bef11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Oliveira?= <48201890+luismco@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:55:16 +0000 Subject: [PATCH 18/21] Apply suggestions from code review Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com> --- install/flatnotes-install.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/install/flatnotes-install.sh b/install/flatnotes-install.sh index 2ea64e0ba..ee7a93ed0 100644 --- a/install/flatnotes-install.sh +++ b/install/flatnotes-install.sh @@ -21,7 +21,7 @@ msg_info "Installing Backend" cd /opt/flatnotes $STD /usr/local/bin/uvx migrate-to-uv $STD /usr/local/bin/uv sync -mkdir data +mkdir /opt/flatnotes/data msg_ok "Installed Backend" msg_info "Installing Frontend" @@ -30,7 +30,8 @@ $STD npm install $STD npm run build msg_ok "Installed Frontend" -msg_info "Configuring Variables" + +msg_info "Creating Service" cat </opt/flatnotes/.env FLATNOTES_AUTH_TYPE='none' FLATNOTES_PATH='/opt/flatnotes/data/' @@ -38,9 +39,6 @@ FLATNOTES_PATH='/opt/flatnotes/data/' #FLATNOTES_PASSWORD='password' #FLATNOTES_SECRET_KEY='secret-key' EOF -msg_ok "Configured Variables" - -msg_info "Creating Service" cat </etc/systemd/system/flatnotes.service [Unit] Description=Flatnotes From 92ffad8a604c131b5eecb677eaf07bdba974de1d Mon Sep 17 00:00:00 2001 From: MintHCM <51930758+MintHCM-admin@users.noreply.github.com> Date: Thu, 15 Jan 2026 15:22:28 +0100 Subject: [PATCH 19/21] Update install/minthcm-install.sh Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com> --- install/minthcm-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/minthcm-install.sh b/install/minthcm-install.sh index ed5752da0..090a31135 100644 --- a/install/minthcm-install.sh +++ b/install/minthcm-install.sh @@ -13,7 +13,7 @@ setting_up_container network_check update_os PHP_VERSION="8.2" -PHP_APACHE="YES" PHP_VERSION="8.2" PHP_MODULE="mysql,cli,redis" PHP_FPM="YES" setup_php +PHP_APACHE="YES" PHP_MODULE="mysql,cli,redis" PHP_FPM="YES" setup_php setup_composer msg_info "Enabling Apache modules (rewrite, headers)" From b92931f6ee614d0f7ed508f2455377e96c8eee56 Mon Sep 17 00:00:00 2001 From: vhsdream Date: Thu, 15 Jan 2026 22:50:31 -0500 Subject: [PATCH 20/21] nextExplorer: disable shell for user; fix version display --- ct/nextexplorer.sh | 1 + install/nextexplorer-install.sh | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ct/nextexplorer.sh b/ct/nextexplorer.sh index 6b2b651b4..27fcf564f 100644 --- a/ct/nextexplorer.sh +++ b/ct/nextexplorer.sh @@ -54,6 +54,7 @@ function update_script() { mv backend/{node_modules,src,package.json} "$APP_DIR" mv frontend/dist/ "$APP_DIR"/src/public chown -R explorer:explorer "$APP_DIR" /etc/nextExplorer + sed -i "\|version|s|$(jq -cr '.version' ${APP_DIR}/package.json)|$(cat ~/.nextexplorer)|" "$APP_DIR"/package.json msg_ok "Updated nextExplorer" msg_info "Starting nextExplorer" diff --git a/install/nextexplorer-install.sh b/install/nextexplorer-install.sh index 8ed03263a..940cdec67 100644 --- a/install/nextexplorer-install.sh +++ b/install/nextexplorer-install.sh @@ -119,8 +119,9 @@ SHARES_ENABLED=true # SHARES_ALLOW_ANONYMOUS=true EOF chmod 600 /etc/nextExplorer/.env -$STD useradd -U -s /bin/bash -m -d /home/explorer explorer +$STD useradd -U -s /usr/sbin/nologin -m -d /home/explorer explorer chown -R explorer:explorer "$APP_DIR" /etc/nextExplorer +sed -i "\|version|s|$(jq -cr '.version' ${APP_DIR}/package.json)|$(cat ~/.nextexplorer)|" "$APP_DIR"/package.json msg_ok "Configured nextExplorer" msg_info "Creating nextExplorer Service" @@ -131,6 +132,8 @@ After=network.target [Service] Type=simple +User=explorer +Group=explorer WorkingDirectory=/opt/nextExplorer/app EnvironmentFile=/etc/nextExplorer/.env ExecStart=/usr/bin/node ./src/app.js From 6c2322443c75190bc744df4d17f359edf86ccadd Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Fri, 16 Jan 2026 08:33:01 +0100 Subject: [PATCH 21/21] Add workflow to update version sources and fetch versions This workflow automates the extraction of version sources from install scripts, fetches their versions, and generates a pull request if changes are detected in version information. --- .github/workflows/update-versions-github.yml | 512 +++++++++++++++++++ 1 file changed, 512 insertions(+) create mode 100644 .github/workflows/update-versions-github.yml diff --git a/.github/workflows/update-versions-github.yml b/.github/workflows/update-versions-github.yml new file mode 100644 index 000000000..5c18ef2e5 --- /dev/null +++ b/.github/workflows/update-versions-github.yml @@ -0,0 +1,512 @@ +name: Update Versions from GitHub + +on: + workflow_dispatch: + schedule: + # Runs at 06:00 and 18:00 UTC + - cron: "0 6,18 * * *" + +permissions: + contents: write + pull-requests: write + +env: + SOURCES_FILE: frontend/public/json/version-sources.json + VERSIONS_FILE: frontend/public/json/versions.json + +jobs: + update-versions: + if: github.repository == 'community-scripts/ProxmoxVE' + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + ref: main + + - name: Generate GitHub App Token + id: generate-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Extract version sources from install scripts + run: | + set -euo pipefail + + echo "=========================================" + echo " Extracting version sources from scripts" + echo "=========================================" + + # Initialize sources array + sources_json="[]" + + # Function to add a source entry + add_source() { + local slug="$1" + local type="$2" + local source="$3" + local script="$4" + + # Check if slug already exists (avoid duplicates) + if echo "$sources_json" | jq -e ".[] | select(.slug == \"$slug\")" > /dev/null 2>&1; then + return + fi + + sources_json=$(echo "$sources_json" | jq \ + --arg slug "$slug" \ + --arg type "$type" \ + --arg source "$source" \ + --arg script "$script" \ + '. += [{"slug": $slug, "type": $type, "source": $source, "script": $script, "version": null, "date": null}]') + } + + echo "" + echo "=== Method 1: fetch_and_deploy_gh_release calls ===" + count=0 + for script in install/*-install.sh; do + [[ ! -f "$script" ]] && continue + slug=$(basename "$script" | sed 's/-install\.sh$//') + + # Extract repo from fetch_and_deploy_gh_release "app" "owner/repo" + while IFS= read -r line; do + if [[ "$line" =~ fetch_and_deploy_gh_release[[:space:]]+\"[^\"]*\"[[:space:]]+\"([^\"]+)\" ]]; then + repo="${BASH_REMATCH[1]}" + add_source "$slug" "github" "$repo" "$script" + ((count++)) + break # Only first match per script + fi + done < <(grep 'fetch_and_deploy_gh_release' "$script" 2>/dev/null || true) + done + echo "Found $count scripts with fetch_and_deploy_gh_release" + + echo "" + echo "=== Method 2: GitHub URLs in scripts (fallback) ===" + count=0 + for script in install/*-install.sh; do + [[ ! -f "$script" ]] && continue + slug=$(basename "$script" | sed 's/-install\.sh$//') + + # Skip if already found + if echo "$sources_json" | jq -e ".[] | select(.slug == \"$slug\")" > /dev/null 2>&1; then + continue + fi + + # Look for github.com/owner/repo patterns + repo=$(grep -oE 'github\.com/([a-zA-Z0-9_-]+/[a-zA-Z0-9_.-]+)' "$script" 2>/dev/null \ + | sed 's|github\.com/||' \ + | sed 's/\.git$//' \ + | grep -v 'community-scripts/ProxmoxVE' \ + | grep -v '^repos/' \ + | head -1 || true) + + if [[ -n "$repo" && "$repo" =~ ^[a-zA-Z0-9_-]+/[a-zA-Z0-9_.-]+$ ]]; then + add_source "$slug" "github" "$repo" "$script" + ((count++)) + fi + done + echo "Found $count additional scripts with GitHub URLs" + + echo "" + echo "=== Method 3: npm packages ===" + # Detect npm install --global + for script in install/*-install.sh; do + [[ ! -f "$script" ]] && continue + slug=$(basename "$script" | sed 's/-install\.sh$//') + + # Skip if already found + if echo "$sources_json" | jq -e ".[] | select(.slug == \"$slug\")" > /dev/null 2>&1; then + continue + fi + + # Look for npm install --global + pkg=$(grep -oE 'npm install[^|;]*--global[^|;]*' "$script" 2>/dev/null \ + | grep -oE '\s[a-z][a-z0-9_-]+(@[^\s]+)?$' \ + | tr -d ' ' \ + | sed 's/@.*//' \ + | tail -1 || true) + + if [[ -n "$pkg" ]]; then + add_source "$slug" "npm" "$pkg" "$script" + fi + done + + echo "" + echo "=== Method 4: Docker images ===" + # Known Docker-based apps (from docker pull or docker run) + declare -A docker_mappings=( + ["homeassistant"]="homeassistant/home-assistant" + ["portainer"]="portainer/portainer-ce" + ["dockge"]="louislam/dockge" + ["immich"]="ghcr.io/immich-app/immich-server" + ["audiobookshelf"]="ghcr.io/advplyr/audiobookshelf" + ["podman-homeassistant"]="homeassistant/home-assistant" + ) + + for slug in "${!docker_mappings[@]}"; do + image="${docker_mappings[$slug]}" + if ! echo "$sources_json" | jq -e ".[] | select(.slug == \"$slug\")" > /dev/null 2>&1; then + add_source "$slug" "docker" "$image" "install/${slug}-install.sh" + fi + done + + echo "" + echo "=== Method 5: Manual GitHub mappings (apt-based apps) ===" + # Apps that install via apt but have GitHub releases for version tracking + declare -A manual_github_mappings=( + ["actualbudget"]="actualbudget/actual" + ["apache-cassandra"]="apache/cassandra" + ["apache-couchdb"]="apache/couchdb" + ["apache-guacamole"]="apache/guacamole-server" + ["apache-tomcat"]="apache/tomcat" + ["archivebox"]="ArchiveBox/ArchiveBox" + ["aria2"]="aria2/aria2" + ["asterisk"]="asterisk/asterisk" + ["casaos"]="IceWhaleTech/CasaOS" + ["checkmk"]="Checkmk/checkmk" + ["cloudflared"]="cloudflare/cloudflared" + ["coolify"]="coollabsio/coolify" + ["crafty-controller"]="crafty-controller/crafty-4" + ["cross-seed"]="cross-seed/cross-seed" + ["deconz"]="dresden-elektronik/deconz-rest-plugin" + ["deluge"]="deluge-torrent/deluge" + ["dokploy"]="Dokploy/dokploy" + ["emqx"]="emqx/emqx" + ["esphome"]="esphome/esphome" + ["flowiseai"]="FlowiseAI/Flowise" + ["forgejo"]="forgejo/forgejo" + ["garage"]="deuxfleurs-org/garage" + ["ghost"]="TryGhost/Ghost" + ["grafana"]="grafana/grafana" + ["graylog"]="Graylog2/graylog2-server" + ["homebridge"]="homebridge/homebridge" + ["hyperhdr"]="awawa-dev/HyperHDR" + ["hyperion"]="hyperion-project/hyperion.ng" + ["influxdb"]="influxdata/influxdb" + ["iobroker"]="ioBroker/ioBroker" + ["jenkins"]="jenkinsci/jenkins" + ["komodo"]="moghingold/komodo" + ["lazylibrarian"]="lazylibrarian/LazyLibrarian" + ["limesurvey"]="LimeSurvey/LimeSurvey" + ["mariadb"]="MariaDB/server" + ["mattermost"]="mattermost/mattermost" + ["meshcentral"]="Ylianst/MeshCentral" + ["metabase"]="metabase/metabase" + ["mongodb"]="mongodb/mongo" + ["mysql"]="mysql/mysql-server" + ["neo4j"]="neo4j/neo4j" + ["node-red"]="node-red/node-red" + ["ntfy"]="binwiederhier/ntfy" + ["nzbget"]="nzbgetcom/nzbget" + ["octoprint"]="OctoPrint/OctoPrint" + ["onedev"]="theonedev/onedev" + ["onlyoffice"]="ONLYOFFICE/DocumentServer" + ["openhab"]="openhab/openhab-distro" + ["openobserve"]="openobserve/openobserve" + ["openwebui"]="open-webui/open-webui" + ["passbolt"]="passbolt/passbolt_api" + ["pihole"]="pi-hole/pi-hole" + ["postgresql"]="postgres/postgres" + ["rabbitmq"]="rabbitmq/rabbitmq-server" + ["readarr"]="Readarr/Readarr" + ["redis"]="redis/redis" + ["runtipi"]="runtipi/runtipi" + ["sftpgo"]="drakkan/sftpgo" + ["shinobi"]="ShinobiCCTV/Shinobi" + ["sonarqube"]="SonarSource/sonarqube" + ["sonarr"]="Sonarr/Sonarr" + ["syncthing"]="syncthing/syncthing" + ["tdarr"]="HaveAGitGat/Tdarr" + ["technitiumdns"]="TechnitiumSoftware/DnsServer" + ["transmission"]="transmission/transmission" + ["typesense"]="typesense/typesense" + ["unmanic"]="Unmanic/unmanic" + ["valkey"]="valkey-io/valkey" + ["verdaccio"]="verdaccio/verdaccio" + ["vikunja"]="go-vikunja/vikunja" + ["wazuh"]="wazuh/wazuh" + ["wordpress"]="WordPress/WordPress" + ["zabbix"]="zabbix/zabbix" + ["zammad"]="zammad/zammad" + ["zerotier-one"]="zerotier/ZeroTierOne" + # Apps without known GitHub repos (use "-" as placeholder) + ["agentdvr"]="-" + ["apt-cacher-ng"]="-" + ["channels"]="-" + ["daemonsync"]="-" + ["dotnetaspwebapi"]="-" + ["fhem"]="-" + ["fileflows"]="-" + ["fumadocs"]="-" + ["infisical"]="-" + ["itsm-ng"]="-" + ["jupyternotebook"]="-" + ["kasm"]="-" + ["lyrionmusicserver"]="-" + ["minarca"]="-" + ["mqtt"]="-" + ["nextcloudpi"]="-" + ["nextpvr"]="-" + ["notifiarr"]="-" + ["nxwitness"]="-" + ["omada"]="-" + ["omv"]="-" + ["plex"]="-" + ["podman"]="-" + ["readeck"]="-" + ["resiliosync"]="-" + ["smokeping"]="-" + ["splunk-enterprise"]="-" + ["sqlserver2022"]="-" + ["swizzin"]="-" + ["teamspeak-server"]="-" + ["twingate-connector"]="-" + ["unifi"]="-" + ["urbackupserver"]="-" + ["yunohost"]="-" + ) + + for slug in "${!manual_github_mappings[@]}"; do + repo="${manual_github_mappings[$slug]}" + if ! echo "$sources_json" | jq -e ".[] | select(.slug == \"$slug\")" > /dev/null 2>&1; then + # Skip placeholder entries in extraction, they get added in Method 8 + [[ "$repo" == "-" ]] && continue + add_source "$slug" "github" "$repo" "install/${slug}-install.sh" + fi + done + + echo "" + echo "=== Method 6: Proxmox LXC templates ===" + # Base OS versions from Proxmox template index + declare -A pveam_mappings=( + ["debian"]="pveam:debian" + ["ubuntu"]="pveam:ubuntu" + ["alpine"]="pveam:alpine" + ) + + for slug in "${!pveam_mappings[@]}"; do + template="${pveam_mappings[$slug]}" + if ! echo "$sources_json" | jq -e ".[] | select(.slug == \"$slug\")" > /dev/null 2>&1; then + add_source "$slug" "pveam" "$template" "ct/${slug}.sh" + fi + done + + echo "" + echo "=== Method 7: Special sources ===" + # Home Assistant OS VM + if ! echo "$sources_json" | jq -e ".[] | select(.slug == \"haos-vm\")" > /dev/null 2>&1; then + add_source "haos-vm" "github" "home-assistant/operating-system" "vm/haos-vm.sh" + fi + + echo "" + echo "=== Method 8: Unknown/Manual apps ===" + # Apps without known version sources - add with type "manual" for manual updates + unknown_apps=( + "agentdvr" "apt-cacher-ng" "channels" "daemonsync" "dotnetaspwebapi" + "fhem" "fileflows" "fumadocs" "infisical" "itsm-ng" "jupyternotebook" + "kasm" "lyrionmusicserver" "minarca" "mqtt" "nextcloudpi" "nextpvr" + "notifiarr" "nxwitness" "omada" "omv" "plex" "podman" "readeck" + "resiliosync" "smokeping" "splunk-enterprise" "sqlserver2022" "swizzin" + "teamspeak-server" "twingate-connector" "unifi" "urbackupserver" "yunohost" + ) + + for slug in "${unknown_apps[@]}"; do + if ! echo "$sources_json" | jq -e ".[] | select(.slug == \"$slug\")" > /dev/null 2>&1; then + add_source "$slug" "manual" "-" "install/${slug}-install.sh" + fi + done + + # Save sources file + echo "$sources_json" | jq --arg date "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ + '{generated: $date, sources: (. | sort_by(.slug))}' > "$SOURCES_FILE" + + total=$(echo "$sources_json" | jq 'length') + echo "" + echo "=========================================" + echo " Total sources extracted: $total" + echo "=========================================" + + - name: Fetch versions for all sources + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + set -euo pipefail + + echo "=========================================" + echo " Fetching versions from sources" + echo "=========================================" + + success=0 + failed=0 + manual=0 + total=$(jq '.sources | length' "$SOURCES_FILE") + + # Process each source + for i in $(seq 0 $((total - 1))); do + entry=$(jq -r ".sources[$i]" "$SOURCES_FILE") + slug=$(echo "$entry" | jq -r '.slug') + type=$(echo "$entry" | jq -r '.type') + source=$(echo "$entry" | jq -r '.source') + + echo -n "[$((i+1))/$total] $slug ($type: $source) ... " + + version="" + date="" + + case "$type" in + github) + # Try releases first + response=$(gh api "repos/${source}/releases/latest" 2>/dev/null || echo '{"message": "Not Found"}') + + if echo "$response" | jq -e '.tag_name' > /dev/null 2>&1; then + version=$(echo "$response" | jq -r '.tag_name') + date=$(echo "$response" | jq -r '.published_at // empty') + else + # Fallback to tags + version=$(gh api "repos/${source}/tags" --jq '.[0].name // empty' 2>/dev/null || echo "") + fi + ;; + + npm) + response=$(curl -fsSL "https://registry.npmjs.org/${source}/latest" 2>/dev/null || echo '{}') + version=$(echo "$response" | jq -r '.version // empty') + ;; + + docker) + if [[ "$source" == ghcr.io/* ]]; then + # GitHub Container Registry + ghcr_path="${source#ghcr.io/}" + owner="${ghcr_path%%/*}" + pkg="${ghcr_path##*/}" + version=$(gh api "users/${owner}/packages/container/${pkg}/versions" --jq '.[0].metadata.container.tags[] | select(. != "latest")' 2>/dev/null | head -1 || echo "") + else + # Docker Hub + version=$(curl -fsSL "https://hub.docker.com/v2/repositories/${source}/tags?page_size=10&ordering=last_updated" 2>/dev/null \ + | jq -r '.results[] | select(.name != "latest") | .name' | head -1 || echo "") + fi + ;; + + pveam) + # Proxmox LXC template versions from download.proxmox.com + os_name="${source#pveam:}" + # Fetch the template index and get latest version + version=$(curl -fsSL "http://download.proxmox.com/images/system/" 2>/dev/null \ + | grep -oE "${os_name}-[0-9]+\.[0-9]+-default_[0-9]+_amd64" \ + | sed "s/${os_name}-//" | sed 's/-default.*//' \ + | sort -V | tail -1 || echo "") + ;; + + manual) + # Manual entries - no automatic version fetching + # These need to be updated manually or have their source type changed + version="-" + ((manual++)) + echo -n "(manual) " + ;; + esac + + if [[ -n "$version" && "$version" != "null" ]]; then + # Update the source entry with version + jq --arg idx "$i" --arg version "$version" --arg date "${date:-}" \ + '.sources[$idx | tonumber].version = $version | .sources[$idx | tonumber].date = $date' \ + "$SOURCES_FILE" > "${SOURCES_FILE}.tmp" && mv "${SOURCES_FILE}.tmp" "$SOURCES_FILE" + echo "✓ $version" + ((success++)) + else + echo "⚠ no version found" + ((failed++)) + fi + done + + echo "" + echo "=========================================" + echo " SUMMARY" + echo "=========================================" + echo "Success: $success (automated)" + echo "Manual: $manual (placeholder)" + echo "Failed: $failed" + echo "Total: $total" + echo "=========================================" + + - name: Generate versions.json for compatibility + run: | + # Convert version-sources.json to versions.json format for backward compatibility + jq '[.sources[] | select(.version != null) | {name: .source, version: .version, date: .date}]' \ + "$SOURCES_FILE" > "$VERSIONS_FILE" + + echo "Generated versions.json with $(jq length "$VERSIONS_FILE") entries" + + - name: Check for changes + id: check-changes + run: | + if git diff --quiet "$SOURCES_FILE" "$VERSIONS_FILE" 2>/dev/null; then + echo "changed=false" >> "$GITHUB_OUTPUT" + echo "No changes detected" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + echo "Changes detected:" + git diff --stat "$SOURCES_FILE" "$VERSIONS_FILE" 2>/dev/null || true + fi + + - name: Create Pull Request + if: steps.check-changes.outputs.changed == 'true' + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + BRANCH_NAME="automated/update-versions-$(date +%Y%m%d)" + + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "GitHub Actions[bot]" + + # Check if branch exists and delete it + git push origin --delete "$BRANCH_NAME" 2>/dev/null || true + + git checkout -b "$BRANCH_NAME" + git add "$SOURCES_FILE" "$VERSIONS_FILE" + git commit -m "chore: update version-sources.json and versions.json + + Sources: $(jq '.sources | length' "$SOURCES_FILE") + With versions: $(jq '[.sources[] | select(.version != null)] | length' "$SOURCES_FILE") + Generated: $(jq -r '.generated' "$SOURCES_FILE")" + + git push origin "$BRANCH_NAME" --force + + # Check if PR already exists + existing_pr=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number // empty') + + if [[ -n "$existing_pr" ]]; then + echo "PR #$existing_pr already exists, updating..." + else + gh pr create \ + --title "[Automated] Update version-sources.json" \ + --body "This PR updates version information from multiple sources. + + ## Sources + - **GitHub Releases**: Direct from \`fetch_and_deploy_gh_release\` calls + - **GitHub URLs**: Extracted from install scripts + - **npm Registry**: For Node.js based apps + - **Docker Hub/GHCR**: For container-based apps + + ## Stats + - Total sources: $(jq '.sources | length' "$SOURCES_FILE") + - With versions: $(jq '[.sources[] | select(.version != null)] | length' "$SOURCES_FILE") + + --- + *Automatically generated from install scripts*" \ + --base main \ + --head "$BRANCH_NAME" \ + --label "automated pr" + fi + + - name: Auto-approve PR + if: steps.check-changes.outputs.changed == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + BRANCH_NAME="automated/update-versions-$(date +%Y%m%d)" + pr_number=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number') + if [[ -n "$pr_number" ]]; then + gh pr review "$pr_number" --approve + fi