Deploy & distribute
A professional Corex setup keeps each website in its own Azure DevOps repo and ships Corex framework updates separately. This guide covers the per-site repo, deployment, branch policies, and update packaging.
Per-site repo + App Service
Section titled “Per-site repo + App Service”- Each website is its own Azure DevOps repo (generated by
make:site). The Corex framework lives in its own repo and is updated separately — client teams never edit it. - Host on Azure App Service + Azure Database for MySQL.
- Deploy from
develop(staging) andmain(production), or from tags. - Secrets go in App Service application settings — never a committed
.envorwp-config.php. Uploads are not committed. - Rollback: redeploy the previous tag / App Service deployment slot.
Branch policies
Section titled “Branch policies”Protect main and develop; require, before merge:
- a pull-request review,
- a green pipeline (build + the headless tests),
wp corex compliance:check— fails the PR if it touches Corex framework folders,wp corex readinessbefore release or client-site kickoff.
# In CI: fail the build if a client PR edited the Corex framework.wp corex compliance:check --files="$(git diff --name-only origin/develop...HEAD | paste -sd,)"The check passes client plugin/theme/docs/specs changes and fails (naming them) any change under a Corex framework
folder. An approved framework change uses --allow-framework.
Readiness reporting
Section titled “Readiness reporting”wp corex readinessThe readiness report covers runtime add-on gating, release metadata, CI/security, make:site validation, deployment, component coverage, Free/Core boundaries, and multi-agent workflow safety. It reports exact evidence and a next action for every non-pass row.
Metadata mismatches include the path, field, expected release, and actual value. Explicit policy exceptions, such as the npm workspace root version being independent from Corex release tags, remain visible in the report.
environment-gated is not a pass. It means the result depends on an external environment or repository setting,
such as wp-env/browser availability, branch protection, required checks, or secret scanning. Verify those gates in
their owning environment before release.
Deploying the first client site
Section titled “Deploying the first client site”Deploy a built, flat WordPress tree instead:
- Assemble a clean tree in
dist/: WordPress core + a real (non-symlinked)wp-contentcontaining the CoreX framework theme/plugins/add-ons you actually use and the generated client theme/plugin as real folders. - Include production vendor + built assets.
npm run buildbuilds the assets;npm run build:dist(below) installs the production Composer packages insidedist/wp-content/vendor/itself, so do not runcomposer install --no-devon the checkout. - Exclude dev-only files:
node_modules, tests, caches,.env, SQL dumps, and local agent state (.corex/,PROGRESS.md-style working files are repo-only). - Migrate the database separately (export local → import to the target), run a site-URL search-replace
(
wp search-replace http://acme.local https://acme.example), and sync uploads (wp-content/uploads/). - Provide the target’s own
wp-config.php(its DB creds and salts) — never ship local config. - Keep a rollback: snapshot the previous release + a DB export before swapping.
On cPanel / shared hosting, the uploaded tree must be this built dist/ artifact (real folders), not the
local symlinked/junctioned wp/. The shared-host profile below records the no-symlink upload shape.
build:dist + Azure (spec 061)
Section titled “build:dist + Azure (spec 061)”There is now a first-class builder for the flat artifact:
npm run build:dist -- --client=acme # assemble dist/ from repo source (de-symlinked, dev files stripped)npm run verify:dist # the package loads the framework; no dev or host-owned files; manifest validIt writes dist/ (git-ignored, never committed) with a corex-release.json manifest. The verifier includes the
packaged core plugin in a PHP process of its own and fails unless it finds the packaged autoloader and a class from
every packaged plugin, add-on and the CLI package loads. CI split: GitHub Actions
runs PR/code-quality gates; Azure Pipelines (azure-pipelines.yml) builds dist/ and deploys it over SFTP from
release tags, with credentials in Azure secrets and production runtime files protected. Full guides:
docs/en/05-deployment/shared-host-dist.md and docs/en/05-deployment/azure-pipelines.md.
A host with no command line (spec 107)
Section titled “A host with no command line (spec 107)”On shared hosting where the only ways in are a file manager and wp-admin, a release is not uploaded over the
running site. npm run build:dist -- --client=acme --zip writes one package, and the site installs it from
CoreX → Releases: the package is checked against its own description, each folder the release owns is replaced
whole, the database step runs before visitors are let back in, and the previous release is kept to go back to. A
plugin that is neither CoreX’s nor the site’s own travels in the package when it is named with
--with-plugin=<folder>. A site that sets DISALLOW_FILE_MODS allows it with
define( 'COREX_ALLOW_RELEASE_INSTALL', true ); in wp-config.php.
It is not a backup and it downloads nothing. Full guides:
docs/en/05-deployment/releases-from-the-admin.md and, for the one installation that is still done by hand,
docs/en/05-deployment/first-installation-by-hand.md.
A WordPress-aware
wp corex package:sitewrapper (calling the same builder) is on the backlog; the framework-onlypackage:updatecommand is documented under Packaging a Corex update.
Deployment profiles
Section titled “Deployment profiles”Spec 055 records these profiles in the readiness check:
| Profile | Package shape | Commands | Blocker status |
|---|---|---|---|
minimal | Corex source, vendor, and built assets | composer install --no-dev --optimize-autoloader; npm run build | No known blocker |
standard | Tagged Corex release with core plugins and theme | composer validate --no-check-publish; composer test; npm run build | No known blocker |
full | First-party Corex runtime with optional add-ons gated by state | composer test; npm run build; npm run test:js | No known blocker |
woo | Corex plus WooCommerce and Woo kit | composer test; npm run build; wp plugin is-installed woocommerce | No known blocker |
client-site | Generated client plugin/theme consuming Corex | wp corex make:site Acme --dir=sites/acme; wp corex compliance:check | No known blocker |
shared-host | Flat WordPress tree copied to shared hosting | npm run build; npm run build:dist; npm run verify:dist | Verify PHP extensions, permissions, and no-symlink upload shape |
azure-container | Production Docker image on Azure App Service | docker build --target prod -t corex:prod .; az webapp config container set | Requires live Azure and repo secret verification |
local-docker | Docker Compose local stack | docker compose up -d --build; docker compose exec php composer test | Requires Docker daemon |
wp-env-stable | wp-env stable smoke/browser target | npm run env:start; npm run test:e2e; npm run env:stop | Requires Docker/wp-env |
wp-env-trunk | wp-env trunk compatibility target | npm run env:start -- --update; npm run test:e2e; npm run env:stop | Requires Docker/wp-env and may fail on upstream trunk regressions |
Packaging a Corex update
Section titled “Packaging a Corex update”The framework update mechanism (in-admin “update available”) ships already; to produce an update:
wp corex package:update 0.25.0 --download-url=https://example.com/corex/corex-0.25.0.zip --changelog="Bug fixes."This emits the manifest.json the self-update mechanism reads (version / requires / requires_php / tested /
download_url / changelog) for the framework only — never client code, content, uploads, or secrets. Build the
ZIP from the planned framework paths and publish it + the manifest (e.g. a GitHub Release / static host).
Read the docs locally
Section titled “Read the docs locally”wp corex docs:sync # locate the built docs to copy into .corex/docs/ (git-ignored)wp corex docs:serve # how to run the docs app locally (no hosted site needed)See also
Section titled “See also”- Build a client site — the per-site repo + team/AI workflow.
- Updates & distribution — the self-update mechanism this packaging feeds.