owenbush / upkeep
Maintenance orchestrator CLI for contributed Drupal modules: cockpit-driven module registry, fixtures, and merge-request workflows.
Requires
- php: >=8.2
- composer/semver: ^3.4
- symfony/console: ^7.2 || ^8.0
- symfony/http-client: ^7.2 || ^8.0
- symfony/process: ^7.2 || ^8.0
- symfony/yaml: ^7.2 || ^8.0
Requires (Dev)
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^11.5
- squizlabs/php_codesniffer: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-09 02:23:30 UTC
README
Upkeep is a maintenance orchestrator CLI for contributed Drupal modules. From one "cockpit" directory it tracks every module you maintain across the Drupal core versions you support, shows every open contribution with its CI and local-check state on a single dashboard, runs each MR through a fully isolated check flow (PHPUnit, PHPStan, PHPCS, install, smoke) in a disposable per-module-per-core environment, and — for compat MRs that pass every gate — offers a human-approved fast-lane merge.
Environments are provisioned with ddev plus the ddev-drupal-contrib add-on (pinned at version 1.1.5) behind a thin adapter, and database fixtures come from the companion ddev-upkeep add-on. You never interact with either directly unless you want to.
Quick start
# 1. Install composer global require owenbush/upkeep # 2. Scaffold a cockpit upkeep init ~/my-cockpit && cd ~/my-cockpit # 3. Build the base artifacts for a core version you maintain for upkeep base-artifacts:build --version=11 # 4. Look at a module — any module, registered or not upkeep issues pathauto upkeep dashboard pathauto
Reading git.drupalcode.org needs no credential. A token is for writing: merging, commenting and publishing.
Documentation
Getting started
| Install | Requirements, installing, shell completion |
| GitLab token | What needs a credential and what does not |
| Set up a cockpit | The registry, and what lives in a cockpit directory |
| Base artifacts | The per-core building blocks, pre-release core majors, rebuilding |
| Publishing: issue forks and SSH | How work reaches drupal.org |
Daily flow
| The dashboard | Everything open, and what a row represents |
| Work on an issue | issues → start → publish |
| Patch contributions | The work a merge-request view cannot see |
| Running checks | The isolated flow, and how it matches drupal.org CI |
| Review, merge and release notes | Looking at it, merging it, writing it up |
| Working in an environment | A shell, a path, a running site |
| Fixtures | Check against real database state |
Reference
| Command reference | Every command, generated from the CLI itself |
| Exit codes | The 0/1/2 contract |
| Disk housekeeping | Where the space goes, and reclaiming it |
| Upgrading a cockpit | What a version change expects |
Design
| Design document | Why upkeep is shaped the way it is |
| The dashboard row model | Why a row is (module, issue, branch) |
| Any module, not just yours | The registry as a watchlist rather than a gate |
Policy stance
Merges are one human approval per merge request, by Drupal Association policy. There is deliberately no batch mode and no unattended merge path, and the browser UI deliberately has no merge button — a button that POSTs an action name is not the per-MR prompt that earns the approval. See Review, merge and release notes.
License
MIT — see LICENSE.