From 8800f524d4451f220721f038ab9c5c873ccddbee Mon Sep 17 00:00:00 2001 From: librelad Date: Mon, 25 May 2026 21:02:53 +0100 Subject: [PATCH] feat(tools): WebUI/CLI publish tool for getlibreportal + weblibreportal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surface the publish step through the existing Tools system (apps-tools.json -> Tools tab + 'libreportal app tool publish'), so the docroot can be (re)built from the WebUI instead of a manual cd + script. - webui_tools.sh: declare a 'publish' tool (no inputs) for getlibreportal + weblibreportal. - scripts/app/containers/getlibreportal/getlibreportal_publish.sh (appGetlibreportalPublish): runs the host's publish.sh into the served data dir, as the container user (owns it). - scripts/app/containers/weblibreportal/weblibreportal_publish.sh (appWeblibreportalPublish): builds Eleventy as the manager (owns the install tree), then syncs the result into the container-user-owned docroot — handling the build-vs-write owner split. - Both guard for the build prerequisites (repo source / npm / dist) and fail with a clear message; regenerated the sourced-file arrays. Honest status: scaffolding only — wiring verified (dispatch names match, files sourced, JSON valid) but the end-to-end tool RUN is untested, and it's build-box-only (needs the repo checkout + npm + a built dist/). These hosting apps are dev-only and headed for a separate repo; this just sets the automation up so it's ready to iterate on. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- .../getlibreportal/getlibreportal_publish.sh | 23 ++++++++++++++++ .../weblibreportal/weblibreportal_publish.sh | 27 +++++++++++++++++++ scripts/source/files/arrays/files_app.sh | 2 ++ .../webui/data/generators/apps/webui_tools.sh | 22 +++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 scripts/app/containers/getlibreportal/getlibreportal_publish.sh create mode 100644 scripts/app/containers/weblibreportal/weblibreportal_publish.sh diff --git a/scripts/app/containers/getlibreportal/getlibreportal_publish.sh b/scripts/app/containers/getlibreportal/getlibreportal_publish.sh new file mode 100644 index 0000000..4605068 --- /dev/null +++ b/scripts/app/containers/getlibreportal/getlibreportal_publish.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Tool: getlibreportal "publish" — assemble the download host's docroot +# (install.sh + the dist/ release artifacts) into its served data dir. +# Runs as the container user (it owns the data dir); reads the manager-owned +# install tree. Build-box only — needs a populated dist/ (run make_release first). +appGetlibreportalPublish() +{ + isHeader "Publish downloads (getlibreportal)" + local app=getlibreportal + local pub="${install_containers_dir}${app}/publish.sh" + local data="${containers_dir}${app}/data" + + [[ -f "$pub" ]] || { isError "publish.sh not found at $pub — full repo checkout needed."; return 1; } + + runFileOp mkdir -p "$data" + if runFileOp bash "$pub" "$data"; then + isSuccessful "Downloads published. Restart $app to serve it." + else + isError "Publish failed (is dist/ present? run scripts/release/make_release.sh first)." + return 1 + fi +} diff --git a/scripts/app/containers/weblibreportal/weblibreportal_publish.sh b/scripts/app/containers/weblibreportal/weblibreportal_publish.sh new file mode 100644 index 0000000..e66aa92 --- /dev/null +++ b/scripts/app/containers/weblibreportal/weblibreportal_publish.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Tool: weblibreportal "publish" — build the Eleventy website and publish it into +# the served data dir. The build runs as the manager (owns the install tree where +# the source + node build live); the result is synced into the container-user-owned +# docroot. Build-box only — needs the repo checkout + npm. +appWeblibreportalPublish() +{ + isHeader "Publish website (weblibreportal)" + local app=weblibreportal + local appdir="${install_containers_dir}${app}" + local data="${containers_dir}${app}/data" + + command -v npm >/dev/null 2>&1 || { isError "npm not found — publishing the website needs a dev/build box."; return 1; } + [[ -f "$appdir/package.json" ]] || { isError "website source not at $appdir — full repo checkout needed."; return 1; } + + isNotice "Building the site (Eleventy)..." + if ! ( cd "$appdir" && runInstallOp npm install --silent && runInstallOp npm run build ); then + isError "Site build failed." + return 1 + fi + + isNotice "Publishing into the docroot..." + runFileOp mkdir -p "$data" + runFileOp sh -c "rm -rf \"$data\"/* \"$data\"/.??* 2>/dev/null; cp -a \"$appdir/dist/.\" \"$data/\"" + isSuccessful "Website published. Restart $app to serve it." +} diff --git a/scripts/source/files/arrays/files_app.sh b/scripts/source/files/arrays/files_app.sh index 86c143b..cf0790e 100755 --- a/scripts/source/files/arrays/files_app.sh +++ b/scripts/source/files/arrays/files_app.sh @@ -38,6 +38,7 @@ app_scripts=( "app/containers/focalboard/focalboard_list_users.sh" "app/containers/focalboard/focalboard_reset_password.sh" "app/containers/focalboard/focalboard_set_admin.sh" + "app/containers/getlibreportal/getlibreportal_publish.sh" "app/containers/gitea/gitea_auth.sh" "app/containers/gitea/gitea_create_account.sh" "app/containers/gitea/gitea_delete_user.sh" @@ -73,5 +74,6 @@ app_scripts=( "app/containers/pihole/pihole_apply_dns_updater.sh" "app/containers/traefik/traefik_auth.sh" "app/containers/traefik/traefik_reset_password.sh" + "app/containers/weblibreportal/weblibreportal_publish.sh" ) diff --git a/scripts/webui/data/generators/apps/webui_tools.sh b/scripts/webui/data/generators/apps/webui_tools.sh index 5507a14..1ca0b78 100644 --- a/scripts/webui/data/generators/apps/webui_tools.sh +++ b/scripts/webui/data/generators/apps/webui_tools.sh @@ -409,6 +409,28 @@ webuiGenerateAppsToolsConfig() { ] } ] + }, + "getlibreportal": { + "tools": [ + { + "id": "publish", + "label": "Publish downloads", + "description": "Rebuild the get.libreportal.org docroot — copy install.sh + the dist/ release artifacts into the served data dir (live on next restart). Build-box only: needs the repo checkout + a built dist/ (run make_release first).", + "icon": "📦", + "fields": [] + } + ] + }, + "weblibreportal": { + "tools": [ + { + "id": "publish", + "label": "Publish website", + "description": "Rebuild the LibrePortal website (Eleventy) into the served data dir (live on next restart). Build-box only: needs the repo checkout + npm.", + "icon": "🌐", + "fields": [] + } + ] } } }