Skip to content

Commit

Permalink
CI: switch to GitHub Actions - step 6: PHP integration tests
Browse files Browse the repository at this point in the history
This commit:
* Adds a GH Actions workflow for the PHPUnit Integration test CI check.
* Removes all references to that check from the `.travis.yml` configuration.
* Replaces the "Build Status" badge in the Readme with a badge using the results from the GH `IntegrationTest` Action runs.
    All other workflows have their own status badges, so the Travis badge can now be safely removed.

Notes:
1. Builds will run on:
    - Select pushes using branch filtering similar to before.
    - All pull requests.
    - When manually triggered.
        Note: manual triggering of builds has to be [explicitly allowed](https://github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/). This is not a feature which is enabled by default.
2. If a previous GH actions run for the same branch hadn't finished yet when the same branch is pushed again, the previous run will be cancelled.
    In Travis, this was an option on the "Settings" page - "Auto cancellation" -, which was turned on for most, if not all, Yoast repos. The `concurrency` configuration in the GHA script emulates the same behaviour.
3. In contrast to various other scripts, the matrix for these integration tests is explicitly set with all variables explicitly defined for each build, as we want full control over the three variables (`php_version`, `wp_version` and `multisite`) used for each run.
4. As a MySQL database is needed, we need to explicitly add that service.
    The MySQL version used varies based on the PHP version against which the tests are run for two reasons:
    1. It's good practice to test against multiple different MySQL versions to verify that any queries run are MySQL cross-version compatible.
    2. While WP is _supposed to_ support MySQL 8.0 since WP 5.4, in actual fact, WordPress doesn't fully support MySQL 8.0 on PHP < 7.4.
        Also see: https://core.trac.wordpress.org/ticket/52496
    Note: in the Travis script, the PHP 5.6 build was explicitly set to use the `trusty` dist to force the use of MySQL 5.6. In GH Actions, this is not directly linked to the Ubuntu image used. All the same, the script has been set up to explicitly use MySQL 5.6 for PHP 5.6, same as before.
5. The default ini settings used by the `setup-php` action are based on the `php.ini-production` configuration.
    This means that `error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT`, `display_errors` is set to `Off` and `zend.assertions` is set to `-1` (= do not compile).
    For the purposes of CI, especially for linting and testing code, I'd recommend running with `zend.assertions=-1`, `error_reporting=-1` and `display_errors=On` to ensure **all** PHP notices are shown.
    Note: the defaults will be changed in the next major of `setup-php` to be based on the `php.ini-develop` configuration, but that may still be a while off.
    Refs:
    * shivammathur/setup-php#450
    * shivammathur/setup-php#469
6. While the `setup-php` action offers the ability to [install the PHAR file for PHPUnit](https://github.com/shivammathur/setup-php#wrench-tools-support), I've elected not to use that option as we need to do a `composer install` anyway to get the other dependencies, like WP Test Utils.
7. The PHPUnit version(s) supported and needed to run the tests depend on **both** the WP version used as well as the PHP version used.
    As an `if` condition on a step would get pretty complicated to handle this, I've introduced a separate - fully documented - step to determine the "type" of install we need.
    The output of that step is subsequently used in the `if` condition for follow-on steps to make sure the correct PHPUnit version will be installed by Composer.
8. Composer dependency downloads will be cached for faster builds using a [predefined GH action](https://github.com/marketplace/actions/install-composer-dependencies) specifically created for this purpose.
    The alternative would be to handle the caching manually, which would add three extra steps to the script.
    Note: Caching works differently between Travis and GH Actions.
    On GH Actions, once a cache has been created, it can't be updated. It can only be replaced by a new cache with a different key.
    As the PHP version, the `composer.json` and a potential `composer.lock` hash are all part of the key used by the above mentioned action, this difference should not have a significant impact.
    Ref: https://docs.github.com/en/actions/advanced-guides/caching-dependencies-to-speed-up-workflows
9. As there is a committed `composer.lock` file and the PHPUnit version is locked at PHPUnit 5.x, we have to do an on-the-fly update of the PHPUnit version depending on the WP and PHP version used for the current build.
    As we still also want to benefit from the Composer caching which the `ramsey/composer-install` action sets up, I've done some nifty trickery with the options passed to the `composer-install` action to get that working.
    - The `dependency-versions: "highest"` basically changes the command used by the action from `composer install` to `composer update`, however we don't want to update _all_ dependencies as run-time dependencies should remain locked at their original version.
    - To that end, I'm passing additional `composer-options` which will limit the update to just and only the test dependencies.
    - These type of updates are only run when needed based on the "install type" determination as described in (7).
10. Installing WordPress was previously done via inline commands in the Travis script. This has now been replaced by the more comprehensive `tests/bin/install-wp-tests.sh` script as made available by the WP CLI `scaffold` command.
    As WPCLI is not used anywhere else in the workflow, a copy of the script, with source annotations, is being introduced into the plugin codebase.
    Note: this script needs to have the `x` flag set to allow it to be executed.
    Ref: https://github.com/wp-cli/scaffold-command/blob/master/templates/install-wp-tests.sh
    Some differences between the scripts:
    - The plugin will no longer be copied into the WordPress install, as, to be honest, that's just not necessary with the current test setup/test bootstrap.
    - The location to which WP is downloaded and installed is different between the scripts, however, this makes no difference for our purposes as the WP Test Utils library already takes the default install locations from the `install-wp-tests.sh` script into account.
    - To test against the "nightly" of WordPress, the matrix needs to set the `wp_version` to `trunk` or `nightly` instead of `master` (as was previously used in some scripts).
    - WordPress will be set up to always use `mysqli` for database commands, even on PHP 5.6.

Differences with the Travis implementation:
* The most appropriate version of the test dependencies will now be used for _all_ builds, not just for builds against PHP 8.0/`nightly`.
* Except for the test dependencies, no other dependencies will be updated during the test run.
* In Travis, there was a reference to a `atanamo/php-codeshift` package, which was removed after the prefixing was finished.
    This package is not a (root) dependency of the WPSEO Free plugin, so removing it doesn't actually have any effect.
    Instead, the `league/oauth2-client` package is removed, as that package should not be used during the test run as it will be prefixed and the prefixed version should be used instead.
* The "mix" of PHP/WP versions + Multisite used in the matrix has been adjusted slightly compared to Travis.
    The current mix in GHA ensure there is a run against high + low WP on low PHP, a run against high + low WP on high PHP and a run against mulisite for all supported WP versions.
* In addition to the PHP versions against which the tests were previously run on Travis, the tests will now also be run against PHP 8.1.
    As PHP 8.1 has been released, the (remaining) test failures on this build need to be fixed, though as these are only _deprecation notices_, the fact that these tests are currently failing is nothing to be too concerned about for the time being.
    To prevent new failures from being introduced in the mean time, I'm not allowing the build to fail, but will instead add expectations for the deprecations or skip requirements to the few tests which still have them for the time being.

    Builds against WP `trunk`, will be "allowed to fail".
    Note: if a "allowed to fail" job actually fails, the workflow will show as successful, but there will still be a red `x` next to a PR.
    This is a known issue in GHA: https://github.com/actions/toolkit/issues/399
    There are work-arounds possible for this, however, the work-arounds would hide failures even more, meaning that chances are they won't be seen until they actually become a problem (no longer allowed to fail), which is too late.
* Instead of using Git to clone WP, the WP-CLI script is now used to retrieve the relevant parts of WP and initiate the database and the `wp-config` settings.
* There are a number of files which are usually created by Grunt and are needed during the test run.
    In Travis, these files were created on the fly from within the Travis script to ensure tests would not error out on these files missing..
    As this was only done in Travis, PHP focussed plugin developers who rarely use Grunt locally, would still end up with these errors when they would run the tests locally.
    As the need for these files is inherent to the integration tests, creating these files from within the integration test bootstrap file will make this more stable and will allow this to work both in CI as for dev-local test runs.
* In Travis, test runs would run either as single site or as multisite. In GH Actions, each build will always run the tests against WP in single site mode and for those builds with the `multisite` flag set to `true` in the matrix, the test will **_also_** be run in multisite mode.
* In Travis, for select test runs, code coverage would be calculated and uploaded to CodeClimate.
    As CodeClimate did not signal back to PRs if a PR changed the code coverage and by how much, this was not very effective, other than to keep track over time, though in practice, nobody seemed to even check on this or check on the reports at all.
    With this in mind, code coverage will no longer be run, nor uploaded to CodeClimate.
    The intention is to eventually run code coverage on the Jenkins server.
  • Loading branch information
jrfnl committed Mar 17, 2022
1 parent 56d3a4b commit 359cf04
Show file tree
Hide file tree
Showing 5 changed files with 423 additions and 132 deletions.
175 changes: 175 additions & 0 deletions .github/workflows/integrationtest.yml
@@ -0,0 +1,175 @@
name: Integration Test

on:
# Run on pushes to select branches and on all pull requests.
push:
branches:
- master
- trunk
- 'release/**'
- 'hotfix/[0-9]+.[0-9]+*'
- 'feature/**'
pull_request:
# Allow manually triggering the workflow.
workflow_dispatch:

# Cancels all previous workflow runs for the same branch that have not yet completed.
concurrency:
# The concurrency group contains the workflow name and the branch name.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
integration-test:
runs-on: ubuntu-latest

strategy:
matrix:
include:
- php_version: '5.6'
wp_version: '5.8'
multisite: true

- php_version: '7.0'
wp_version: 'latest'
multisite: false

- php_version: '7.3'
wp_version: 'trunk'
multisite: true

- php_version: '7.4'
wp_version: 'latest'
multisite: false

# WP 5.6 is the earliest version which (sort of) supports PHP 8.0.
- php_version: '8.0'
wp_version: '5.8'
multisite: false

# WP 5.9 is the earliest version which (sort of) supports PHP 8.1.
- php_version: '8.1'
wp_version: 'latest'
multisite: true

name: "Integration Test: PHP ${{ matrix.php_version }} | WP ${{ matrix.wp_version }}${{ matrix.multisite == true && ' (+ ms)' || '' }}"

# Allow builds to fail on as-of-yet unreleased WordPress versions.
continue-on-error: ${{ matrix.wp_version == 'trunk' }}

services:
mysql:
# Use MySQL 5.6 for PHP 5.6, use MySQL 5.7 for PHP 7.0 < 7.4, otherwise MySQL 8.0.
# Also see: https://core.trac.wordpress.org/ticket/52496
image: mysql:${{ ( matrix.php_version == '5.6' && '5.6' ) || ( matrix.php_version < '7.4' && '5.7' ) || '8.0' }}
env:
MYSQL_ALLOW_EMPTY_PASSWORD: false
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=10s --health-retries=10

steps:
- name: Checkout code
uses: actions/checkout@v3

# The prefix-dependencies task makes use of reflection-based PHP code that only works on PHP > 7.2.
- name: Install PHP 7.x for generating the vendor_prefixed directory and dependency injection
uses: shivammathur/setup-php@v2
with:
php-version: 7.2
coverage: none

- name: Install Composer dependencies, generate vendor_prefixed directory and run dependency injection
uses: ramsey/composer-install@v2

# Remove packages which are not PHP cross-version compatible and only used for the prefixing.
# - humbug/php-scoper is only needed to actually do the prefixing, so won't be shipped anyway.
# - league/oauth2-client and its dependencies *are* the packages being prefixed.
- name: Delete dependencies which are not cross-version compatible
run: composer remove --dev --no-scripts humbug/php-scoper league/oauth2-client

- name: Remove vendor directory
run: rm -rf vendor/*

- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php_version }}
ini-values: zend.assertions=1, error_reporting=-1, display_errors=On
coverage: none

# Determine the type of Composer install which is needed.
# 1: WP 5.9 or higher - all PHPUnit versions needed are supported, use the most appropriate one.
# 2. WP < 5.9 with PHP 8.0 or higher - PHPUnit 5 - 7 supported, locked at 5.x, but needs upgrade to 7 for PHP >= 8.0.
# 3. WP < 5.9 with PHP < 8.0 - just use the locked PHPUnit 5 version.
- name: Determine the type of Composer install to use
id: composer_toggle
run: |
if [[ "${{ matrix.wp_version }}" =~ ^(trunk|latest|5\.9|[6789]\.[0-9])$ ]]; then
echo '::set-output name=TYPE::1'
elif [[ "${{ matrix.php_version }}" > "7.4" ]]; then
echo '::set-output name=TYPE::2'
else
echo '::set-output name=TYPE::3'
fi
- name: Debug info - show type determined
run: echo ${{ steps.composer_toggle.outputs.TYPE }}

# Install dependencies and handle caching in one go.
# Includes updating the test dependencies to the most appropriate version
# for the PHP/WP version combination on which the tests will be run.
# @link https://github.com/marketplace/actions/install-composer-dependencies

### Install type 1.
- name: "Install type 1: remove PHPUnit root requirement"
run: composer remove --dev phpunit/phpunit --no-update --no-scripts

- name: "Install type 1: install Composer dependencies - WP 5.9 or higher"
if: ${{ steps.composer_toggle.outputs.TYPE == '1' }}
uses: ramsey/composer-install@v2
with:
# Force a `composer update` run.
dependency-versions: "highest"
# But make it selective.
composer-options: "yoast/wp-test-utils --with-dependencies --no-scripts"

### Install type 2.
- name: "Install type 2: conditionally require a higher PHPUnit version"
if: ${{ steps.composer_toggle.outputs.TYPE == '2' }}
run: composer require --dev phpunit/phpunit:"^7.5" --no-update --ignore-platform-req=php --no-scripts

- name: "Install type 2: install Composer dependencies - WP < 5.9 with PHP >= 8.0"
if: ${{ steps.composer_toggle.outputs.TYPE == '2' }}
uses: ramsey/composer-install@v2
with:
# Force a `composer update` run.
dependency-versions: "highest"
# But make it selective.
composer-options: "yoast/wp-test-utils phpunit/phpunit --with-dependencies --no-scripts --ignore-platform-req=php"

### Install type 3.
# As PHPUnit is a root requirement and some of the PHPUnit dependencies are locked at versions incompatible
# with all supported PHP versions, the PHPUnit dependency needs to explicitly also be allowed to update
# (within the version constraints as per the `composer.json` file, i.e. PHPUnit 5.7).
- name: "Install type 3: install Composer dependencies - WP < 5.9 with PHP < 8.0"
if: ${{ steps.composer_toggle.outputs.TYPE == '3' }}
uses: ramsey/composer-install@v2
with:
# Force a `composer update` run.
dependency-versions: "highest"
# But make it selective.
composer-options: "yoast/wp-test-utils phpunit/phpunit --with-dependencies --no-scripts"

- name: Install WP
shell: bash
run: config/scripts/install-wp-tests.sh wordpress_test root '' 127.0.0.1:3306 ${{ matrix.wp_version }}

- name: Run unit tests - single site
run: composer integration-test

- name: Run unit tests - multisite
if: ${{ matrix.multisite == true }}
run: composer integration-test
env:
WP_MULTISITE: 1
135 changes: 4 additions & 131 deletions .travis.yml
Expand Up @@ -2,9 +2,6 @@ os: linux
dist: xenial
language: php

services:
- mysql

branches:
only:
- master
Expand All @@ -15,33 +12,13 @@ branches:
# Also build tags like 1.1.1 or 1.1 for deployment.
- /^\d+\.\d+(\.\d+)?(-\S*)?$/

stages:
# Don't run the test steps on tag builds, this makes tag deployments a ton faster.
- name: test
if: NOT tag is present
- 🚀 deployment

jobs:
fast_finish: true
include:
- php: 7.3.24
env: WP_VERSION=latest WP_MULTISITE=1 COVERAGE=1
- php: 5.6
env: WP_VERSION=5.8 WP_MULTISITE=1 PHPUNIT=1
# Use 'trusty' to test against MySQL 5.6, 'xenial' contains 5.7 by default.
dist: trusty
- php: 7.3
env: WP_VERSION=trunk PHPUNIT=1
- php: 7.4
env: WP_VERSION=latest PHPUNIT=1
- php: 8.0
env: WP_VERSION=latest PHPUNIT=1
- php: "nightly"
- stage: 🚀 deployment
name: "Deploy to S3"
if: branch = deploy # Only build when on the `deploy` branch, this functionality is not used yet and is taking a long time to complete.
env: SC_ATTR=wordpress-seo
before_script: skip
script: grunt artifact
install:
- yarn global add grunt-cli
Expand All @@ -66,7 +43,6 @@ jobs:
install:
- yarn global add grunt-cli
- yarn install
before_script: skip
script:
- |
if [[ ! -z "$TRAVIS_TAG" ]]; then
Expand All @@ -93,25 +69,18 @@ jobs:
repo: $TRAVIS_REPO_SLUG
all_branches: true

allow_failures:
# Allow failures for unstable builds.
- php: "nightly"
- php: 7.3
env: WP_VERSION=trunk PHPUNIT=1

cache:
yarn: true
directories:
- $HOME/.composer/cache
- node_modules

before_install:
- if [[ -z "$CC_TEST_REPORTER_ID" ]]; then COVERAGE="0"; fi
- if [[ "$COVERAGE" != "1" ]]; then phpenv config-rm xdebug.ini || echo 'No xdebug config.'; fi
- phpenv config-rm xdebug.ini || echo 'No xdebug config.'

install:
- |
if [[ "$PHPUNIT" == "1" || "$COVERAGE" == "1" || "$TRAVIS_BUILD_STAGE_NAME" == "🚀 deployment" ]]; then
if [[ "$TRAVIS_BUILD_STAGE_NAME" == "🚀 deployment" ]]; then
# The prefix-dependencies task only works on PHP 7.1 and we need to prefix our dependencies to accurately test them.
# So we temporarily switch PHP versions, do a full install and then remove the package.
# Then switch back to the PHP version we want to test and delete the vendor directory.
Expand All @@ -126,110 +95,14 @@ install:
rm -rf vendor/*
fi
- |
if [[ "$COVERAGE" == "1" ]]; then
# Install phpcov so we can combine the coverage results of unit and integration tests.
travis_retry composer require phpunit/phpcov ^3.1 --no-interaction
fi
- |
if [[ ${TRAVIS_PHP_VERSION:0:1} == "8" || $TRAVIS_PHP_VERSION == "nightly" ]]; then
travis_retry composer install --no-interaction --ignore-platform-reqs --no-scripts --no-suggest
elif [[ "$PHPUNIT" == "1" || "$COVERAGE" == "1" ]]; then
# Run composer update as we have dev dependencies locked at PHP ^7.0 versions.
travis_retry composer update --no-interaction --no-scripts
travis_retry composer install --no-interaction --no-scripts
travis_retry composer du --no-scripts
elif [[ "$TRAVIS_BUILD_STAGE_NAME" == "🚀 deployment" ]]; then
if [[ "$TRAVIS_BUILD_STAGE_NAME" == "🚀 deployment" ]]; then
travis_retry composer update --no-interaction
travis_retry composer install --no-dev --no-interaction
composer du
fi
before_script:
# Careful: The HTTPS version of the following URL is different, therefore we need to use HTTP.
- |
if [[ "$PHPUNIT" == "1" || "$COVERAGE" == "1" ]]; then
if [[ "$WP_VERSION" == "latest" ]]; then
curl -s http://api.wordpress.org/core/version-check/1.7/ > /tmp/wp-latest.json
WP_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
fi
PLUGIN_SLUG=$(basename $(pwd))
export WP_DEVELOP_DIR=/tmp/wordpress/
git clone --depth=1 --branch="$WP_VERSION" git://develop.git.wordpress.org/ /tmp/wordpress
cd ..
cp -r "$PLUGIN_SLUG" "/tmp/wordpress/src/wp-content/plugins/$PLUGIN_SLUG"
cd /tmp/wordpress/
cp wp-tests-config-sample.php wp-tests-config.php
sed -i "s/youremptytestdbnamehere/wordpress_tests/" wp-tests-config.php
sed -i "s/yourusernamehere/travis/" wp-tests-config.php
sed -i "s/yourpasswordhere//" wp-tests-config.php
mysql -e "CREATE DATABASE wordpress_tests;" -uroot
cd "/tmp/wordpress/src/wp-content/plugins/$PLUGIN_SLUG"
mkdir src/generated/assets
echo "<?php return [ 'post-edit.js' => [ 'dependencies' => [], 'version' => 'test' ], 'installation-success.js' => [ 'dependencies' => [], 'version' => 'test' ], 'workouts.js' => [ 'dependencies' => [], 'version' => 'test' ] ];" >> src/generated/assets/plugin.php
echo "<?php return [];" >> src/generated/assets/externals.php
echo "<?php return [];" >> src/generated/assets/languages.php
fi
- phpenv rehash
- |
if [[ "$COVERAGE" == "1" ]]; then
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
chmod +x ./cc-test-reporter
./cc-test-reporter before-build
mkdir -p /tmp/coverage
fi
- export -f travis_fold
- export -f travis_time_start
- export -f travis_time_finish
- mysql --version
- phpenv versions
- php --version
- php -m
- curl --version
- git --version
- svn --version
- locale -a

script:
# PHP Unit
- |
if [[ "$PHPUNIT" == "1" && ${TRAVIS_PHP_VERSION:0:1} != "8" && $TRAVIS_PHP_VERSION != "nightly" ]]; then
# PHP < 8
travis_fold start "PHP.integration-tests" && travis_time_start
vendor/bin/phpunit -c phpunit-integration.xml.dist
travis_time_finish && travis_fold end "PHP.integration-tests"
elif [[ "$PHPUNIT" == "1" ]] && [[ ${TRAVIS_PHP_VERSION:0:1} == "8" || $TRAVIS_PHP_VERSION == "nightly" ]] && [[ ${WP_VERSION:0:3} == "5.9" || ${WP_VERSION:0:1} == "6" || $WP_VERSION == "trunk" ]]; then
# PHP >= 8 with WP >= 5.9
travis_fold start "PHP.integration-tests" && travis_time_start
travis_retry composer remove --dev phpunit/phpunit --no-update --no-interaction &&
travis_retry composer update yoast/wp-test-utils --no-interaction --with-dependencies --ignore-platform-req=php &&
vendor/bin/phpunit -c phpunit-integration.xml.dist
travis_time_finish && travis_fold end "PHP.integration-tests"
elif [[ "$PHPUNIT" == "1" ]] && [[ ${TRAVIS_PHP_VERSION:0:1} == "8" || $TRAVIS_PHP_VERSION == "nightly" ]]; then
# PHP >= 8 with WP < 5.9
travis_fold start "PHP.integration-tests" && travis_time_start
travis_retry composer require --dev phpunit/phpunit:"^7.5" --update-with-dependencies --ignore-platform-reqs --no-interaction &&
vendor/bin/phpunit -c phpunit-integration.xml.dist
travis_time_finish && travis_fold end "PHP.integration-tests"
fi
- |
if [[ "$COVERAGE" == "1" ]]; then
travis_fold start "PHP.coverage" && travis_time_start
vendor/bin/phpunit -c phpunit-integration.xml.dist --coverage-php /tmp/coverage/integration-tests.cov
travis_time_finish && travis_fold end "PHP.coverage"
fi
- |
if [[ "$COVERAGE" == "1" ]]; then
travis_fold start "PHP.coverage" && travis_time_start
vendor/bin/phpunit --coverage-php /tmp/coverage/tests.cov
travis_time_finish && travis_fold end "PHP.coverage"
fi
after_script:
- |
if [[ "$COVERAGE" == "1" ]]; then
./vendor/bin/phpcov merge /tmp/coverage --clover build/logs/clover.xml
fi
- if [[ "$COVERAGE" == "1" ]]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT; fi
- git status

notifications:
slack:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -5,7 +5,7 @@
[![LintJS](https://github.com/Yoast/wordpress-seo/actions/workflows/jslint.yml/badge.svg)](https://github.com/Yoast/wordpress-seo/actions/workflows/jslint.yml)
[![TestJS](https://github.com/Yoast/wordpress-seo/actions/workflows/jstest.yml/badge.svg)](https://github.com/Yoast/wordpress-seo/actions/workflows/jstest.yml)
[![Unit Tests](https://github.com/Yoast/wordpress-seo/actions/workflows/unittest.yml/badge.svg)](https://github.com/Yoast/wordpress-seo/actions/workflows/unittest.yml)
[![Build Status](https://api.travis-ci.com/Yoast/wordpress-seo.svg?branch=master)](https://travis-ci.com/Yoast/wordpress-seo)
[![Integration Tests](https://github.com/Yoast/wordpress-seo/actions/workflows/integrationtest.yml/badge.svg)](https://github.com/Yoast/wordpress-seo/actions/workflows/integrationtest.yml)
[![Stable Version](https://poser.pugx.org/yoast/wordpress-seo/v/stable.svg)](https://packagist.org/packages/yoast/wordpress-seo)
[![License](https://poser.pugx.org/yoast/wordpress-seo/license.svg)](https://packagist.org/packages/yoast/wordpress-seo)

Expand Down

0 comments on commit 359cf04

Please sign in to comment.