From 3d07ceb59efdd2b957019e330c5b9ab8d8692646 Mon Sep 17 00:00:00 2001 From: "John R. D'Orazio" Date: Fri, 1 May 2026 02:00:54 +0200 Subject: [PATCH 1/2] docs: refresh deployment section for unified workflow + bump Next.js to 16 Two issues the README didn't reflect: 1. Tech-stack header said "Next.js 15"; package.json has been on ^16.2.4 for a while. 2. Deployment section described an outdated single-trigger workflow that only deployed to production on `release: published`, and listed a stale, partially-incorrect mix of secrets and variables. Updates: - Production / Staging Architecture section now lists all three subdomains (catholicdigitalcommons.org, staging.catholicdigitalcommons.org, cms.catholicdigitalcommons.org) and explains that staging shares the production WordPress backend. - Notes the proxy.ts noindex behavior so anyone reading the README understands why staging never appears in search results. - Documents that runtime env (WP_GRAPHQL_URL, WP_PREVIEW_SECRET) is configured in the Plesk panel, not in .env files on disk. Distinguishes that from NEXT_PUBLIC_SITE_URL which is baked into the client bundle at build time. GitHub Actions section rewritten for the unified deploy.yml: - Documents both triggers (release and workflow_dispatch with environment input) - Adds gh CLI examples for non-interactive deploys - Mentions the pr-build.yml required check - Reorganizes the required-config table into separate Secrets (credentials) and Variables (plain config) sections, listing all the entries the unified workflow actually reads: - secrets: VPS_HOST, VPS_USERNAME, VPS_SSH_KEY, WP_APP_USERNAME, WP_APP_PASSWORD - vars: WP_GRAPHQL_URL, WP_REST_URL, NEXT_PUBLIC_SITE_URL_PROD, NEXT_PUBLIC_SITE_URL_STAGING, VPS_APP_DIR, VPS_STAGING_APP_DIR, WP_THEME_DIR, WP_PLUGINS_DIR Note: assumes PR #50 (workflow unification) lands first. If the sequencing flips, the gh CLI command syntax in this README will be wrong until #50 merges. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 62 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index f52b3e7..f7eac15 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The official website for the **Catholic Digital Commons Foundation (CDCF)**, bui ## Tech Stack -- **Framework:** Next.js 15 (App Router, React Server Components) +- **Framework:** Next.js 16 (App Router, React Server Components) - **CMS:** WordPress (headless) with WPGraphQL + ACF + Polylang - **Styling:** Tailwind CSS v4 + custom CDCF brand system - **i18n:** next-intl (UI chrome) + Polylang (CMS content) @@ -289,32 +289,70 @@ You can set this up as a WordPress publish hook (e.g. via the WP Webhooks plugin ## Deployment -### Production Architecture +### Production and Staging Architecture -Production runs natively on a Plesk-managed server (no Docker) with two subdomains: +Production and staging both run natively on the same Plesk-managed server (no Docker) on three subdomains: -- **`catholicdigitalcommons.org`** — Next.js frontend (standalone build running via Node.js) +- **`catholicdigitalcommons.org`** — production Next.js frontend (standalone build, Node.js) +- **`staging.catholicdigitalcommons.org`** — staging Next.js frontend (separate standalone build, same Node.js) - **`cms.catholicdigitalcommons.org`** — WordPress admin backend (PHP-FPM managed by Plesk) -WordPress and Next.js share the same MariaDB instance already running on the server. Plesk manages Nginx, SSL certificates, and PHP-FPM. +**Staging shares the production WordPress backend.** That keeps the staging environment lightweight (no second WP install or DB), but it also means staging-only theme/plugin testing isn't possible — both environments see the same CMS code at any moment. The deploy workflow only ships the Next.js bundle to staging for that reason. -The Next.js app fetches content from WordPress via `WP_GRAPHQL_URL=https://cms.catholicdigitalcommons.org/graphql`. The WordPress theme's CORS headers (registered in `functions.php`) allow cross-origin GraphQL requests from the frontend subdomain. +`proxy.ts` sets `X-Robots-Tag: noindex, nofollow` on every response from any host other than `catholicdigitalcommons.org` / `www.catholicdigitalcommons.org`, so staging (and any preview / one-off subdomain) is never indexed by search engines. + +The Next.js apps fetch content from WordPress via `WP_GRAPHQL_URL=https://cms.catholicdigitalcommons.org/graphql`. The WordPress theme's CORS headers (registered in `functions.php`) allow cross-origin GraphQL requests from both the production and staging frontends. + +Per-environment runtime env vars (`WP_GRAPHQL_URL`, `WP_PREVIEW_SECRET`, etc.) are configured in the **Plesk panel** for each Node.js app, not in `.env.local` files on disk. `NEXT_PUBLIC_SITE_URL` is per-environment too but is **baked into the client bundle at build time** (different value per workflow run, see below). ### GitHub Actions CI/CD -The deploy workflow (`.github/workflows/deploy.yml`) triggers when a GitHub release is published. It builds the Next.js standalone output in CI, then SCPs the artifacts to the VPS (no repo clone needed on the server). +The deploy workflow (`.github/workflows/deploy.yml`) is unified for both environments: + +- **`release: published`** — automatically deploys to **production** +- **`workflow_dispatch`** — user picks `production` or `staging` (default: `staging`) + +Production-only steps (WP theme + plugin tarballs, plugin activation) are gated behind an environment check. Staging deploys ship only the Next.js bundle so they can't overwrite production WordPress code. + +**Triggering deploys from the command line** (no UI dropdown needed): + +```bash +# Deploy to staging (matches the dropdown default) +gh workflow run deploy.yml --ref main -f environment=staging + +# Deploy to production +gh workflow run deploy.yml --ref main -f environment=production + +# No -f → uses the workflow default (staging) +gh workflow run deploy.yml --ref main +``` + +A separate workflow (`.github/workflows/pr-build.yml`) runs `next build` on every pull request as a required check, so build-only failures (file-name conflicts, missing imports, type errors) are caught pre-merge instead of at deploy time. + +**Required GitHub repository configuration:** -**Required GitHub Secrets:** +Secrets (encrypted, used as credentials): | Secret | Description | |--------|-------------| -| `WP_GRAPHQL_URL` | WordPress GraphQL endpoint (e.g. `https://cms.catholicdigitalcommons.org/graphql`) | -| `WP_PREVIEW_SECRET` | Shared secret for preview/revalidation | | `VPS_HOST` | VPS IP address or hostname | | `VPS_USERNAME` | SSH username | | `VPS_SSH_KEY` | SSH private key for deployment | -| `VPS_APP_DIR` | Directory on the VPS where the Next.js standalone app runs | -| `WP_THEME_DIR` | WordPress theme directory (e.g. `/var/www/vhosts/.../wp-content/themes/cdcf-headless`) | +| `WP_APP_USERNAME` | WordPress application-password username (for plugin activation) | +| `WP_APP_PASSWORD` | WordPress application password | + +Variables (plain config, visible in workflow logs): + +| Variable | Description | +|----------|-------------| +| `WP_GRAPHQL_URL` | WordPress GraphQL endpoint (e.g. `https://cms.catholicdigitalcommons.org/graphql`) | +| `WP_REST_URL` | WordPress REST root (e.g. `https://cms.catholicdigitalcommons.org/wp-json`) | +| `NEXT_PUBLIC_SITE_URL_PROD` | Public URL of the production site (e.g. `https://catholicdigitalcommons.org`) | +| `NEXT_PUBLIC_SITE_URL_STAGING` | Public URL of the staging site (e.g. `https://staging.catholicdigitalcommons.org`) | +| `VPS_APP_DIR` | Production Next.js app directory on the VPS | +| `VPS_STAGING_APP_DIR` | Staging Next.js app directory on the VPS | +| `WP_THEME_DIR` | WordPress theme directory (e.g. `/var/www/vhosts/.../wp-content/themes`) | +| `WP_PLUGINS_DIR` | WordPress plugins directory (e.g. `/var/www/vhosts/.../wp-content/plugins`) | ### Docker (Local Development Only) From 46f049738d681f4863ea029e08ab8b2b8fe75f87 Mon Sep 17 00:00:00 2001 From: "John R. D'Orazio" Date: Fri, 1 May 2026 02:04:53 +0200 Subject: [PATCH 2/2] docs: add Next.js / React / TypeScript / Tailwind / build badges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five badges in a row under the title: - Next.js, React, TypeScript, Tailwind CSS — all read from package.json on main via shields.io's /github/package-json/dependency-version endpoint, so they update automatically whenever dependencies bump (no more drift like the "Next.js 15" header that was wrong for months) - PR Build — the new pr-build.yml workflow status on main, so anyone glancing at the README sees green/red at a glance Each links to the project's homepage. No license badge: package.json has no license field and there's no LICENSE file in the repo. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f7eac15..4c726cf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Catholic Digital Commons Foundation — Website CMS +[![Next.js](https://img.shields.io/github/package-json/dependency-version/CatholicOS/cdcf-website/next?label=Next.js&logo=nextdotjs&color=000000)](https://nextjs.org) +[![React](https://img.shields.io/github/package-json/dependency-version/CatholicOS/cdcf-website/react?label=React&logo=react&color=61DAFB&logoColor=white)](https://react.dev) +[![TypeScript](https://img.shields.io/github/package-json/dependency-version/CatholicOS/cdcf-website/dev/typescript?label=TypeScript&logo=typescript&color=3178C6&logoColor=white)](https://www.typescriptlang.org) +[![Tailwind CSS](https://img.shields.io/github/package-json/dependency-version/CatholicOS/cdcf-website/dev/tailwindcss?label=Tailwind%20CSS&logo=tailwindcss&color=06B6D4&logoColor=white)](https://tailwindcss.com) +[![PR Build](https://github.com/CatholicOS/cdcf-website/actions/workflows/pr-build.yml/badge.svg?branch=main)](https://github.com/CatholicOS/cdcf-website/actions/workflows/pr-build.yml) + The official website for the **Catholic Digital Commons Foundation (CDCF)**, built with Next.js and headless WordPress. This site serves as the public-facing portal for the foundation, showcasing projects, community resources, news, and governance information. ## Tech Stack