fix(deploy): prune dangling standalone symlinks before rsync#38
Merged
Conversation
The nextjs-ssr deploy uploads .next/standalone with `rsync --copy-links`, so rsync follows every symlink. On pnpm monorepos, Next's standalone tracing can leave a compat symlink pointing at a version it never wrote into the bundle, like .pnpm/node_modules/semver -> ../semver@6.3.1/... when only semver@7.x was traced. The link dangles, rsync fails trying to follow it, exits 23, and the deploy aborts with an empty stderr. Add a step 3b that walks .next/standalone after the build and deletes any symlink whose target is missing, before the rsync runs. It recurses into real directories but never follows a symlinked one, so there are no cycles. The dangling package isn't part of the traced runtime, so removing the link is safe. It prints how many it removed. Replaces the manual find/delete workaround for every pnpm monorepo. The smbcloud-deploy-nextjs skill is updated to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
f8f7409 to
e894c6a
Compare
Review follow-ups on the dangling-symlink prune: - Swap exists() for try_exists()? in both branches so a stat error on a symlink target propagates instead of being misread as "dangling" and deleting a link we merely failed to stat. - Note in the docstring that the walk depends on pnpm's layout, where every package dir is a real directory reachable directly (so nested dangling links are always visited). - Print the success symbol on the prune line to match the other step output. - Add a cycle-safety test (a dir symlink pointing back at the root must not be followed) and a root-is-dangling-symlink test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Adds a prune_dangling_symlinks helper to the nextjs-ssr deploy path that recursively walks .next/standalone/ removing symlinks whose targets are missing, run as a new step 3b before the rsync --copy-links upload. This fixes rsync exiting with status 23 on pnpm monorepos where Next's standalone tracing leaves dangling compat symlinks. Includes four unix-gated tests and a skill doc update. The core logic to verify is the try_exists handling and the non-following of directory symlinks.
Automated review by siGit Code · commit 907c9ca
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.
Fixes the
nextjs-ssrdeploy failing withrsync ... status 23on pnpm monorepos.What happens
The standalone upload runs
rsync --copy-links, so rsync follows every symlink. On pnpm, Next's standalone tracing sometimes leaves a compat symlink pointing at a package version it never actually wrote into the bundle. A real one:.pnpm/node_modules/semver -> ../semver@6.3.1/node_modules/semver, when onlysemver@7.xgot traced. The6.3.1target isn't there, so the link dangles. rsync tries to follow it, hits an IO error, and exits 23. The deploy aborts with an empty stderr, so the real cause is invisible from the CLI output.The change
A new step 3b in
process_deploy_nextjs_ssrruns between the build and the rsync. It walks.next/standalone/and removes any symlink whose target is missing. It recurses into real directories but never follows a symlinked directory, so there's no risk of cycles. The dangling package was never part of the traced runtime, so deleting the link is safe. If it removes anything, it prints the count.No new dependencies (std only). This does in the CLI what the skill used to tell people to do by hand (
find ... -deletebefore deploy), so every pnpm monorepo gets it without a manual step.Tests
Two unix-gated unit tests: one checks that a dangling link is removed while a valid link and real files survive, the other checks that a clean tree is left alone. The full crate suite passes (11 tests) and
cargo check -p smbcloud-cliis clean.I also updated the
smbcloud-deploy-nextjsskill so the status-23 section says the CLI handles this now, with the manual find/postbuild step only needed onsmb0.4.7 and older.