refactor(selfhost): dedup shared logic in deploy and backup scripts - #2951
Conversation
Two script pairs duplicated substantial shell logic: - deploy-selfhost-image.sh / deploy-selfhost-prebuilt.sh copy-pasted require_cmd()/env_get()/env_put()/compose_file_args() verbatim. Extracted into scripts/lib/selfhost-deploy-common.sh, sourced via a BASH_SOURCE- relative path from both. Reconciled an unintentional drift found while extracting: env_put()'s temp-file location differed (image.sh created it same-directory as the target, avoiding cross-filesystem write issues; prebuilt.sh used a plain mktemp with no documented reason) -- both now use the safer same-directory version. - backup.sh / verify-backup.sh duplicated url_decode()/pgpass_escape() byte-for-byte. Extracted into scripts/selfhost-pg-url.sh (a sibling file, not a lib/ subdirectory, since both scripts are bind-mounted individually at container root with no shared /lib path -- docker-compose.yml gets a matching bind-mount). prepare_pg_env()/pg_connect_arg() are deliberately NOT merged despite sharing the same URI-parsing algorithm: they have genuinely different PGPASSFILE lifecycles (single global vs. per-call arg, a reentrancy unset-guard, one passfile vs. a tracked list) that a forced merge would risk breaking -- left as-is with a stronger cross-reference comment explaining why. Verified via the existing (and, for the backup pair, deliberately adversarial) test suites rather than assumed safe: all 47 tests across selfhost-image-deploy, selfhost-sentry-release, backup-script, selfhost-backup-script, and selfhost-verify-backup-script still pass unchanged, including the reentrancy/leak-guard test that proves no password crosses between connections. Also manually exercised both deploy scripts end-to-end (deploy-selfhost-prebuilt.sh has no existing script-execution test coverage) and confirmed shellcheck is clean on every touched file.
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-04 06:40:50 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 6 non-blocking
Concerns raised — review before merging
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2951 +/- ##
=======================================
Coverage 96.05% 96.05%
=======================================
Files 259 259
Lines 28459 28459
Branches 10348 10348
=======================================
Hits 27335 27335
Misses 489 489
Partials 635 635 🚀 New features to boost your workflow:
|
Summary
Two self-host script pairs duplicated substantial shell logic. Investigated both pairs thoroughly (exact diff of every shared function, every call site, container-mount constraints, and existing test coverage) before deciding what was safe to merge.
deploy-selfhost-image.sh/deploy-selfhost-prebuilt.sh— copy-pastedrequire_cmd()/env_get()/env_put()/compose_file_args()verbatim. Extracted intoscripts/lib/selfhost-deploy-common.sh, sourced via aBASH_SOURCE-relative path from both (works regardless of invocation style — relative, absolute, orbash scripts/..., matching how the existing test spawns it). Found and reconciled a genuine, undocumented drift while extracting:env_put()'s temp-file location differed between the two scripts —deploy-selfhost-image.shcreated it in the same directory as the target.envfile (avoiding a cross-filesystem write if$ENV_FILElives on a different mount than the system tmpdir),deploy-selfhost-prebuilt.shused a plainmktempwith no comment explaining the difference. Both now use the safer same-directory version.backup.sh/verify-backup.sh— duplicatedurl_decode()/pgpass_escape()byte-for-byte. Extracted intoscripts/selfhost-pg-url.sh— a sibling file, not alib/subdirectory, because both scripts are bind-mounted individually at container root (/backup.sh,/verify-backup.sh) with no shared/libpath;docker-compose.ymlgets a matching bind-mount (./scripts/selfhost-pg-url.sh:/selfhost-pg-url.sh:ro) so. "$(dirname "$0")/selfhost-pg-url.sh"resolves correctly both in the container and when either script is run directly from a checkout (as the tests do).Deliberately did NOT merge
prepare_pg_env()(backup.sh) andpg_connect_arg()(verify-backup.sh), despite them sharing the identical URI-parsing algorithm — full analysis confirmed genuine, non-cosmetic differences in their PGPASSFILE lifecycle:prepare_pg_env()reads the URL from a single global and runs once per invocation;pg_connect_arg()takes the URL as an argument,unsetsPGPASSFILEat the top of every call (a reentrancy guard against a stale value leaking from a previous call for a different URL — required because it's called up to 4 times per run for different URLs), and tracks a list of created passfiles instead of one. Forcing these into a single function risked losing that reentrancy guard, which would leak a password across connections. Left as-is with a strengthened cross-reference comment in both files explaining exactly why.Verification (not assumed safe): ran the existing — and for the backup pair, deliberately adversarial — test suites. All 47 tests across
selfhost-image-deploy,selfhost-sentry-release,backup-script,selfhost-backup-script, andselfhost-verify-backup-scriptpass unchanged, including the test that specifically proves no password leaks between connections across the full multi-URL scratch-restore flow.deploy-selfhost-prebuilt.shhas no existing script-execution test coverage (a pre-existing gap, not introduced here) — manually exercised it end-to-end for real (a fulldocker runbuild) to confirm the sourced functions work correctly; it completed successfully well past every shared-function call site.shellcheckis clean on every touched/new file.Resolves #2910. Part of the #1667 self-host review-stack roadmap.
Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run typecheckshellcheckon every touched/new shell file — clean (only pre-existing, unrelated info-level notices remain inverify-backup.sh)vitest runon all 5 relevant test files — 47 tests passeddeploy-selfhost-prebuilt.shrun for real (Docker build) to verify the shared-lib sourcing works where no automated test existsdocker-compose.ymlre-validated as parseable YAML after the new bind-mountnpm run actionlint/npm run test:workers/npm run build:mcp/npm run test:mcp-pack/npm audit/ui:*— not run locally; no workflow, worker-pool, MCP-package, or UI files touched. CI runs the full gate, including the self-host "build + boot smoke test" job (this PR touchesdocker-compose.ymlandscripts/, so that job will run and is the authoritative confirmation the backup service still boots with its new bind-mount).If any required check was skipped, explain why:
test:coverage/test:cinot run locally — nosrc/**files changed (this is ascripts/**/docker-compose.ymldiff only, both Codecov-ignored paths); the shell-script test suites above are the real correctness signal for this change, and they all pass.Safety