Skip to content

Add backup exclude options and defaults - #437

Closed
whoiskatrin wants to merge 15 commits into
mainfrom
ignore-files
Closed

whoiskatrin wants to merge 15 commits into
mainfrom
ignore-files

Conversation

@whoiskatrin

@whoiskatrin whoiskatrin commented Mar 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This PR changes backup exclusion behavior to follow .gitignore by default instead of maintaining a hardcoded default ignore list.

createBackup() now supports:

  • useGitignore?: boolean to control whether git ignore rules are applied

Default behavior:

  • when the backup directory is inside a git repository, ignored paths are excluded from the archive
  • when useGitignore: false, gitignored paths are included
  • when the directory is not inside a git repository, backup proceeds without git-based exclusions

Why

The previous approach maintained a built-in list of default excluded paths. Based on review feedback, this PR moves away from that model and aligns backup behavior with standard tooling that respects .gitignore by default.

API and behavior

Changes in this PR:

  • remove exclude
  • remove excludeDefaults
  • add useGitignore?: boolean with default true
  • resolve ignored paths in the container via git instead of hand-maintaining defaults in the SDK
  • exclude .git when gitignore-based exclusion is enabled
  • gracefully fall back to a full backup when git is unavailable or the directory is not in a git repository

Tests

Updated backup workflow E2E coverage for:

  • respecting .gitignore by default
  • opting out with useGitignore: false
  • non-git directory fallback
  • nested .gitignore behavior

Validation run locally:

  • npm run typecheck

Reviewer notes

This PR now addresses the feedback to stop maintaining a default ignore list and instead use gitignore-driven defaults.

@changeset-bot

changeset-bot Bot commented Mar 2, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9bdedbc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@cloudflare/sandbox Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

github-actions[bot]

This comment was marked as outdated.

@pkg-pr-new

pkg-pr-new Bot commented Mar 2, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/cloudflare/sandbox-sdk/@cloudflare/sandbox@437

commit: 9bdedbc

@github-actions

github-actions Bot commented Mar 2, 2026 •

Copy link
Copy Markdown
Contributor

🐳 Docker Images Published

Variant Image
Default cloudflare/sandbox:0.0.0-pr-437-2aecdff
Python cloudflare/sandbox:0.0.0-pr-437-2aecdff-python
OpenCode cloudflare/sandbox:0.0.0-pr-437-2aecdff-opencode
Musl cloudflare/sandbox:0.0.0-pr-437-2aecdff-musl
Desktop cloudflare/sandbox:0.0.0-pr-437-2aecdff-desktop

Usage:

FROM cloudflare/sandbox:0.0.0-pr-437-2aecdff

Version: 0.0.0-pr-437-2aecdff


📦 Standalone Binary

For arbitrary Dockerfiles:

COPY --from=cloudflare/sandbox:0.0.0-pr-437-2aecdff /container-server/sandbox /sandbox
ENTRYPOINT ["/sandbox"]

Download via GitHub CLI:

gh run download 22720770848 -n sandbox-binary

Extract from Docker:

docker run --rm cloudflare/sandbox:0.0.0-pr-437-2aecdff cat /container-server/sandbox > sandbox && chmod +x sandbox

github-actions[bot]

This comment was marked as outdated.

github-actions[bot]

This comment was marked as outdated.

github-actions[bot]

This comment was marked as outdated.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OpenCode Review

This PR adds a much-needed feature for backup exclusion patterns - the implementation looks solid overall. The approach is clean: new optional parameters flow through all three layers (SDK → DO → Container), with proper validation at each boundary.

Strengths:

  • Proper three-layer architecture flow (SDK validates, container executes)
  • Good default exclude patterns (node_modules, .git, dist, build, etc.)
  • Comprehensive E2E tests that verify actual behavior
  • Shell escaping for security (preventing injection)
  • Temporary exclude file cleanup
  • Clear changeset with user-focused description

A few technical considerations:

The duplicate validation between packages/sandbox/src/sandbox.ts:192-213 and packages/sandbox-container/src/handlers/backup-handler.ts:24-42 follows the pattern of defense-in-depth validation but could be consolidated into shared utilities since the logic is identical.

The control character regex /[\u0000-\u001f\u007f]/ is correctly implemented in both places - this covers C0 control chars plus DEL, which is appropriate for shell safety.

The E2E tests properly verify end-to-end behavior rather than just mocking - they create actual files, exclude patterns, and verify the restored state. This gives good confidence the feature works as intended.

Minor improvement opportunities:

  • Consider extracting the control character validation to @repo/shared since it's duplicated
  • The temporary exclude file cleanup could benefit from explicit error handling (currently just logs warnings)

Documentation consideration:
The feature is well-documented in the type definitions, but the Cloudflare docs should be updated to include the new exclude and excludeDefaults parameters in the backup API documentation.

Overall this is a clean, well-tested implementation that follows the project's patterns. Ready to merge.

@ghostwriternr ghostwriternr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only overarching issue I have with this PR is that ideally, this should behave similar to how most unix tools behave, which is gitignore, if present, is respected by default, but can be disabled with a flag. And there's an explicit flag for passing a list of paths to ignore. Us maintaining a list of "default" paths to ignore imo is definitely not a good path to pursue.

whoiskatrin and others added 6 commits March 7, 2026 12:47
This adds end-to-end support for backup exclude patterns so users can
skip dependency and build directories during createBackup. It also adds
an excludeDefaults option for common paths and covers both exclude and
default excludes with backup workflow E2E tests.
Use regex for control character detection in the SDK layer, matching
the pattern already used for backup name validation. Add the same
control character check to the container handler for defense-in-depth.
Log warnings on exclude file cleanup failures instead of silently
swallowing errors.
@cloudflare cloudflare deleted a comment from ask-bonk Bot Mar 7, 2026
@cloudflare cloudflare deleted a comment from ask-bonk Bot Mar 7, 2026
@github-actions

github-actions Bot commented Mar 7, 2026 •

Copy link
Copy Markdown
Contributor

🐳 Docker Images Published

Variant Image
Default cloudflare/sandbox:0.0.0-pr-437-9bdedbc
Python cloudflare/sandbox:0.0.0-pr-437-9bdedbc-python
OpenCode cloudflare/sandbox:0.0.0-pr-437-9bdedbc-opencode
Musl cloudflare/sandbox:0.0.0-pr-437-9bdedbc-musl
Desktop cloudflare/sandbox:0.0.0-pr-437-9bdedbc-desktop

Usage:

FROM cloudflare/sandbox:0.0.0-pr-437-9bdedbc

Version: 0.0.0-pr-437-9bdedbc


📦 Standalone Binary

For arbitrary Dockerfiles:

COPY --from=cloudflare/sandbox:0.0.0-pr-437-9bdedbc /container-server/sandbox /sandbox
ENTRYPOINT ["/sandbox"]

Download via GitHub CLI:

gh run download 22848212875 -n sandbox-binary

Extract from Docker:

docker run --rm cloudflare/sandbox:0.0.0-pr-437-9bdedbc cat /container-server/sandbox > sandbox && chmod +x sandbox

@whoiskatrin

Copy link
Copy Markdown
Contributor Author

/bonk check why the tests are failing and fix it

ask-bonk Bot and others added 2 commits March 7, 2026 14:26
mksquashfs -ef matches patterns containing '/' against the full
absolute source path, not relative to the source directory root.
The git ls-files output was relative, so no files were excluded.
Co-authored-by: whoiskatrin <whoiskatrin@users.noreply.github.com>
@ask-bonk

ask-bonk Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Two E2E backup tests were failing:

  • "should respect gitignore rules by default"
  • "should resolve nested gitignore rules from the backup directory context"

Root cause: mksquashfs -ef (exclude file) matches patterns containing / against the full absolute filesystem path, not paths relative to the source directory root. The resolveGitignoreExcludePatterns method was writing relative paths from git ls-files (e.g., node_modules/a.txt) into the exclude file, but mksquashfs needed absolute paths (e.g., /workspace/.../app/node_modules/a.txt) to match correctly.

Fix (packages/sandbox-container/src/services/backup-service.ts:319-337): Convert the relative paths returned by git ls-files to absolute paths by joining them with the normalized backup directory. The .git exclude entry is also converted to an absolute path for consistency.

github run

Emit both direct and sticky mksquashfs exclude patterns so
.gitignore-derived paths are excluded regardless of how the
source directory is rooted in the archive.
Switch from newline to null-byte delimiters when listing gitignored
files to handle paths containing spaces, quotes, and non-ASCII
characters. Remove .git from hardcoded excludes since git ls-files
already omits it.
@whoiskatrin

Copy link
Copy Markdown
Contributor Author

Closing to reopen as a cleaner PR with focused review

@whoiskatrin whoiskatrin closed this Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants