---
title: Self-hosted overlay
---

`--channel=self-hosted` changes Plugin Check so a self-updater is allowed, and the scaffold command writes `Update URI` into the plugin header. The overlay is not part of this plugin's runtime.

## What the overlay adds

The overlay is one workflow file:

<!-- wp:docspress/file-tree {"root":"overlays/self-hosted/","tree":".github/workflows/\n  plugin-check.yml","caption":"Replaces the root Plugin Check workflow in a generated plugin."} /-->

The root workflow and the overlay workflow are the same except the overlay passes `exclude_checks: plugin_updater` into `linchpin/actions` Plugin Check.

<!-- wp:docspress/colorful-code {"language":"yaml","filename":"overlays/self-hosted/.github/workflows/plugin-check.yml","code":"with:\n  build_dir: ./build/plugin-scaffold\n  build_command: bash scripts/build.sh\n  php_version: '8.3'\n  exclude_directories: vendor,node_modules\n  exclude_checks: plugin_updater","highlightedLines":"6","showLineNumbers":true,"caption":"The root .github/workflows/plugin-check.yml omits exclude_checks."} /-->

## Update URI

`overlays/README.md` states that the CLI also writes `Update URI` into the plugin header. This repository does not contain the header line or the writer. The generated plugin header is where that field appears after `--channel=self-hosted`.

<!-- wp:docspress/callout {"tone":"note","title":"Uninstall and deactivation keep data","content":"<p><code>Install::deactivate()</code> is empty and comments that data stays. <code>uninstall.php</code> only guards on <code>WP_UNINSTALL_PLUGIN</code>. A self-updater does not change that.</p>","collapsible":false} /-->
