CLI MAINTENANCE ORCHESTRATOR · DRUPAL CONTRIB

One cockpit for every module you maintain.

Upkeep runs the whole triage loop from your terminal: every open merge request across every module, checked in an isolated environment, reviewed in a real browser, merged one deliberate approval at a time.

View on GitHub composer global require owenbush/upkeep
~/cockpit
$ upkeep dashboard
MODULEMRISSUECORETITLECILOCALSTATUS
entity_clone!142341988211.xDrupal 11 compatibility fixespasspassREADY-AUTO entity_clone!139341157010.3Fix cloning of paragraph fieldsREVIEW ci-missing menu_position!87340211811.xDeprecate legacy plugin managerpassfailREVIEW local-failed:phpunit menu_position!85339900410.3Add config schema for defaultspasspassREADY-AUTO taxonomy_tools!231342104611.xBulk term reparenting UIREVIEW draft taxonomy_tools!228341877311.xRebase onto 2.1.xfailBLOCKED conflicts
READY-AUTO — every gate passed, safe to fast-lane REVIEW — a human needs to look, reason attached BLOCKED — cannot proceed until resolved
THE DAILY LOOP

A morning of triage, five commands.

Dashboard upkeep dashboard

Every open MR across every registered module, in one table: CI status, local check results, the linked drupal.org issue state, and the fast-lane gate verdict. Cached so it returns instantly; --refresh when you want fresh data.

Check upkeep check entity_clone 142 --version=11

Provisions a fully isolated environment (ddev + ddev-drupal-contrib), applies the MR, then runs PHPUnit, PHPStan, PHPCS, install and smoke checks. Results are cached; the exit code is a 0/1/2 contract you can script against.

Review upkeep review entity_clone 142

Applies the MR to a running site and hands back a browser URL with a one-time login. Green checks are not the same as looking at the thing.

Issue status upkeep issue entity_clone 142

Shows the linked drupal.org issue and opens it in the browser so you can set RTBC, needs work, or fixed without hunting for the node.

Merge upkeep merge --fast-lane

Bot MRs that cleared every gate: one prompt, one approval, one merge. There is no batch mode, deliberately — merges stay human-approved to comply with Drupal Association policy.

FIXTURES

Checks against real state, not a bare install.

A fixture is a gzipped, sanitised SQL dump — tests/fixtures/smoke.sql.gz — that captures a database state worth testing against: configured entities, test users, sample content. Capture it once, commit it, and every check from then on runs against the site your module actually lives in.

STEP 1 Set the site up Install, create content, configure what your module needs
STEP 2 Capture it ddev upkeep-fixture-create smoke
STEP 3 Commit the dump Sanitised automatically — no real emails or passwords
STEP 4 Check with it --fixture=smoke
STEP 5 State restores First load imports the dump; after that, a snapshot in under a second
STEP 6 Checks run for real Against your content, not an empty database

When you need one

When your module can’t be meaningfully exercised against a bare Drupal install. If it manages vocabulary terms, you need terms. If it configures form displays, you need content types with fields. The fixture captures that setup once instead of every time.

The tests/fixtures convention

Gzipped SQL, sanitised, lean, living in the module repo at tests/fixtures/. Upkeep promotes this for all contrib modules, whether or not they use Upkeep — anyone can load one with or without the add-on.

SETUP

Four steps to a cockpit.

PHP 8.2+, Composer, ddev with Docker. Full detail lives in the README.

Install the CLI
composer global require owenbush/upkeep
Add a GitLab token
Create a PAT on git.drupalcode.org, then drop it in place: ~/.config/upkeep/drupal-pat
Initialise the cockpit
upkeep init ~/my-cockpit
Register your modules, build base artifacts
Then run upkeep dashboard and you’re in.
REFERENCE

Every command.

dashboardAll open MRs with CI, local check, issue status and fast-lane gate
checkFull isolated check flow for one MR — PHPUnit, PHPStan, PHPCS, install, smoke
reviewApply an MR to a running site and get a browser URL
issueShow and open the linked drupal.org issue
merge --fast-laneHuman-approved merge of gate-passing MRs, one at a time
execRun a command inside a module’s environment
notesDraft release notes from MRs merged since the last tag
status / pruneDisk inventory and cleanup