This project is not covered by Drupal’s security advisory policy.

Content Deployment reads and writes Drupal content as JSON content specs, lands every write as a draft for a person to review, and ships content changes with code as changesets that run once per environment.

A content spec describes one content entity: a node with its whole Paragraphs tree, a media item, a taxonomy term, a menu link, a user account, a custom block or a redirect, in every language it has. Drush commands and Tool API plugins read and write the same format, so a script or an agent can propose content and a person decides what is published.

Features

  • Content specs. One JSON object per entity, with its paragraph tree and its translations. Read an entity, change the spec, apply it back: paragraphs keep their identity where uuids match, and the content model command reports what each bundle can carry.
  • Drafts by default. A write to a published entity becomes a pending draft revision, and a new entity an unpublished draft. Editors see a notice on the page with a Publish link, which takes the workflow's transition. Nothing is deleted: content is retired by unpublishing, archiving or blocking.
  • Changesets. Content that ships with code and runs exactly once on each environment, from files outside the docroot. Each changed value carries a fingerprint of the value it replaces, so an edit made on the live site since is kept: an entity with a conflict lands as a pending draft, flagged for review. Files travel beside the changeset, addressed by SHA-256.
  • Export from a staging workspace (content_deployment_export, development environments only). Stage content in a Workspaces workspace and export what it changed as the next changeset, from Drush or the workspace's Export changeset operation.
  • Translations. Specs carry every language, with symmetric paragraph translation. Each language has its own draft, review record and Publish.
  • Media. Files become media items once per set of bytes, through File Hash; image media need alt text. content_deployment_media ranks the image library against a text and fills empty image fields.
  • Tool API plugins (content_deployment_tools, experimental). Model, query, read, create, apply, media ingest, pending, publish and unpublish, each run as the account invoking it and checked against that account's own access.

Requirements

  • Drupal 11.3 or later, and PHP 8.3 or later.
  • content_deployment_export needs core's Workspaces and HTTP Basic Authentication.
  • content_deployment_tools needs Tool API.

Recommended modules

  • Content Moderation (core): drafts with a workflow state, and the Latest version tab.
  • Paragraphs and Entity Reference Revisions: paragraph trees.
  • File Hash, with SHA-256: one media item per set of bytes, and changesets that carry files.
  • Config Read-only: configuration locked on live, where changesets write content only.
  • Pathauto and Redirect: generated aliases are reported and left to Pathauto; a changed alias leaves a redirect.

Post-installation

  1. Set $settings['content_deployment_directory'] to a directory outside the docroot, for changesets and their files.
  2. Put the bundles that are written to under a workflow, and give editors the permissions to see and publish drafts.
  3. Enable content_deployment_export on development environments only, and list it in $settings['config_exclude_modules'].
  4. To run changesets during drush deploy, set $settings['content_deployment_run_on_deploy'] = TRUE;. Without it, drush deploy reports the changesets waiting.
  5. Where changesets carry files, enable File Hash with SHA-256 and run drush filehash:generate once.

Drush commands

  • content-spec:model, content-spec:query, content-spec:read: the content model, finding entities, an entity as a spec.
  • content-spec:create, content-spec:apply: write a spec, as a draft.
  • content-spec:media-ingest: files into media.
  • content-spec:pending, content-spec:publish, content-spec:unpublish: the review flow.
  • content-spec:suggest-media, content-spec:illustrate: images for a page (content_deployment_media).
  • content-spec:kitchen-sink: a page with every field filled in, for reviewing a theme.
  • content-deployment:status, content-deployment:run, content-deployment:export: changesets.

Documentation

Similar projects

  • Default Content imports content from files when a module is installed. Content Deployment runs each changeset once on sites already in use, and keeps the edits made there.
  • Single Content Sync exports and imports entities as YAML. Content Deployment writes as drafts for review, and records which changesets each environment has run.
  • Entity Share pulls entities from one site into another over JSON:API. Content Deployment moves content through the repository, with the code, and needs no connection between sites.
Supporting organizations: 

Project information

Releases