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.
This commit is contained in:
2026-07-30 10:09:53 +02:00
parent d51285d9dd
commit 9b44a5e85e
2 changed files with 53 additions and 3 deletions
+28
View File
@@ -132,6 +132,34 @@ jobs:
rm -rf $RELEASE_DIR/wwwroot/web && \
ln -s ../../../shared/wwwroot-web $RELEASE_DIR/wwwroot/web"
# Optional plugin modules (future modular support): a compiled SlpModularCms.Modules.*.dll
# dropped into shared/modules survives every release, the same persistence pattern as
# shared/wwwroot-web above — except there's no cross-account permission dance here, since
# shared/modules lives entirely under gitea-workflow's own tree (unlike wwwroot-web, which
# reaches into webadmin's). ModuleOrchestrator.DiscoverModules() already scans its own base
# directory on disk for matching assemblies at startup (SlpModularCms.Core/Hosting/
# ModuleOrchestrator.cs) and loads whatever it finds via reflection — no code change needed,
# only somewhere for the DLL to still be after the next deploy replaces releases/{timestamp}.
# `ls ... 2>/dev/null` piped to a `while read` (rather than a bare glob loop) keeps this
# POSIX-sh safe and correct when shared/modules is empty, which is the common case today.
- name: Link persistent modules
env:
SSH_USER: ${{ secrets.PI_MAIN_USERNAME }}
SSH_PASS: ${{ secrets.PI_MAIN_PASSWORD }}
SSH_PORT: ${{ secrets.PI_MAIN_PORT }}
SSH_HOST: ${{ secrets.PI_MAIN_ADDRESS }}
run: |
RELEASE_DIR="${{ inputs.deploy_path }}/releases/${{ steps.release.outputs.timestamp }}"
sshpass -p "$SSH_PASS" ssh \
-p "$SSH_PORT" \
-o StrictHostKeyChecking=no \
"$SSH_USER@$SSH_HOST" \
"mkdir -p ${{ inputs.deploy_path }}/shared/modules && \
ls ${{ inputs.deploy_path }}/shared/modules/*.dll 2>/dev/null | while read -r f; do \
name=\$(basename \"\$f\"); \
ln -sf \"../../shared/modules/\$name\" \"$RELEASE_DIR/\$name\"; \
done"
# Atomic release switch (FR-06, D-27): `ln -sfn` replaces the `current` symlink target in a
# single filesystem operation, so there is no moment where `current` points at a half-written
# directory. The process is then restarted so it picks up the new assemblies — a running .NET