feat: Initial Claude skills for websimple-devops
This commit is contained in:
214
references/wp-local-site.md
Normal file
214
references/wp-local-site.md
Normal file
@@ -0,0 +1,214 @@
|
||||
# WP Local Site
|
||||
|
||||
Use this skill for local WordPress site lifecycle operations. For project naming and derived values, use `references/wp-project.md`. For stack/host environment assumptions, use `references/websimple-stack.md`. For Composer-managed plugins/themes, use `references/wp-composer.md`.
|
||||
|
||||
## Derived values
|
||||
|
||||
For project slug `${slug}`, use `references/wp-project.md` conventions:
|
||||
|
||||
- Local project path: `${WP_LOCAL_ROOT_PATH}/${slug}`
|
||||
- Local database name: `wp_${slug}`
|
||||
- Local site URL: `${WEBSIMPLE_STACK_PROTOCOL}://${slug}.${WEBSIMPLE_STACK_DOMAIN}`
|
||||
- Default local DB table prefix: `wp_`, unless the production/source instance uses a different prefix
|
||||
- Repository URL: `https://gitea.websimple.com/wp-sites/${slug}`
|
||||
|
||||
Resolve project values with `references/wp-project.md`; do not hard-code local paths, protocol, or domain.
|
||||
|
||||
## Safety
|
||||
|
||||
- Prefer read-only checks before creating, deleting, or resetting anything.
|
||||
- Ask before destructive actions such as dropping a database, deleting a project directory, or overwriting local files.
|
||||
- Use recoverable deletion where practical. If shelling out, prefer moving to the user's trash over permanent removal.
|
||||
- Never delete source-controlled project-specific plugins/themes as part of Composer repair; use the `references/wp-composer.md` integrity guidance.
|
||||
- Treat remote hosts as read-only unless a future approved workflow says otherwise.
|
||||
|
||||
## Create local site skeleton
|
||||
|
||||
A local site creation workflow should generally:
|
||||
|
||||
1. Resolve `${slug}` and derived values with `references/wp-project.md`.
|
||||
2. Verify `${WP_LOCAL_ROOT_PATH}` exists.
|
||||
3. Verify `${WP_LOCAL_ROOT_PATH}/${slug}` does not already exist, or ask how to proceed.
|
||||
4. Clone or create the project directory from `https://gitea.websimple.com/wp-sites/${slug}`.
|
||||
5. Create the local database `wp_${slug}` using host `mysql` credentials from `~/.my.cnf`.
|
||||
6. Determine the DB table prefix: use `wp_` by default, or the production/source prefix when provisioning from an existing site.
|
||||
7. Run `wp core config` with only the database name and table prefix when WP-CLI defaults provide DB host/user/password.
|
||||
8. Run Composer install if the project uses Composer.
|
||||
9. Either run `wp core install` for a fresh local site or synchronize/import from an existing remote site.
|
||||
10. Verify local URL and WP-CLI access.
|
||||
|
||||
Example database creation command:
|
||||
|
||||
```bash
|
||||
mysql -e 'CREATE DATABASE `wp_example` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'
|
||||
```
|
||||
|
||||
Use the real derived DB name; quote identifiers safely.
|
||||
|
||||
## WP core config
|
||||
|
||||
The host should have WP-CLI defaults in `~/.wp-cli/config.yml` for DB host, user, and password. Local provisioning should normally only specify the DB name:
|
||||
|
||||
```bash
|
||||
wp core config --dbname="wp_${slug}" --dbprefix="wp_"
|
||||
```
|
||||
|
||||
Run from the local project path. Do not duplicate DB host/user/password flags unless defaults are missing or the user explicitly asks.
|
||||
|
||||
Use `wp_` as the default table prefix for new local sites. When provisioning from production/staging, detect and preserve the source table prefix if it differs from `wp_`; the imported database and local `wp-config.php` prefix must agree.
|
||||
|
||||
## WP core install
|
||||
|
||||
Use `wp core install` only when creating a fresh local site without importing an existing database. Do not run it before a remote DB import because the import will replace the local tables anyway.
|
||||
|
||||
Example for a new local site:
|
||||
|
||||
```bash
|
||||
wp core install \
|
||||
--url="${WEBSIMPLE_STACK_PROTOCOL}://${slug}.${WEBSIMPLE_STACK_DOMAIN}" \
|
||||
--title="${slug}" \
|
||||
--skip-email
|
||||
```
|
||||
|
||||
`~/.wp-cli/config.yml` contains default admin user, email, and password values, so do not pass `--admin_user`, `--admin_email`, or `--admin_password` unless the user asks for custom values. Avoid inventing real production credentials.
|
||||
|
||||
## Standard admin user
|
||||
|
||||
Local sites should have the standard admin user from `~/.wp-cli/config.yml`. After installing or importing a site, check whether that user exists. If missing, create it using the configured default admin values.
|
||||
|
||||
Do not hard-code admin credentials in commands. Do not echo the password in chat or log summaries. Refer to credentials by variable name only.
|
||||
|
||||
The exact YAML shape varies by user setup. Inspect the file before constructing any command, so the keys you read match the keys that actually exist:
|
||||
|
||||
```bash
|
||||
# Inspect — show keys only, not the password value
|
||||
grep -E '^[[:space:]]*(user_login|user_email|user_pass|role)' ~/.wp-cli/config.yml \
|
||||
| sed 's/\(user_pass:\).*/\1 <redacted>/'
|
||||
```
|
||||
|
||||
Two common shapes:
|
||||
|
||||
```yaml
|
||||
# Shape A — defaults nested under `user create:`
|
||||
user create:
|
||||
user_login: someuser
|
||||
user_email: someone@example.com
|
||||
user_pass: <set>
|
||||
role: administrator
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Shape B — flat top-level keys consumed by custom commands
|
||||
admin_user: someuser
|
||||
admin_email: someone@example.com
|
||||
admin_password: <set>
|
||||
```
|
||||
|
||||
If the file uses Shape A, WP-CLI will already apply the defaults when `wp user create` runs without explicit flags. If it uses Shape B, the values have to be passed explicitly.
|
||||
|
||||
When `yq` is available, prefer it over hand-parsing:
|
||||
|
||||
```bash
|
||||
ADMIN_USER="$(yq '.["user create"].user_login // .admin_user' ~/.wp-cli/config.yml)"
|
||||
ADMIN_EMAIL="$(yq '.["user create"].user_email // .admin_email' ~/.wp-cli/config.yml)"
|
||||
# Keep ADMIN_PASSWORD only in the subshell that needs it; do not export or print it.
|
||||
```
|
||||
|
||||
If `yq` is not available and the YAML doesn't match a known shape, ask the user for the admin login and email rather than guessing — and have them provide the password via stdin (`read -s`) instead of an argument that would land in shell history.
|
||||
|
||||
Typical flow:
|
||||
|
||||
1. Inspect `~/.wp-cli/config.yml` and identify the admin user/email key names actually used.
|
||||
2. Check whether that user exists locally.
|
||||
3. Create the user only if missing.
|
||||
4. Grant the administrator role if needed.
|
||||
|
||||
```bash
|
||||
# Step 2–4 — assuming ADMIN_USER, ADMIN_EMAIL, ADMIN_PASSWORD are set in the current shell
|
||||
if ! wp user get "$ADMIN_USER" >/dev/null 2>&1; then
|
||||
wp user create "$ADMIN_USER" "$ADMIN_EMAIL" \
|
||||
--role=administrator \
|
||||
--user_pass="$ADMIN_PASSWORD"
|
||||
fi
|
||||
wp user set-role "$ADMIN_USER" administrator
|
||||
```
|
||||
|
||||
If `wp user create` works without the explicit `--user_pass` flag (Shape A in use), prefer that form so the password never appears on the command line.
|
||||
|
||||
## Synchronize from remote site
|
||||
|
||||
Synchronizing from a remote site means pulling production/staging state into the local site. Keep remote actions read-only: export/read/copy from remote is okay; writing to or mutating remote is not.
|
||||
|
||||
Typical flow:
|
||||
|
||||
1. Resolve local metadata with `references/wp-project.md` and remote metadata with `references/websimple-gitea.md` Actions variables, especially `WP_SITE_URL`.
|
||||
2. Confirm source remote URL/host and destination local path/database.
|
||||
3. Create/reset the local database only after confirmation.
|
||||
4. Detect the remote/source DB table prefix before export/import. Use `wp_` only if the source also uses `wp_` or the source prefix is unknown and no imported DB is involved.
|
||||
5. Export the remote database in a read-only way, preferably streaming to local instead of leaving files on the remote host.
|
||||
6. Import into local DB.
|
||||
7. Ensure local `wp-config.php` uses the same table prefix as the imported DB.
|
||||
8. Search-replace remote URLs to the derived local URL.
|
||||
9. Pull uploads/media from remote unless specified otherwise.
|
||||
10. Verify `siteurl` and `home` locally.
|
||||
|
||||
Preferred DB sync path: stream a compressed remote DB dump over SSH into the local MySQL client. Use this when both remote WP-CLI and local `mysql` are available:
|
||||
|
||||
```bash
|
||||
ssh "$REMOTE_SSH" 'cd "$REMOTE_PATH" && wp db export - --skip-plugins --skip-themes --single-transaction --quick --lock-tables=false | gzip -c' \
|
||||
| gunzip \
|
||||
| mysql "$LOCAL_DB_NAME"
|
||||
```
|
||||
|
||||
After DB import, run URL replacement locally:
|
||||
|
||||
```bash
|
||||
wp search-replace "$REMOTE_SITE_URL" "${WEBSIMPLE_STACK_PROTOCOL}://${slug}.${WEBSIMPLE_STACK_DOMAIN}" --all-tables --skip-columns=guid
|
||||
wp option get siteurl
|
||||
wp option get home
|
||||
```
|
||||
|
||||
Do not run `wp search-replace` on the remote site during local synchronization.
|
||||
|
||||
Preferred uploads sync path: use `rsync` over SSH and include `--delete` so local `wp-content/uploads/` matches remote exactly, unless the user asks to preserve extra local files. Websimple SSH usually requires an explicit port, so include the SSH transport option when needed:
|
||||
|
||||
```bash
|
||||
rsync -az --delete -e "ssh -p $REMOTE_SSH_PORT" "$REMOTE_SSH:$REMOTE_PATH/wp-content/uploads/" "wp-content/uploads/"
|
||||
```
|
||||
|
||||
If the SSH host alias already encodes the port in `~/.ssh/config`, the `-e "ssh -p ..."` option may be omitted. If remote uploads path differs, inspect the project before syncing. Be explicit when `--delete` will remove local-only upload files.
|
||||
|
||||
## Provision from existing project
|
||||
|
||||
When provisioning from an existing local or remote project:
|
||||
|
||||
1. Resolve local and remote metadata using `references/wp-project.md` and `references/websimple-gitea.md`.
|
||||
2. Confirm the source and destination clearly.
|
||||
3. Keep remote actions read-only.
|
||||
4. Import database/content only after confirming the target local DB and path.
|
||||
5. After import, replace remote URLs with the derived local site URL.
|
||||
6. Run small verification checks, such as `wp option get siteurl` and `wp option get home`.
|
||||
|
||||
## Delete/reset local site
|
||||
|
||||
A local delete/reset workflow may include:
|
||||
|
||||
- local project directory `${WP_LOCAL_ROOT_PATH}/${slug}`
|
||||
- local database `wp_${slug}`
|
||||
- generated/cache artifacts
|
||||
|
||||
Before deleting:
|
||||
|
||||
1. Show the resolved path, DB name, and local URL.
|
||||
2. Check whether the path exists and whether it has uncommitted Git changes.
|
||||
3. Ask for confirmation.
|
||||
4. Prefer backup/trash for files where practical.
|
||||
5. Drop the local DB only after explicit confirmation.
|
||||
|
||||
Example DB drop command after confirmation:
|
||||
|
||||
```bash
|
||||
mysql -e 'DROP DATABASE `wp_example`;'
|
||||
```
|
||||
|
||||
Use the real derived DB name; quote identifiers safely.
|
||||
Reference in New Issue
Block a user