Repository navigation
Conversation
Add publishApp(options), which uploads a local build directory into a project's app folder and keeps the sync mirror up to date. It reports per-file progress through events, returns a structured result, and throws PublishError and PublishDivergedError instead of printing and setting process.exitCode. deepnote publish becomes an adapter over publishApp with unchanged output and exit codes. publish-mirror.ts and its tests move into the package, and the package no longer exports projectFilesDir, which nothing outside it imports. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYyMrxsMPw3Yu9zmWuusYP
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #566 +/- ##
==========================================
+ Coverage 90.36% 90.44% +0.08%
==========================================
Files 215 216 +1
Lines 12546 12584 +38
Branches 3517 3636 +119
==========================================
+ Hits 11337 11382 +45
+ Misses 1206 1199 -7
Partials 3 3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
tkislan
marked this pull request as draft
October 8, 2026 12:35
…sh-app Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RC56T3VN4kVv9pmUBgeuf3
…n its types Export PublishMirrorError from the package and list it in the README. The README now follows the package's API-reference table, so the option, event, result and error details of publishApp live on the exported types. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RC56T3VN4kVv9pmUBgeuf3
PublishAppOptions.syncRoot and the CLI's publish options now use the exported SyncRootOption instead of restating its union. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RC56T3VN4kVv9pmUBgeuf3
Contributor
Author
|
@coderabbitai full review |
Contributor
✅ Action performedFull review finished. |
Contributor
tkislan
marked this pull request as ready for review
October 9, 2026 16:38
This branch has not been deployed
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.
Summary
Closes #564.
deepnote publishran its whole upload flow inside a commander action: it printed as it went, signalled failure throughprocess.exitCode, and the "Deepnote changed these files since the last sync" check existed only as an error message. This moves the flow into@deepnote/cloud-syncaspublishApp(options), which reports per-file progress throughonEvent, returns a structured result, and throwsPublishError/PublishDivergedError.deepnote publishis now an adapter over it.CLI behavior is unchanged: no change to flags, output, exit codes or the manifest format.
Changes
packages/cloud-sync/src/publish-app.ts(new):publishApp,PublishError(reason:invalid-input|unreadable-directory|project-unavailable),PublishDivergedError(syncRoot, sortedpaths), and thePublishAppOptions/PublishAppEvent/PublishAppResulttypes.PublishDivergedErroris thrown before any delete or upload request unlessforceis set. The file helpers (collectFiles,isEnvFile,normalizeTargetPrefix,preparePublishFiles,appUrlWithPath) moved over unchanged.packages/cloud-sync/src/publish-mirror.tsand its test: moved withgit mvfrompackages/cli/src/utils/.resolvePublishMirrortakes an optionalonMirrorSkippedcallback in place of the CLI'sdebugcall, andSyncRootOptionis nowstring | false | undefined. Of its symbols,PublishMirrorErrorandSyncRootOptionare exported fromindex.ts;PublishAppOptions.syncRootand the CLI's publish options useSyncRootOption.packages/cli/src/commands/publish.ts: loads.env, resolves the token, callspublishApp, renders each event with the previous text, and maps errors to the previous exit codes. It no longer imports@deepnote/cloud.packages/cloud-sync/README.md: adds apublishAppusage example and rows forpublishApp,PublishError,PublishDivergedErrorandPublishMirrorErrorto the API reference table. Options, events and result fields are documented on the exported types.packages/cloud-sync/src/index.ts: exportspublishApp,PublishError,PublishDivergedError,PublishMirrorErrorand thePublishApp*,PublishErrorReasonandSyncRootOptiontypes.Judgment calls
index.tskeepsmain's export set. After merging feat(cloud-sync): move the workspace sync engine into @deepnote/cloud-sync #568 and feat(cloud-sync): move Streamlit app registration into @deepnote/cloud-sync #573, nothing outsidepackages/cloud-syncimportssha256,baselineDiverged,assertNoSymbolicLinkAncestors,saveSyncManifest,isSafeRelativeFilePathorprojectFilesDir, so issue step 5 would remove them. They stay because the README onmainlists them as public helpers.PublishMirrorErrorandSyncRootOptionare exported, unlike the rest ofpublish-mirror.ts(issue step 1).PublishMirrorErrornever reachespublishAppcallers:publishApprethrows it asPublishErrorwith reasoninvalid-input.try. A throwingonEventlistener would otherwise be recorded as a failed upload.PublishAppOptions.onEventdocuments that the listener must not throw.PublishOptions.quietguards are kept in the adapter although Commander never populates it, to keep the diff a pure move.syncRoot: false,mirror-skipped, a failed manifest save reported before sharing,apiAccesstrue/false, and input errors. One extrapublish-mirrortest coversonMirrorSkipped.Verification
Run on this branch after merging
main(#568, #573):pnpm typecheck,pnpm prettier:checkexit 0.pnpm biome:checkandpnpm spell-checkreport nothing in any file this PR touches.pnpm install --frozen-lockfileaccepts the lockfile.package.json,tsdown.config.tsandpnpm-lock.yamlno longer differ frommain, which already declares@deepnote/database-integrationsas a dependency and a tsdown external.pnpm buildsucceeds; the built@deepnote/cloud-syncexportsPublishMirrorErrorfrom ESM, CJS andindex.d.ts.pnpm test: 3569 passed in 189 files. This workspace had apythonshim onPATHfor the threecli/run.test.tscases that need it.commands/publish.test.tspass with the file unchanged; all 18 original mirror tests pass.packages/cloud-sync/src(non-test) has no import ofcommander,chalk,ora,@inquirer/prompts,dotenvor@deepnote/cli, and noprocess.reference.6f33d9e, before the merge, which changes no publish code). I brokepublish-app.tsandpublish-mirror.ts22 ways (dropped divergence check, reorderedmirror-incompletebefore the save, unsorted divergent paths, wrongmirrorUpdated, skipped.envrefusal, wrong hash, …); the new tests failed on every one. A first run of the tests passed everything, so this is what shows they can fail.6f33d9e). A throwaway harness (not committed) ranorigin/main'spublish.tsand the new adapter side by side over 47 scenarios (happy path, prune, every failure class, divergence with and without--force, mirror warnings, quiet/debug, bad flags, missing token). Console and stderr output, exit codes, API call order and arguments, and resulting file trees were identical./code-review-typescript, with two skeptics per finding. The one blocker (type errors in the new test file, which vitest does not catch) and the README inaccuracies are fixed.Not verified: a live run against Deepnote Cloud, and Windows path behavior.
Pre-existing behavior, moved unchanged
Noticed during review and deliberately not changed here:
.envrefusal is case-sensitive:.ENVand.envrcare published.✓ removedwith an empty name.🤖 Generated with Claude Code
https://claude.ai/code/session_01BYyMrxsMPw3Yu9zmWuusYP
Summary by CodeRabbit