Commit Graph
7 Commits
Author SHA1 Message Date
Sluijsens 9b44a5e85e Adds a shared/modules symlink mechanism for optional plugin modules
Continuous Integration / config (pull_request) Successful in 9s
Continuous Integration / backend-build (pull_request) Successful in 5m4s
Continuous Integration / vulnerability-scan (pull_request) Successful in 4m23s
Continuous Integration / frontend-prepare (pull_request) Successful in 1m40s
Continuous Integration / backend-test (pull_request) Successful in 5m46s
Continuous Integration / frontend-build (pull_request) Successful in 2m18s
Continuous Integration / frontend-test (pull_request) Successful in 4m33s
Continuous Integration / frontend-lint (pull_request) Successful in 2m0s
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
Continuous Integration / publish-test (pull_request) Successful in 6m11s
Deploy (SCP) / deploy (pull_request) Successful in 1m25s
Continuous Integration / deploy-test (pull_request) Successful in 1m25s
ModuleOrchestrator already discovers SlpModularCms.Modules.*.dll from disk at
startup via reflection, so this needed no code change — only a persistent
location (mirroring shared/wwwroot-web) that survives release swaps, and a
deploy-scp.yaml step to symlink its contents into each new release before
restart.
2026-07-30 10:09:53 +02:00
SluijsensandClaude Sonnet 5 d51285d9dd Removes the secret-diagnosis debug step, fixes wwwroot symlink parent dir
Continuous Integration / config (pull_request) Successful in 10s
Continuous Integration / backend-build (pull_request) Successful in 4m34s
Continuous Integration / vulnerability-scan (pull_request) Successful in 4m39s
Continuous Integration / frontend-prepare (pull_request) Successful in 1m45s
Continuous Integration / backend-test (pull_request) Successful in 5m15s
Continuous Integration / frontend-build (pull_request) Successful in 2m14s
Continuous Integration / frontend-test (pull_request) Successful in 4m27s
Continuous Integration / frontend-lint (pull_request) Successful in 1m57s
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
Continuous Integration / publish-test (pull_request) Successful in 5m51s
Deploy (SCP) / deploy (pull_request) Failing after 11m46s
Continuous Integration / deploy-test (pull_request) Failing after 11m47s
The PI_MAIN_USERNAME/PASSWORD debug step served its purpose (found the
shell-metacharacter password bug fixed in 51488d6) and is removed now
that deploy-test gets past authentication.

"Link persistent website content" then failed with `ln: failed to
create symbolic link '.../wwwroot/web': No such file or directory` -
dotnet publish only emits a wwwroot/ folder when the source project's
own wwwroot has content, so a release built before any frontend/website
content exists can land with no wwwroot/ directory at all, not merely
an empty wwwroot/web/. `ln -s` can't create the missing parent
directory itself. Added `mkdir -p $RELEASE_DIR/wwwroot` before the
existing rm/ln pair to guarantee the parent exists either way.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015FffvxxJp5wG34Ru48GBig
2026-07-30 00:28:29 +02:00
SluijsensandClaude Sonnet 5 51488d6d94 Routes PI_MAIN_* secrets through env vars instead of inline interpolation
Continuous Integration / config (pull_request) Successful in 9s
Continuous Integration / backend-build (pull_request) Successful in 4m57s
Continuous Integration / vulnerability-scan (pull_request) Successful in 4m21s
Continuous Integration / frontend-prepare (pull_request) Successful in 1m28s
Continuous Integration / backend-test (pull_request) Successful in 5m3s
Continuous Integration / frontend-build (pull_request) Successful in 2m10s
Continuous Integration / frontend-test (pull_request) Successful in 4m42s
Continuous Integration / frontend-lint (pull_request) Successful in 1m56s
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
Continuous Integration / publish-test (pull_request) Successful in 6m30s
Deploy (SCP) / deploy (pull_request) Failing after 57s
Continuous Integration / deploy-test (pull_request) Failing after 58s
Every ssh/scp step interpolated ${{ secrets.PI_MAIN_PASSWORD }} and
${{ secrets.PI_MAIN_USERNAME }} directly into the run: shell text.
Gitea/GitHub Actions substitutes that as literal text before bash ever
sees it, so any shell-metacharacter in the password ($, `, ", \) gets
re-interpreted by bash instead of passed through - silently changing
what sshpass actually receives. This plausibly explains a persistent
"Permission denied" even after the username and password length were
both confirmed correct via the debug step (which used env: and so
never hit this).

All five steps now receive SSH_USER/SSH_PASS/SSH_PORT/SSH_HOST via
env:, which bash treats as opaque values with no re-parsing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015FffvxxJp5wG34Ru48GBig
2026-07-29 20:42:57 +02:00
SluijsensandClaude Sonnet 5 3776c0f27b Adds a trimmed-length check to the PI_MAIN_PASSWORD debug step
Continuous Integration / config (pull_request) Successful in 9s
Continuous Integration / backend-build (pull_request) Successful in 4m39s
Continuous Integration / vulnerability-scan (pull_request) Successful in 4m15s
Continuous Integration / frontend-prepare (pull_request) Successful in 1m47s
Continuous Integration / backend-test (pull_request) Successful in 5m15s
Continuous Integration / frontend-build (pull_request) Successful in 2m11s
Continuous Integration / frontend-test (pull_request) Successful in 4m40s
Continuous Integration / frontend-lint (pull_request) Successful in 1m58s
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
Continuous Integration / publish-test (pull_request) Successful in 6m25s
Deploy (SCP) / deploy (pull_request) Failing after 56s
Continuous Integration / deploy-test (pull_request) Failing after 57s
Username is now confirmed correct (14 chars, exact match). This checks
whether the password secret carries leading/trailing whitespace or a
stray newline picked up when it was pasted into Gitea - the length
differs from the trimmed length if so, without ever logging the
password's actual characters.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015FffvxxJp5wG34Ru48GBig
2026-07-29 20:39:36 +02:00
SluijsensandClaude Sonnet 5 56f4f6fe0f Adds Monitoring Setup docs and deploy-scp troubleshooting/debug fixes
Continuous Integration / config (pull_request) Successful in 9s
Continuous Integration / backend-build (pull_request) Successful in 4m27s
Continuous Integration / vulnerability-scan (pull_request) Successful in 4m10s
Continuous Integration / backend-test (pull_request) Canceled after 0s
Continuous Integration / frontend-build (pull_request) Canceled after 0s
Continuous Integration / frontend-test (pull_request) Canceled after 0s
Continuous Integration / frontend-lint (pull_request) Canceled after 0s
Continuous Integration / publish-test (pull_request) Canceled after 0s
Continuous Integration / publish-production (pull_request) Canceled after 0s
Continuous Integration / deploy-test (pull_request) Canceled after 0s
Continuous Integration / deploy-production (pull_request) Canceled after 0s
Continuous Integration / frontend-prepare (pull_request) Canceled after 50s
Monitoring Setup: operations/plans/monitoring-setup-plan.md and
operations/monitoring/monitoring-instructions.md, covering Sentry alert
rules on the security_event tag, UptimeRobot's 6 liveness monitors, and
the two new Umami website entries for the admin SPA.

deployment-instructions.md gains a missing Observability__Environment
host var (without it, both environments would tag Sentry events as
"Production"), the nginx client_max_body_size fix for the 413 seen on
publish-test/production artifact uploads, and two troubleshooting notes
on Gitea Actions re-run behaviour: re-running deploy-test/production
alone loses the run's uploaded artifact, and re-running all jobs on an
existing (rather than a brand new) run can replay stale secrets.

deploy-scp.yaml: step names no longer show literal unresolved
${{ inputs.* }} text (Gitea doesn't interpolate that context in step
names), and a temporary debug step logs PI_MAIN_USERNAME/PASSWORD
length plus a username equality check to diagnose a persistent
Permission denied during the SSH steps, without ever logging the
secret values themselves.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015FffvxxJp5wG34Ru48GBig
2026-07-29 19:39:44 +02:00
Sluijsens 2cd8c4aa88 Renames the backup script to match the instance, not the software
Continuous Integration / config (pull_request) Successful in 10s
Continuous Integration / backend-build (pull_request) Successful in 4m6s
Continuous Integration / vulnerability-scan (pull_request) Successful in 3m39s
Continuous Integration / frontend-prepare (pull_request) Failing after 58s
Continuous Integration / frontend-build (pull_request) Skipped
Continuous Integration / frontend-test (pull_request) Skipped
Continuous Integration / frontend-lint (pull_request) Skipped
Continuous Integration / backend-test (pull_request) Successful in 4m26s
Continuous Integration / publish-test (pull_request) Skipped
Continuous Integration / publish-production (pull_request) Skipped
Continuous Integration / deploy-test (pull_request) Skipped
Continuous Integration / deploy-production (pull_request) Skipped
backup-slpmodularcms-db.sh named the CMS; this backs up slpsoftware
specifically, same as every other instance-scoped path already does.
Hardcoded in deploy-scp.yaml itself, so this is the actual pipeline
code, not just docs describing it.
2026-07-29 14:17:41 +02:00
Sluijsens bd2a963498 U6 — the deploy workflow itself
deploy-scp.yaml: download, back up the production database before
touching anything, upload into a timestamped release, symlink the
persistent website in, switch current and restart, verify /health
with retries, prune old releases only once that check passes. No
sudo, no container actions, one shared interface U5 will call next.
2026-07-28 15:33:03 +02:00