No results found.

Featured CI & testing

Magento CI Testing Images

Docker images with Magento 2.4.2 to 2.4.9 or Mage-OS 1.0 to 3.5 already installed, so Magento module CI skips installing Magento on every run.

Source on GitHub ↗Docker Hub ↗

Version and PHP images
141
Magento versions
70
Mage-OS versions
21
PHP versions
7.4–8.5

Every CI run for a Magento module used to start the same way: create a Magento project and install it, once for every Magento and PHP version in the matrix, before a single test ran. I built these images so that step happens once, at image build time, and a pipeline mounts the module and gets straight to the tests.

How is the matrix built?

One manifest drives every build, so supporting a new release means adding it to the manifest. 70 Magento versions from 2.4.2 to 2.4.9 make 103 images, and 21 Mage-OS versions from 1.0.0 to 3.5.0 make 38, across PHP 7.4 to 8.5. Older core versions with install bugs get Composer patches at build time rather than being skipped.

Every push to master builds and smoke-tests the full matrix before anything is released. A /test comment on a pull request builds a filtered subset.

Which images does it publish?

Three, each on Docker Hub and the GitHub Container Registry:

ImageContents
magento-base-ci-testing-envAlpine PHP-FPM, extensions, Composer, n98-magerun2. For testing whole projects
magento-ci-testing-envMagento Open Source installed, DI compiled, static content deployed
mage-os-ci-testing-envMage-OS, built the same way

The README lists them at about 50, 198 and 190 MB compressed. Current tags on Docker Hub have grown since, up to about 68 MB for the base image and 240 MB with Magento installed (10th October 2026). The application images add PHPStan with the Magento extension and vaimo/composer-patches, and expose an ./extensions/* path repository for the module under test.

Tags come in two forms: rolling (2.4.8-php8.3), updated with each release, and pinned (2.4.8-php8.3-v1.0.0).

How does a module pipeline use them?

The job runs inside the image, checks the module out into extensions/, requires it and runs the tests. A trimmed version of the README’s GitHub Actions example:

jobs:
  test:
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/samjuk/magento-ci-testing-env:2.4.8-php8.3
      options: --user 1001:1001 -v "${{github.workspace}}":"${{github.workspace}}"
    steps:
      - run: cp -R /var/www/html/* ${{ github.workspace }}/
      - uses: actions/checkout@v4
        with:
          path: ./extensions/${{ github.event.repository.name }}
      - run: |
          EXT_NAME=$(cat ./extensions/${{ github.event.repository.name }}/composer.json | jq -r '.name')
          composer require -W --prefer-source ${EXT_NAME}:@dev
      - run: vendor/bin/phpunit

m2-meta-security-patches runs its CI on these images, across 70 Magento and 12 Mage-OS versions.

How are the images secured?

Anyone pulling an image can check where it was built. Images are signed with Cosign through keyless Sigstore signing, and released with SBOM and mode=max provenance attestations. Pull requests are scanned for secrets with TruffleHog and Gitleaks. To check a signature:

cosign verify \
  --certificate-identity-regexp="https://github.com/SamJUK/magento-ci-testing-env" \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
  ghcr.io/samjuk/magento-ci-testing-env:2.4.8-php8.3