Repository navigation
🐛 Fixed migrate-export failing to copy a production site's content - #2405
Merged
Merged
Conversation
ref https://linear.app/ghost/issue/PLA-479/s5e-production-import-and-cutover A production install's content belongs to the ghost user, so the export copies it with sudo. ui.sudo was changed in #2348 to take an array of arguments and refuse anything else, but the exporter still passed it shell strings, so every standard production export failed at "Copying content files" with "ui.sudo expects an array of arguments". The unit tests stubbed ui.sudo and ran the strings through a shell, so they never saw the refusal. ghost-docker's production import scenario found it. The arguments now go to ui.sudo as an array, which also makes the shell quoting unnecessary: ui.sudo never uses a shell. - lib/tasks/migration-export/index.js: pass cp and chown their arguments as arrays and remove the shell quoting. - test/unit/tasks/migration-export/index-spec.js: the stub refuses anything but an array, as ui.sudo does, and the copies that really run do so without a shell.
acburdine
enabled auto-merge (squash)
October 9, 2026 19:42
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2405 +/- ##
==========================================
- Coverage 93.12% 93.12% -0.01%
==========================================
Files 106 106
Lines 4410 4408 -2
Branches 789 789
==========================================
- Hits 4107 4105 -2
Misses 228 228
Partials 75 75
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
acburdine
added a commit
to TryGhost/ghost-docker
that referenced
this pull request
Oct 9, 2026
ref https://linear.app/ghost/issue/PLA-479/s5e-production-import-and-cutover Ghost-CLI 1.33.3's migrate-export failed on every standard production install: it copies content owned by the ghost user with sudo, and passed ui.sudo shell strings after ui.sudo had begun to accept only arrays. 1.33.4 fixes it (TryGhost/Ghost-CLI#2405), so it is the minimum for exporting, and what the end-to-end scenarios run. - tests/e2e/import.sh, .github/workflows/test.yml: run 1.33.4. - docs/install.md, docs/bundle-v1.md, pages/index.html: the minimum, and the exporter documentation at that tag. - manager/src/bundle/manifest.ts: the re-export advice names it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ref https://linear.app/ghost/issue/PLA-479/s5e-production-import-and-cutover
ghost migrate-exportfails on every standard production install in 1.33.3, at "Copying content files":A production install's content belongs to the
ghostuser, so the exporter copies it with sudo. #2348 changedui.sudoto take only an array of arguments, butlib/tasks/migration-export/index.jsstill passed it shell strings (cp -R …,chown -R …). The unit tests didn't catch it: they stubbedui.sudoand ran the strings through/bin/sh. Local sites never take the sudo path, so only production exports fail.ghost-docker's new production import scenario (TryGhost/ghost-docker#382) found it on a real Ghost-CLI production install (Ubuntu 24.04, MySQL, systemd, nginx).
Changes
cpandchowntheir arguments as arrays.ui.sudonever uses a shell, so the shell quoting is removed.ui.sudostub refuses anything but an array, as the real one does. The copies that really run do so without a shell.Testing
pnpm test: 1160 passed, lint clean.🤖 Generated with Claude Code