Summary
Two pairs of self-host operator scripts duplicate substantial, security-sensitive shell logic instead of sharing it:
scripts/deploy-selfhost-image.sh and scripts/deploy-selfhost-prebuilt.sh copy-paste ~90 lines of identical bash (require_cmd(), env_get()/env_put() — awk-based .env parsing/writing — and compose_file_args()).
scripts/backup.sh and scripts/verify-backup.sh duplicate Postgres-URL password-stripping logic (url_decode(), pgpass_escape(), prepare_pg_env()/pg_connect_arg()) — verify-backup.sh's own comment even says "the same approach backup.sh uses, see that file for the full rationale," acknowledging the duplication rather than sharing code.
Part of #1667.
Context
Found during a 2026-07-04 audit. Neither pair is dead code — both scripts in each pair serve genuinely different, actively-used purposes (pull-a-published-image vs. build-a-prebuilt-bundle-locally; back up vs. verify-a-backup). The duplication is real drift risk though: a future fix to the shared .env parsing or the credential-handling logic in one file will not automatically propagate to its sibling.
Requirements
- Extract the shared
require_cmd()/env_get()/env_put()/compose_file_args() helpers from the two deploy scripts into a single sourced library (e.g. scripts/lib/selfhost-deploy-common.sh), and have both scripts source it.
- Extract the shared
url_decode()/pgpass_escape()/prepare_pg_env()/pg_connect_arg() logic from backup.sh/verify-backup.sh into a shared sourced file, keeping in mind both scripts are run independently inside a Docker container (docker compose run --rm backup sh /backup.sh / sh /verify-backup.sh) — the shared file needs to be mounted/available to both at runtime, not just at repo-checkout time.
- This touches credential-handling code (Postgres password extraction/masking) — be conservative. Add or confirm test coverage for the extracted functions before/after the refactor so behavior is provably unchanged, and manually exercise both scripts end-to-end (not just unit-level) since these are POSIX sh scripts with limited existing test coverage.
- Do not change any user-facing script invocation, flags, or output format — this is an internal-structure-only refactor.
Deliverables
- A PR (or two, one per pair, if that keeps each change reviewable) that de-duplicates the shared logic into sourced library file(s), with the four (or however many) scripts updated to source them.
- Before/after manual verification notes in the PR description (e.g. running each script against a local test Postgres instance and confirming identical behavior).
Expected outcome
A future change to .env parsing or to Postgres-credential handling only needs to happen in one place, and cannot silently drift between the two scripts in each pair.
Summary
Two pairs of self-host operator scripts duplicate substantial, security-sensitive shell logic instead of sharing it:
scripts/deploy-selfhost-image.shandscripts/deploy-selfhost-prebuilt.shcopy-paste ~90 lines of identical bash (require_cmd(),env_get()/env_put()— awk-based.envparsing/writing — andcompose_file_args()).scripts/backup.shandscripts/verify-backup.shduplicate Postgres-URL password-stripping logic (url_decode(),pgpass_escape(),prepare_pg_env()/pg_connect_arg()) —verify-backup.sh's own comment even says "the same approach backup.sh uses, see that file for the full rationale," acknowledging the duplication rather than sharing code.Part of #1667.
Context
Found during a 2026-07-04 audit. Neither pair is dead code — both scripts in each pair serve genuinely different, actively-used purposes (pull-a-published-image vs. build-a-prebuilt-bundle-locally; back up vs. verify-a-backup). The duplication is real drift risk though: a future fix to the shared
.envparsing or the credential-handling logic in one file will not automatically propagate to its sibling.Requirements
require_cmd()/env_get()/env_put()/compose_file_args()helpers from the two deploy scripts into a single sourced library (e.g.scripts/lib/selfhost-deploy-common.sh), and have both scripts source it.url_decode()/pgpass_escape()/prepare_pg_env()/pg_connect_arg()logic frombackup.sh/verify-backup.shinto a shared sourced file, keeping in mind both scripts are run independently inside a Docker container (docker compose run --rm backup sh /backup.sh/sh /verify-backup.sh) — the shared file needs to be mounted/available to both at runtime, not just at repo-checkout time.Deliverables
Expected outcome
A future change to
.envparsing or to Postgres-credential handling only needs to happen in one place, and cannot silently drift between the two scripts in each pair.