# Drupal Migration

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-trebormc-drupal-ai-agents-drupal-migration`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [trebormc](https://agentstack.voostack.com/s/trebormc)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [trebormc](https://github.com/trebormc)
- **Source:** https://github.com/trebormc/drupal-ai-agents/tree/main/.claude/skills/drupal-migration

## Install

```sh
agentstack add skill-trebormc-drupal-ai-agents-drupal-migration
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

## Environment

All commands via `ssh web drush`.

## Required modules

```bash
ssh web composer require drupal/migrate_plus drupal/migrate_tools drupal/migrate_upgrade
ssh web drush en migrate migrate_plus migrate_tools -y
```

## Migration YAML structure

Place in `config/install/` or `migrations/` directory:

```yaml
id: my_migration
label: 'Migrate content from source'
migration_group: my_group
source:
  plugin: csv
  path: private://import/data.csv
  ids: [id]
  header_offset: 0
process:
  type:
    plugin: default_value
    default_value: article
  title: title
  body/value: body
  body/format:
    plugin: default_value
    default_value: basic_html
  field_date:
    plugin: format_date
    source: date
    from_format: 'm/d/Y'
    to_format: 'Y-m-d'
destination:
  plugin: 'entity:node'
migration_dependencies:
  required: []
  optional: []
```

## Common migration commands

| Task | Command |
|------|---------|
| List migrations | `ssh web drush migrate:status` |
| Run migration | `ssh web drush migrate:import my_migration` |
| Run with limit | `ssh web drush migrate:import my_migration --limit=10` |
| Rollback (undo imported rows) | `ssh web drush migrate:rollback my_migration` |
| Reset stuck "Importing" status | `ssh web drush migrate:reset-status my_migration` |
| Run all in group | `ssh web drush migrate:import --group=my_group` |
| Update existing | `ssh web drush migrate:import my_migration --update` |

## D7 to D10/D11 workflow

### Step 1: Generate migration config
```bash
ssh web drush migrate:upgrade --legacy-db-key=d7 --configure-only
```

### Step 2: Review and customize
```bash
ssh web drush cex -y
# Review migrate_plus.migration.* files in config/sync/
```

### Step 3: Test with limits
```bash
ssh web drush migrate:import upgrade_d7_node_article --limit=5
```

### Step 4: Verify and run full
```bash
ssh web drush migrate:import --all
```

## Custom source plugin template

```php
select('source_table', 's')
      ->fields('s', ['id', 'title', 'body', 'created']);
  }

  public function fields(): array {
    return [
      'id' => $this->t('Unique ID'),
      'title' => $this->t('Title'),
    ];
  }

  public function getIds(): array {
    return ['id' => ['type' => 'integer']];
  }

  public function prepareRow(Row $row): bool {
    return parent::prepareRow($row);
  }

}
```

## Process plugin reference

| Plugin | Use case |
|--------|----------|
| `get` | Direct field mapping (default) |
| `default_value` | Set static value |
| `migration_lookup` | Reference migrated entity |
| `format_date` | Date format conversion |
| `entity_generate` | Create referenced entity if missing |
| `callback` | PHP callback transformation |
| `static_map` | Value mapping table |
| `skip_on_empty` | Skip row if source empty |

## Related Skills

- **drupal-testing** — Create PHPUnit tests for migration source plugins and process logic
- **drupal-debugging** — Debug migration errors, inspect entities, check watchdog logs

## Verification (after EVERY import)

```bash
# 1. Check status: Imported count must be > 0 and Status must be "Idle"
ssh web drush migrate:status --format=table

# 2. Verify migrated content count matches expectations
ssh web drush sqlq "SELECT COUNT(*) FROM node WHERE type = 'article'"

# 3. Check for migration errors
ssh web drush migrate:messages my_migration
ssh web drush ws --count=10 --severity=Error
```

## If a migration fails

| Symptom | Fix |
|---------|-----|
| Status stuck at "Importing" | `ssh web drush migrate:reset-status my_migration`, then re-import |
| Wrong/partial data imported | `ssh web drush migrate:rollback my_migration`, fix the migration config, re-import with `--limit=5` first |
| Source DB connection error | Verify the `d7` database key exists in settings.php and the source DB is reachable |
| Row-level errors | Read them with `ssh web drush migrate:messages my_migration` and fix the process pipeline for those fields |

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [trebormc](https://github.com/trebormc)
- **Source:** [trebormc/drupal-ai-agents](https://github.com/trebormc/drupal-ai-agents)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-trebormc-drupal-ai-agents-drupal-migration
- Seller: https://agentstack.voostack.com/s/trebormc
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
