ddtcorex

16 Sept 2026 · 2 min read

Pre-merge testing with Govard in CI

Using Govard environments inside the pipeline to run real integration tests before a branch merges

Part 5 of the Govard deep-dive series — the environment as a CI primitive. This is the final post.

Testing against a real stack, not a mock

Unit tests catch logic bugs; integration bugs live in the gap between your code and Magento's services — the database, the cache, the search index. Mocks paper over that gap. The fast feedback loop is to spin up a real Govard environment inside CI, run the suite against it, and tear it down. The branch that merges has been exercised by the same stack the storefront runs on.

Wiring Govard into the pipeline

Govard runs anywhere Docker does, so a CI runner with Docker available can stand up an environment per job:

# .github/workflows/ci.yml (shape only)
jobs:
  integration:
    runs-on: ubuntu-latest
    services:
      docker: { } # docker-in-docker or socket mount
    steps:
      - uses: actions/checkout@v4
      # Govard is a native Go binary, not an npm package — install it first,
      # pinning the version so CI and local runs stay in lockstep.
      - run: curl -fsSL https://raw.githubusercontent.com/ddtcorex/govard/master/install.sh | bash -s -- --version v1.70.3
      - run: govard env up --seed
      - run: vendor/bin/phpunit --testsuite integration
      - run: govard env down --volumes

The shape is the same in GitLab CI or any runner: bring the environment up with a seeded database, run phpunit (or the project's integration suite), then bring it down and remove volumes so the next run starts clean.

What to run here

  • Integration tests that touch the database and services — the ones unit tests cannot cover.
  • Static analysis (PHPStan/phpcs) and composer audit — see the Performance/DevOps series for the gate design.
  • A smoke deploy of the theme, so a broken layout override fails before merge.

Pitfalls

  • CI time cost. A full environment per job is slower than a mock. Cache the base image and seed data, and run heavy suites only on relevant paths.
  • Large seed data. A multi-GB dump makes every run slow; use a lean, representative dataset.
  • Leftover containers. Always tear down in a finally/post-step, or runners accumulate orphaned envs and exhaust resources.
  • Drift from local. If CI uses a different Govard version than developers, results diverge; pin the same --version in the install.sh step that developers run locally.

Closing the series

This deep-dive moved from what Govard stands up (architecture), how to run many of them (parallel environments), how to debug inside one (tooling), how to shape it to a project (customizing), and finally how to make it a CI primitive (pre-merge testing). The throughline: a reproducible environment is not a convenience — it is the substrate that makes every other quality practice actually work.

This was the final post in the Govard deep-dive series.

magento2govardci