08
Oct 2020
Announcing the ExtDN Github ACtions for M2
One of the ways ExtDN is trying to advance the Magento ecosystem is through promoting good practice in extension coding standards. We are happy to announce that to support this mission we have started releasing some open source tools that can be easily embedded in any Magento 2 extension development process using Github Actions.
While there is more to a great extension using these actions we believe provide a good baseline.
All you need is a repo and then copy and paste our pre-setup Github Actions.
Magento 2 Coding Standard
Back in the early days there were many differing standards in circulation in the Magento ecosystem:
- PSR-2 (Magento is part of PHP-FIG after all)
- MEQP-2 (Marketplace)
- ECG-2 (Expert consulting group)
- Standard contained in the Magento 2 code base
Fortunately all of the above have now been replaced by the unified Magento 2 Coding Standard with the core code also adhering to it.
This Github action allows you to test your own code against this standard in an automated fashion.
Create a new file .github/workflows/coding-standard.yml
then copy the following content
name: ExtDN M2 Coding Standard
on: [push, pull_request]
jobs:
static:
name: M2 Coding Standard
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: extdn/github-actions-m2/magento-coding-standard@master
once this is pushed to Github you are all set and any new code pushes and pull request will run through Magento’s coding standard check.
Magento 2 PHPStan
PHPStan is a static code analysis tool that understands more of your code than the Php_CodeSniffer that the Magento 2 Coding Standard above is based on, thanks in large parts being Php 7+ and having access to the underlying code syntax tree.
This allows PHPStan to catch a wide range of issues without the need to write explicit tests for it. Issues that show up in PHPStan include calling inexistent classes, methods, wrong parameter counts, etc.
Adobe has recently introduced PHPStan to the Magento core code checks. This Github action extracts this check to be run standalone against your code.
To use it create a new file .github/workflows/phpstan.yml
with the following content:
name: ExtDN M2 PhpStan
on: [push, pull_request]
jobs:
phpstan:
name: M2 PhpStan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: extdn/github-actions-m2/magento-phpstan@master
with:
composer_name: foo/magento2-foobar
Magento 2 Mess Detector
This action extracts the Magento 2 mess detector ruleset into its own action. Usage is through creating .github/workflows/mess-detector.yml
with this content:
name: ExtDN M2 Mess Detector
on: [push, pull_request]
jobs:
phpmd:
name: M2 Mess Detector
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: extdn/github-actions-m2/magento-mess-detector@master
Magento 2 Integration Tests
Integration tests are a great way to test that your code works well within a given Magento installation. This Github Action provides a blueprint on how to get your existing tests run as a Github action.
In your Github repository add .github/workflows/integration.yml
name: ExtDN M2 Integration Tests
on: [push, pull_request]
jobs:
integration-tests:
name: Magento 2 Integration Tests
runs-on: ubuntu-latest
services:
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: root
ports:
- 3306:3306
options: --tmpfs /tmp:rw --tmpfs /var/lib/mysql:rw --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
es:
image: docker.io/wardenenv/elasticsearch:7.8
ports:
- 9200:9200
env:
'discovery.type': single-node
'xpack.security.enabled': false
ES_JAVA_OPTS: "-Xms64m -Xmx512m"
options: --health-cmd="curl localhost:9200/_cluster/health?wait_for_status=yellow&timeout=60s" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- uses: actions/checkout@v2
- name: M2 Integration Tests with Magento 2 (Php7.4)
uses: extdn/github-actions-m2/magento-integration-tests/7.4@master
with:
module_name: Foo_Bar
composer_name: foo/magento2-foobar
ce_version: '2.4.0'
Magento 2 Performance Profiling
Thanks to our ExtDN supporter Blackfire.io we have been able to work on a performance test for extensions.
The test we have come up with for the initial release is meant as a way to flag extensions that have obvious performance implications. The test runs a performance profile of the category page before and after installing an extension. We excluded the block level cache and fullpage cache to get a true representation of what happens at the application level. The profiles are then compared and will fail if memory consumption, execution time or number of sql queries goes up substantially (more than 25%).
Why the category page? For the initial implementation we picked a page that historically has been one that exhibits performance issues often. What might look like a small delay on a single product can be substantial if the category page loads a lot of products.
Why 25% as a default threshold? In our testing so far we have seen a variation of around 5-10% on the before and after snapshots without any code changes. Setting the threshold to 25% provides a bit of headroom for an extension to add something to the category page. We want to catch the outliers here.
In your GitHub repository add the below as .github/workflows/performance.yml
name: ExtDN M2 Performance Testing
on: [push, pull_request]
jobs:
performance:
name: M2 Performance Testing
runs-on: ubuntu-latest
env:
DOCKER_COMPOSE_FILE: "./docker-compose.yml"
EXTENSION_NAME: "Foo_Bar"
EXTENSION_PACKAGE_NAME: "foo/magento2-foobar"
steps:
- uses: actions/checkout@v2
name: Checkout files
with:
path: extension
- name: Get composer cache directory
id: composer-cache
run: "echo \"::set-output name=dir::$(composer config cache-dir)\""
working-directory: ./extension
- name: Cache dependencies
uses: actions/cache@v1
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Prepare ExtDN performance testing
uses: extdn/github-actions-m2/magento-performance-setup@master
env:
BLACKFIRE_CLIENT_ID: ${{ secrets.BLACKFIRE_CLIENT_ID }}
BLACKFIRE_CLIENT_TOKEN: ${{ secrets.BLACKFIRE_CLIENT_TOKEN }}
BLACKFIRE_SERVER_ID: ${{ secrets.BLACKFIRE_SERVER_ID }}
BLACKFIRE_SERVER_TOKEN: ${{ secrets.BLACKFIRE_SERVER_TOKEN }}
- name: Install Magento
run: >-
docker-compose -f ${{ env.DOCKER_COMPOSE_FILE }} exec -T php-fpm
bash -c 'cd /var/www/html/m2 && sudo chown www-data: -R /var/www/html/m2 && ls -al && id
&& php -f bin/magento setup:install --base-url=http://magento2.test/ --backend-frontname=admin --db-host=mysql --db-name=magento_performance_tests --db-user=root --db-password=123123q --admin-user=admin@example.com --admin-password=password1 --admin-email=admin@example.com --admin-firstname=firstname --admin-lastname=lastname'
- name: Generate Performance Fixtures
run: >-
docker-compose -f ${{ env.DOCKER_COMPOSE_FILE }} exec -T php-fpm
bash -c 'cd /var/www/html/m2
&& php -f bin/magento setup:performance:generate-fixtures setup/performance-toolkit/profiles/ce/small.xml
&& php -f bin/magento cache:enable
&& php -f bin/magento cache:disable block_html full_page'
- name: Run Blackfire
id: blackfire-baseline
run: docker-compose -f ${{ env.DOCKER_COMPOSE_FILE }} run blackfire-agent blackfire --json curl http://magento2.test/category-1/category-1-1.html > ${{ github.workspace }}/baseline.json
env:
BLACKFIRE_CLIENT_ID: ${{ secrets.BLACKFIRE_CLIENT_ID }}
BLACKFIRE_CLIENT_TOKEN: ${{ secrets.BLACKFIRE_CLIENT_TOKEN }}
BLACKFIRE_SERVER_ID: ${{ secrets.BLACKFIRE_SERVER_ID }}
BLACKFIRE_SERVER_TOKEN: ${{ secrets.BLACKFIRE_SERVER_TOKEN }}
- name: Install Extension
run: >-
docker-compose -f ${{ env.DOCKER_COMPOSE_FILE }} exec -e EXTENSION_BRANCH=${GITHUB_REF#refs/heads/} -T php-fpm
bash -c 'cd /var/www/html/m2
&& php -f vendor/composer/composer/bin/composer config repo.extension path /var/www/html/extension
&& php -f vendor/composer/composer/bin/composer require ${{ env.EXTENSION_PACKAGE_NAME }}:dev-$EXTENSION_BRANCH#${{ github.sha }}
&& php -f bin/magento module:enable ${{ env.EXTENSION_NAME }}
&& php -f bin/magento setup:upgrade
&& php -f bin/magento cache:enable
&& php -f bin/magento cache:disable block_html full_page'
- name: Run Blackfire Again
id: blackfire-after
run: docker-compose -f ${{ env.DOCKER_COMPOSE_FILE }} run blackfire-agent blackfire --json curl http://magento2.test/category-1/category-1-1.html > ${{ github.workspace }}/after.json
env:
BLACKFIRE_CLIENT_ID: ${{ secrets.BLACKFIRE_CLIENT_ID }}
BLACKFIRE_CLIENT_TOKEN: ${{ secrets.BLACKFIRE_CLIENT_TOKEN }}
BLACKFIRE_SERVER_ID: ${{ secrets.BLACKFIRE_SERVER_ID }}
BLACKFIRE_SERVER_TOKEN: ${{ secrets.BLACKFIRE_SERVER_TOKEN }}
- name: Compare Performance Results
uses: extdn/github-actions-m2/magento-performance-compare@master
Additionally please create the following Github Secrets for this repository with the values available in your blackfire.io account:
BLACKFIRE_CLIENT_ID
BLACKFIRE_CLIENT_TOKEN
BLACKFIRE_SERVER_ID
BLACKFIRE_SERVER_TOKEN
Summary
We hope these actions provide you with a starting point on your testing journey towards writing quality Magento 2 extensions. Any questions or suggestions please a leave a comment in our repo here.