Automating Magento code review with GitHub Actions

A reusable, open-source engine: deterministic checks, PHP static analysis, and a Claude AI reviewer


Reviewing Magento pull requests by hand, across a dozen client repositories, is a lot of the same work over and over: is the PR titled with the Jira key, are the new modules registered, does the diff trip PHPCS, is there a var_dump someone forgot. It is important work, but most of it is mechanical — and mechanical work is what CI is for. So I built a reusable GitHub Actions code review engine and open-sourced it: github.com/zynqa/code-review-engine .

The pipeline

Every pull request runs through a single reusable workflow. Each stage is optional and toggled per repository, and the final merge gate only judges the checks you actually enabled.

Pull request opened / updated
1PR conventionstitle · branch · commits carry the Jira key
2Module registrationnew Magento modules are actually enabled
3Static analysisPHPCS · PHPStan · PHPMD on changed files
4Claude AI reviewthe diff plus Jira, Confluence & Slack context
5PHPUnit testsruns the suite when the repo has one
6Auto-merge gateapprove · update branch · merge
Approved & merged ✓

One reusable workflow, six optional stages. The gate only requires what you switched on.

One workflow, every repository

The engine is a single reusable workflow. A consumer repo doesn’t copy CI logic around — it calls the engine and picks which checks to run:

yaml
# .github/workflows/code-review.yml
name: Code Review
on:
  pull_request:
    types: [opened, edited, synchronize, reopened]

jobs:
  review:
    uses: zynqa/code-review-engine/.github/workflows/review.yml@main
    with:
      magento-version: "2.4.5-p5"
      jira-project-key: "PROJ"
      enable-pr-validation: true
      enable-module-registration: true
      enable-static-analysis: true
      enable-ai-review: false
      enable-tests: false
    secrets: inherit

Because everyone points at @main, fixing a rule or adding a check in the engine rolls out to every repository on its next PR — no bumping versions across a dozen projects.

code-review-enginereview.yml @mainone reusable workflow
Magento repo 1
Magento repo 2
Module repo
● on  ● off — each repo toggles its own checks

Point every repo at @main once; each keeps its own profile of enabled checks.

Deterministic first, AI second

The order matters. Cheap, deterministic checks run first and catch the mechanical problems for free, so the AI review (the only stage that costs money and time) is spent on judgement, not on things a linter already knows.

Static analysis runs only on the files the PR changed, not the whole repository — fast, and the comments land on the lines you actually touched. It runs PHPCS, PHPStan and PHPMD, and posts GitHub annotations, inline review comments, and a sticky summary with counts per tool. On top of the standard Magento sniffs, the engine ships custom Zynqa PHPCS rules:

  • declare(strict_types=1); is required
  • Magento helpers must be stateless
  • no superglobals and no global
  • no eval, die, var_dump, print_r, error_log
  • no direct ObjectManager usage
  • no deprecated Setup/InstallSchema.php
  • admin controller inheritance / ADMIN_RESOURCE rules
  • no inline presentation logic in .phtml

Here are a few of those rules firing as inline review comments on a real pull request — click any to expand:

The AI reviewer, with real context

Only once the mechanical checks pass does the Claude reviewer run — and it doesn’t just see the diff. It pulls the surrounding context a human reviewer would open in other tabs: the Jira ticket, related Confluence pages, and Slack threads, alongside the GitHub PR itself. That is the difference between “this method is long” and “this doesn’t do what the ticket asked”.

GitHub PR
Jira ticket
Confluence
Slack
Claudereviews the change
Inline reviewcomments + summary

The reviewer reads the ticket, the docs and the chat — not just the diff — then comments on the exact lines.

If AI review is enabled without an ANTHROPIC_API_KEY, the job fails loudly rather than silently skipping — a check you think is running should actually run.

The merge gate

When the enabled checks pass, the last stage can approve the PR as github-actions[bot], pick an allowed merge method, update the branch if it is behind, and merge — falling back to GitHub’s native auto-merge when a ruleset blocks a direct merge. Crucially, the gate only evaluates the checks a repo turned on, so a module repo running just static analysis isn’t held hostage to an AI review it never enabled.

Auto-merge gate: the bot approves and merges the pull request after all configured checks pass

Profiles

Two toggle profiles cover most repos. A Magento application repo tends to run PR conventions + module registration + static analysis + auto-approval; a standalone module repo usually runs just static analysis (and maybe tests). Both are a handful of true/false inputs — no forked pipelines.

Try it

It’s open source: github.com/zynqa/code-review-engine . Copy the project template into a repo’s .github/workflows/, set the inputs, keep secrets: inherit, and your next pull request gets the full treatment. Start with static analysis only — it’s the highest signal for zero configuration — and switch on the rest as you trust it.