Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ newspack-workspace is the Newspack monorepo. It contains all product plugins, th
- `plugins/<name>/` - Product plugins (12 total).
- `themes/<name>/` - Themes (newspack-theme, newspack-block-theme).
- `packages/<name>/` - Shared libraries (scripts, components, colors, icons).
- `repos/plugins/<name>/`, `repos/themes/<name>/` - Standalone/local plugin and theme checkouts that live outside the monorepo (e.g. private or customer-specific plugins, `newspack-manager`, licensed WooCommerce extensions). The `repos/plugins` and `repos/themes` directories are tracked (`.gitkeep`); anything you drop inside them is gitignored. Mounted at `/newspack-repos` and symlinked into the active site (`wp-content/plugins/`, `wp-content/themes/`) by `bin/link-repos.sh`. **Any directory works with no registration** - `n` commands (`n build`, `n composer`, `n watch`, cwd-detection) discover `repos/` checkouts by path, so there's no need to edit `bin/repos.sh`. If a name also exists in the monorepo `plugins/`/`themes/`, the **tracked copy wins** and the `repos/` duplicate is skipped. Workflow: drop a real checkout in (clone/unzip directly, or `git worktree add`), build it, then `n restart`/`n start` to pick it up. A symlink *inside* `repos/` pointing outside the workspace will dangle in the container - use a real directory.
- `repos/plugins/<name>/`, `repos/themes/<name>/` - Standalone/local plugin and theme checkouts that live outside the monorepo (e.g. private or customer-specific plugins, `newspack-manager`, licensed WooCommerce extensions). The `repos/plugins` and `repos/themes` directories are tracked (`.gitkeep`); anything you drop inside them is gitignored. Mounted at `/newspack-repos` and symlinked into the active site (`wp-content/plugins/`, `wp-content/themes/`) by `bin/link-repos.sh`. **Any directory works with no registration** - `n` commands (`n build`, `n composer`, `n watch`, cwd-detection) discover `repos/` checkouts by path, so there's no need to edit `bin/repos.sh`. If a name also exists in the monorepo `plugins/`/`themes/`, the **tracked copy wins** and the `repos/` duplicate is skipped. Workflow: drop a real checkout in (clone/unzip directly, or `git worktree add`), build it, then `n restart`/`n start` to pick it up. A symlink *inside* `repos/` pointing outside the workspace will dangle in the container - use a real directory. For the two private, non-monorepo plugins every install needs (`newspack-manager`, `newspack-manager-admin`), `n setup-repos` clones and builds them into `repos/plugins/` in one shot - see [First-Time Setup](#first-time-setup).

Each directory is a standalone WordPress plugin/theme that can be zipped and installed independently.

Expand Down Expand Up @@ -125,9 +125,20 @@ cp default.env .env # Create local config
n start # Launch containers
n install # Install WordPress
n ci-build all # Build all projects
n setup-repos # Clone + build the private managed plugins (optional)
n setup --yes # Bootstrap site with content and plugins
```

`n setup-repos` pulls in the two plugins that can't live in this monorepo because
they're in separate private repos: `newspack-manager` and `newspack-manager-admin`.
It clones them into `repos/plugins/` (auth via the GitHub CLI, so `gh auth login`
first), skipping any that are already present, then builds each through the same
standalone-repo path as `n build <name>` and symlinks them into the running site
via `bin/link-repos.sh` - so they show up in the plugins list ready to activate,
no restart needed. Pass `--env <name>` to build and link into an isolated
environment instead of the main site. Omit this step if you don't need the
Manager plugins locally.

### Building Projects
```bash
n build # Build current project (from within repo folder)
Expand Down
1 change: 1 addition & 0 deletions bin/env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ services:
- .:/newspack-monorepo
- ./plugins:/newspack-plugins
- ./themes:/newspack-themes
- ./repos:/newspack-repos
${worktree_volumes} - ./envs/${env_name}/html:/var/www/html
- ./manager-html:/var/www/manager-html
- ./additional-sites-html:/var/www/additional-sites-html
Expand Down
8 changes: 8 additions & 0 deletions bin/repos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ newspack_themes=(
"newspack-block-theme"
)

# Plugins that live in their own private repos outside this monorepo, so a fresh
# checkout has no copy of them. `n setup-repos` clones these into repos/plugins/
# (auth via gh) where the standard repos/ convention picks them up.
managed_plugins=(
"newspack-manager"
"newspack-manager-admin"
)

woocommerce_plugins=(
"woocommerce"
"woocommerce-gateway-stripe"
Expand Down
40 changes: 40 additions & 0 deletions bin/setup-repos.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
#
# Clone the non-monorepo "managed" plugins (newspack-manager,
# newspack-manager-admin) into repos/plugins/ for local development.
#
# These plugins live in private Automattic repos and can't be tracked in this
# monorepo, so a fresh checkout has no copy of them. This pulls them in one
# shot via the GitHub CLI (which carries your auth for the private repos),
# idempotently: an existing checkout is left untouched.
#
# Cloning only -- building and symlinking are handled by the caller
# (`n setup-repos`) through the standard build-repos.sh / link-repos.sh paths,
# the same ones `n build <name>` and container startup use.
#
# Usage: n setup-repos

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
source "$SCRIPT_DIR/repos.sh"

if ! command -v gh &>/dev/null; then
echo "Error: the GitHub CLI (gh) is required to clone the private managed repos." >&2
echo "Install it from https://cli.github.com/, then run 'gh auth login'." >&2
exit 1
fi

DEST="$ROOT_DIR/repos/plugins"
mkdir -p "$DEST"

for name in "${managed_plugins[@]}"; do
target="$DEST/$name"
if [ -d "$target" ]; then
echo "✓ $name already present in repos/plugins/, skipping clone."
continue
fi
echo "Cloning Automattic/$name into repos/plugins/$name..."
gh repo clone "Automattic/$name" "$target"
done
30 changes: 30 additions & 0 deletions n
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,34 @@ case $1 in
setup-newspack-network)
docker exec $DOCKER_IT $USER_COMMAND $TARGET_CONTAINER sh -c "/var/scripts/setup-newspack-network.sh"
;;
setup-repos)
shift
repos_container="$TARGET_CONTAINER"
while [[ $# -gt 0 ]]; do
if [[ "$1" == "--env" ]]; then
if [[ $# -lt 2 || "$2" == --* ]]; then
echo "Error: --env requires an environment name." >&2
echo "Usage: n setup-repos [--env ENV_NAME]" >&2
exit 1
fi
repos_container=$(echo "newspack_env_${2}" | tr '-' '_')
shift 2
else
echo "Unknown argument: $1" >&2
echo "Usage: n setup-repos [--env ENV_NAME]" >&2
exit 1
fi
done
# Clone happens on the host (gh carries the auth for the private repos)
# into the shared repos/plugins/ dir; build + symlink happen in the
# container via the standard repos/ paths. Abort if the clone failed so
# we don't try to build a checkout that isn't there.
"$NABSPATH/bin/setup-repos.sh" || exit $?
for managed in "${managed_plugins[@]}"; do
docker exec $DOCKER_IT $USER_COMMAND "$repos_container" sh -c "/var/scripts/build-repos.sh $managed"
done
docker exec $DOCKER_IT $USER_COMMAND "$repos_container" sh -c "/var/scripts/link-repos.sh"
;;
worktree)
"$NABSPATH/bin/worktree.sh" "${@:2}"
;;
Expand Down Expand Up @@ -508,6 +536,8 @@ case $1 in
echo " setup-newspack-network Set up Newspack Network Docker environment."
echo ""
echo "Repository Management:"
echo " setup-repos [--env name] Clone the private managed plugins (newspack-manager,"
echo " newspack-manager-admin) into repos/plugins/ and build them."
echo " pull Pull the latest changes for all repositories."
echo " branch [name] Switch all repositories to the specified branch."
echo " trunk Switch all repositories to the trunk branch."
Expand Down
Loading