Skip to content

Add .deployignore support to Site Sync#2955

Open
ivan-ottinger wants to merge 6 commits intotrunkfrom
stu-16-add-deployignore-to-site-sync
Open

Add .deployignore support to Site Sync#2955
ivan-ottinger wants to merge 6 commits intotrunkfrom
stu-16-add-deployignore-to-site-sync

Conversation

@ivan-ottinger
Copy link
Copy Markdown
Contributor

@ivan-ottinger ivan-ottinger commented Apr 1, 2026

Related issues

How AI was used in this PR

AI-assisted implementation with human iteration and review of all changes, architecture decisions, and edge cases. I have manually tested the changes as well.

Proposed Changes

Follow-up to #2924, which added .deployignore support for Preview Sites. This PR extends it to Site Sync (push to WordPress.com / Pressable).

  • Add additionalDefaults parameter to createDeployIgnoreFilter so the sync path can include Studio-internal exclusions (database, db.php, debug.log, sqlite-database-integration, cache) alongside the base defaults
  • Sync tree UI: Update listLocalFileTree and shouldExcludeFromSync to use the deploy-ignore filter. Files matching .deployignore patterns are hidden from the sync dialog. Dotfile hiding is preserved as a separate UI-only check
  • Sync push/export: Add optional deployIgnore field to ExportOptions, used by DefaultExporter.addWpContent() alongside existing hardcoded exclusions (isExactPathExcluded, isPathExcludedByPattern). Local backup export is unaffected (no filter passed)
  • meta.json filtering: Filter the plugin and theme lists in meta.json against the deploy-ignore filter. Without this, the server-side import would reinstall excluded plugins from WordPress.org even though their files were excluded from the archive
  • Rename SYNC_EXCLUSIONS to SYNC_ADDITIONAL_DEFAULTS — items already covered by deploy-ignore defaults (.git, node_modules, .DS_Store, Thumbs.db) are removed, keeping only Studio-internal items
  • Downgrade ignore package from v7 to v5 to match the rest of the dependency tree and avoid TypeScript type conflicts between different major versions

Testing Instructions

Tip

It is probably easier to ask your AI assistant to perform the steps 2 and 3 for you, so you don't have to create the testing files manually.

  1. Create a local site in Studio
  2. Add a .deployignore file at the site root (e.g., ~/Studio/my-site/.deployignore) with the following content:
    # Ignore vendor dependencies in my-plugin, except important-lib
    wp-content/plugins/my-plugin/vendor/*
    !wp-content/plugins/my-plugin/vendor/important-lib
    
    # Ignore all log files
    *.log
    
    # Ignore old uploads
    wp-content/uploads/2024
    
    # Ignore a specific plugin
    wp-content/plugins/wordpress-seo
    
  3. Create matching test files/folders in the site's wp-content:
    # Plugin with build artifacts
    mkdir -p wp-content/plugins/my-plugin/vendor/some-lib
    mkdir -p wp-content/plugins/my-plugin/vendor/important-lib
    echo '<?php // plugin entry' > wp-content/plugins/my-plugin/my-plugin.php
    echo '<?php // vendor file' > wp-content/plugins/my-plugin/vendor/some-lib/autoload.php
    echo '<?php // important' > wp-content/plugins/my-plugin/vendor/important-lib/loader.php
    echo 'build log' > wp-content/plugins/my-plugin/build.log
    
    # .git and node_modules inside the plugin (built-in defaults)
    mkdir -p wp-content/plugins/my-plugin/.git
    echo 'ref: refs/heads/main' > wp-content/plugins/my-plugin/.git/HEAD
    mkdir -p wp-content/plugins/my-plugin/node_modules/some-package
    echo '{"name":"some-package"}' > wp-content/plugins/my-plugin/node_modules/some-package/package.json
    
    # Old and new uploads
    mkdir -p wp-content/uploads/2024
    echo 'old photo' > wp-content/uploads/2024/photo.jpg
    mkdir -p wp-content/uploads/2025
    echo 'new photo' > wp-content/uploads/2025/photo.jpg
    
  4. Install the wordpress-seo plugin on the site
  5. Connect the local site to a target remote site (WordPress.com or Pressable)
  6. Consider checking the target site to confirm it does not yet include any directories/files we want to ignore during the sync.
  7. Open the Sync dialog and verify:
    • wordpress-seo plugin is hidden from the tree
    • akismet and my-plugin are still visible
    • uploads/2024 directory is hidden
    • uploads/2025 is still visible
  8. Push to WordPress.com / Pressable and verify (e.g through a SSH connection to the WoA site):
    • vendor/some-lib/ is excluded from the push
    • vendor/important-lib/ is included (negation pattern)
    • *.log files are excluded
    • uploads/2024/ is excluded, uploads/2025/ is present
    • wordpress-seo plugin is excluded and not reinstalled by the server
  9. Verify that .git and node_modules inside my-plugin are excluded by built-in defaults
  10. Verify that site export (backup) is unaffected by .deployignore

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

Integrate the deploy-ignore filter (from PR #2924) into the Site Sync
flow. Files matching .deployignore patterns are now hidden from the
sync tree UI and excluded from the push archive.

- Add additionalDefaults parameter to createDeployIgnoreFilter for
  sync-specific Studio-internal exclusions
- Update shouldExcludeFromSync to use the ignore filter alongside
  the existing dotfile check
- Thread the deploy-ignore filter through listLocalFileTree recursion
- Pass the filter via ExportOptions to DefaultExporter for archive
  filtering during sync push
- Downgrade ignore package from v7 to v5 to match the rest of the
  dependency tree and avoid TypeScript type conflicts
@ivan-ottinger ivan-ottinger self-assigned this Apr 1, 2026
"date-fns": "^3.3.1",
"fast-deep-equal": "^3.1.3",
"ignore": "^7.0.5",
"ignore": "^5.3.2",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have made this change because other packages we are already using in Studio rely on the ignore v5. This version provides everything we need.

Using v7 would require several workarounds that would make the code less maintainable and more difficult to read

When specificSelectionPaths is undefined, the exporter reads wp-content
from disk directly. Top-level directories like wordpress-seo need to be
checked against the deploy-ignore filter before archiving, not just
their children in the callback.
The server-side import uses meta.json to install plugins/themes from
WordPress.org. Without filtering this list, excluded plugins would be
reinstalled by the server even though their files were excluded from
the archive.
Comment on lines +306 to +317
studioJson.plugins = this.options.deployIgnore
? plugins.filter(
( p: StudioJsonPluginOrTheme ) =>
! this.options.deployIgnore!.ignores( `wp-content/plugins/${ p.name }` )
)
: plugins;
studioJson.themes = this.options.deployIgnore
? themes.filter(
( t: StudioJsonPluginOrTheme ) =>
! this.options.deployIgnore!.ignores( `wp-content/themes/${ t.name }` )
)
: themes;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These changes are required because otherwise the .deployignored plugins/themes would be reinstalled on the target site.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Extends existing .deployignore support to Studio’s Site Sync flow (sync tree UI + push/export), ensuring ignored files are consistently hidden/excluded and that meta.json doesn’t re-trigger server-side reinstalls of excluded plugins/themes.

Changes:

  • Adds additionalDefaults support to the shared deploy-ignore filter and updates sync defaults to use it.
  • Updates Sync tree listing/exclusion logic to rely on the deploy-ignore filter (while keeping dotfile hiding UI-only).
  • Passes deploy-ignore filtering through the export pipeline and filters meta.json plugin/theme lists accordingly; downgrades ignore to v5 to avoid type conflicts.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tools/common/package.json Downgrades ignore dependency to ^5.3.2.
tools/common/lib/deploy-ignore.ts Adds additionalDefaults parameter to createDeployIgnoreFilter.
package-lock.json Updates lockfile entries to reflect ignore@5.3.2 usage.
apps/studio/src/modules/sync/lib/tree-utils.ts Reworks sync exclusion logic to use a deploy-ignore filter + dotfile hiding.
apps/studio/src/modules/sync/lib/ipc-handlers.ts Creates deploy-ignore filter during push export and passes it into ExportOptions.
apps/studio/src/modules/sync/constants.ts Renames/adjusts sync exclusion defaults to Studio-internal items only.
apps/studio/src/lib/import-export/export/types.ts Adds optional deployIgnore?: Ignore to ExportOptions.
apps/studio/src/lib/import-export/export/exporters/default-exporter.ts Applies deploy-ignore filtering during wp-content archive creation and filters meta.json plugins/themes.
apps/studio/src/ipc-handlers.ts Updates listLocalFileTree to build/reuse deploy-ignore filter when listing sync tree.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ivan-ottinger ivan-ottinger marked this pull request as ready for review April 1, 2026 13:00
@ivan-ottinger ivan-ottinger requested a review from a team April 1, 2026 13:02
@fredrikekelund
Copy link
Copy Markdown
Contributor

Noting that #3010 changed a lot of the sync logic on trunk. The CLI now also supports sync, and a lot of the internals moved to tools/common. We should update this PR accordingly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants