Skip to content

Repeatable deploy hooks via ys_deploy module to replace custom post-provision scripts #2597

@AlexSkrypnyk

Description

@AlexSkrypnyk

Background

Part of the Vortex 2.0 epic.

Vortex currently ships bespoke post-provision shell scripts to run logic after drush deploy. Drupal/Drush's run-once hooks (hook_update_N, hook_post_update_NAME, hook_deploy_NAME) cannot express "run on every deploy" - they are recorded as completed and never repeat. Historically this required a "persistent update" hack (resetting a hook's completion marker), which is now unmaintained and an anti-pattern.

Decision

Drush already supports running logic on every drush deploy via a native pre-command / post-command annotated-command hook targeting deploy. These are not run-once tracked. No upstream change is required.

Goal

Ship a dedicated, consumer-owned module (ys_deploy) that hosts pre/post-deploy sequences via Drush command hooks. It runs identically wherever drush deploy runs (CI, local, and production hosting post-rollout), and replaces the bespoke post-provision scripts.

Scope

  • New module ys_deploy (project-prefixed) with a DeployCommands class exposing PRE_COMMAND_HOOK / POST_COMMAND_HOOK hooks on deploy, where consumers define their own repeatable, idempotent deploy sequences.
  • Developer-experience helpers in this class to make common operations easy to run and to express step ordering.
  • Make these sequences testable.
  • Port the capabilities currently provided by the bespoke post-provision scripts into this module.
  • Decommission the custom post-provision shell scripts once parity is reached.
  • Document the two layers:
    • Drupal-level "every deploy" -> this module's Drush command hooks (runs wherever drush deploy runs).
    • Vortex tooling-level -> pre/post provision event scripts (#1198) for orchestration outside drush deploy (e.g. work before DB import).
  • Pin the supported hook form for the Drush version in use (Drush 13.7+ nudges some hook types toward Listener classes).

Example

A post-command hook that runs after every drush deploy, with no run-once tracking:

<?php

declare(strict_types=1);

namespace Drupal\ys_deploy\Drush\Commands;

use Consolidation\AnnotatedCommand\CommandData;
use Consolidation\AnnotatedCommand\Hooks\HookManager;
use Drush\Attributes as CLI;
use Drush\Commands\DrushCommands;

/**
 * Repeatable deploy-time tasks for this project.
 */
final class DeployCommands extends DrushCommands {

  /**
   * Runs after EVERY `drush deploy` (not recorded as done, so never skipped).
   *
   * The correct home for idempotent, must-run-on-every-deploy work (search
   * reindex, a re-runnable migration, cache warmups). Replaces the legacy
   * "persistent update" hack. Contrast hook_deploy_NAME(), which is run-once
   * and tracked.
   */
  #[CLI\Hook(type: HookManager::POST_COMMAND_HOOK, target: 'deploy')]
  public function postDeploy(mixed $result, CommandData $commandData): void {
    $this->logger()->notice(dt('Running repeatable post-deploy tasks.'));
    // Project-specific idempotent commands go here, e.g.:
    //   drush search-api:index
    //   drush migrate:import --update --sync some_config_migration
  }

}

HookManager::PRE_COMMAND_HOOK provides the same extension point before the deploy steps.

Acceptance criteria

  • A generated project includes a ys_deploy module with documented pre/post deploy hook extension points.
  • Repeatable deploy logic runs on every deploy across CI, local, and production.
  • The bespoke post-provision scripts are removed.
  • Deploy sequences are covered by tests.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    A1Board worker 1

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    In progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions