Merge pull request #7637 from ampproject/dependabot/npm_and_yarn/post… #1472
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build, test & measure | |
on: | |
push: | |
branches: | |
- develop | |
# Include all release branches. | |
- '[0-9]+.[0-9]+' | |
pull_request: | |
# Run workflow whenever a PR is opened, updated (synchronized), or marked ready for review. | |
types: [opened, synchronize, ready_for_review] | |
# Cancel previous workflow run groups that have not completed. | |
concurrency: | |
# Group workflow runs by workflow name, along with the head branch ref of the pull request | |
# or otherwise the branch or tag ref. | |
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.ref }} | |
cancel-in-progress: true | |
jobs: | |
pre-run: | |
name: 'Pre run' | |
runs-on: ubuntu-latest | |
outputs: | |
changed-file-count: ${{ steps.determine-file-counts.outputs.count }} | |
changed-php-count: ${{ steps.determine-file-counts.outputs.php-count }} | |
changed-css-count: ${{ steps.determine-file-counts.outputs.css-count }} | |
changed-js-count: ${{ steps.determine-file-counts.outputs.js-count }} | |
changed-gha-workflow-count: ${{ steps.determine-file-counts.outputs.gha-workflow-count }} | |
steps: | |
- name: Checkout including last 2 commits | |
# Fetch last 2 commits if it's not a PR, so that we can determine the list of modified files. | |
if: ${{ github.base_ref == null }} | |
uses: actions/checkout@v3 | |
with: | |
fetch-depth: 2 | |
- name: Checkout | |
# Do usual checkout if it's a PR. | |
if: ${{ github.base_ref != null }} | |
uses: actions/checkout@v3 | |
- name: Fetch base branch | |
# Only fetch base ref if it's a PR. | |
if: ${{ github.base_ref != null }} | |
run: git fetch --depth=1 --no-tags origin ${{ github.base_ref }} | |
- name: Determine modified files for PR | |
if: ${{ github.base_ref != null }} | |
run: echo "MODIFIED_FILES=$(git diff --name-only FETCH_HEAD HEAD | base64 -w 0)" >> $GITHUB_ENV | |
- name: Determine modified files for commit | |
if: ${{ github.base_ref == null }} | |
run: echo "MODIFIED_FILES=$(git diff --name-only HEAD~1 HEAD | base64 -w 0)" >> $GITHUB_ENV | |
- id: determine-file-counts | |
name: Determine if modified files should make the workflow run continue | |
run: | | |
MODIFIED_FILES=$(echo "$MODIFIED_FILES" | base64 -d) | |
echo -e "Modified files:\n$MODIFIED_FILES\n" | |
FILE_COUNT=$(php -f bin/determine-modified-files-count.php "$IGNORE_PATH_REGEX" "$MODIFIED_FILES" --invert) | |
PHP_FILE_COUNT=$(php -f bin/determine-modified-files-count.php ".+\.php|composer\.(json|lock)|phpstan\.neon\.dist" "$MODIFIED_FILES") | |
CSS_FILE_COUNT=$(php -f bin/determine-modified-files-count.php ".+\.s?css|package\.json|package-lock\.json" "$MODIFIED_FILES") | |
JS_FILE_COUNT=$(php -f bin/determine-modified-files-count.php ".+\.(js|snap)|package\.json|package-lock\.json" "$MODIFIED_FILES") | |
GHA_WORKFLOW_COUNT=$(php -f bin/determine-modified-files-count.php "(\.github\/workflows\/.+\.yml)" "$MODIFIED_FILES") | |
echo "Changed file count: $FILE_COUNT" | |
echo "Changed PHP file count: $PHP_FILE_COUNT" | |
echo "Changed CSS file count: $CSS_FILE_COUNT" | |
echo "Changed JS file count: $JS_FILE_COUNT" | |
echo "Changed GHA workflow file count: $GHA_WORKFLOW_COUNT" | |
echo "count=$FILE_COUNT" >> $GITHUB_OUTPUT | |
echo "php-count=$PHP_FILE_COUNT" >> $GITHUB_OUTPUT | |
echo "css-count=$CSS_FILE_COUNT" >> $GITHUB_OUTPUT | |
echo "js-count=$JS_FILE_COUNT" >> $GITHUB_OUTPUT | |
echo "gha-workflow-count=$GHA_WORKFLOW_COUNT" >> $GITHUB_OUTPUT | |
env: | |
# Ignore Paths: | |
# - .github/ | |
# - !.github/workflows | |
# - .wordpress-org/ | |
# - docs/ | |
IGNORE_PATH_REGEX: \.github\/(?!workflows)|\.wordpress-org\/|docs\/ | |
lint-css: | |
needs: pre-run | |
if: needs.pre-run.outputs.changed-css-count > 0 || needs.pre-run.outputs.changed-gha-workflow-count > 0 | |
name: 'Lint: CSS' | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup Node | |
uses: actions/[email protected] | |
with: | |
node-version-file: '.nvmrc' | |
cache: npm | |
- name: Install Node dependencies | |
run: npm ci | |
- name: Detect coding standard violations (stylelint) | |
run: npm run lint:css | |
#----------------------------------------------------------------------------------------------------------------------- | |
lint-js: | |
name: 'Lint: JS' | |
needs: pre-run | |
if: needs.pre-run.outputs.changed-js-count > 0 || needs.pre-run.outputs.changed-gha-workflow-count > 0 | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup Node | |
uses: actions/[email protected] | |
with: | |
node-version-file: '.nvmrc' | |
cache: npm | |
- name: Install Node dependencies | |
run: npm ci | |
- name: Validate package.json | |
run: npm run lint:pkg-json | |
- name: Detect ESLint coding standard violations | |
if: > | |
github.event.pull_request.head.repo.fork == true || | |
github.event.pull_request.user.login == 'dependabot[bot]' | |
run: npm run lint:js | |
- name: Generate ESLint coding standard violations report | |
# Prevent generating the ESLint report if PR is from a fork or authored by Dependabot. | |
if: > | |
! ( github.event.pull_request.head.repo.fork == true || | |
github.event.pull_request.user.login == 'dependabot[bot]' ) | |
run: npm run lint:js:report | |
continue-on-error: true | |
- name: Annotate code linting results | |
# The action cannot annotate the PR when run from a PR fork or was authored by Dependabot. | |
if: > | |
! ( github.event.pull_request.head.repo.fork == true || | |
github.event.pull_request.user.login == 'dependabot[bot]' ) | |
uses: ataylorme/[email protected] | |
with: | |
repo-token: '${{ secrets.GITHUB_TOKEN }}' | |
report-json: 'lint-js-report.json' | |
#----------------------------------------------------------------------------------------------------------------------- | |
normalize-composer: | |
name: 'Normalize composer.json' | |
needs: pre-run | |
if: needs.pre-run.outputs.changed-php-count > 0 || needs.pre-run.outputs.changed-gha-workflow-count > 0 | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup PHP | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: '8.1' | |
coverage: none | |
- name: Get composer-normalize.phar | |
run: | | |
wget https://github.com/ergebnis/composer-normalize/releases/latest/download/composer-normalize.phar | |
# Check if phar is actually downloaded. | |
if [ ! -f composer-normalize.phar ]; then | |
sleep 5 | |
wget https://github.com/ergebnis/composer-normalize/releases/latest/download/composer-normalize.phar | |
fi | |
# If not downloaded, exit with error this time. | |
if [ ! -f composer-normalize.phar ]; then | |
echo "::error::Failed to download composer-normalize.phar" | |
exit 1 | |
fi | |
chmod +x composer-normalize.phar | |
- name: Validate composer.json | |
run: composer --no-interaction validate --no-check-all | |
- name: Normalize composer.json | |
run: | | |
composer config --no-interaction --no-plugins allow-plugins.ergebnis/composer-normalize true | |
./composer-normalize.phar --dry-run | |
#----------------------------------------------------------------------------------------------------------------------- | |
lint-php: | |
name: 'Lint: PHP' | |
needs: pre-run | |
if: needs.pre-run.outputs.changed-php-count > 0 || needs.pre-run.outputs.changed-gha-workflow-count > 0 | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup PHP | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: '8.0' | |
coverage: none | |
tools: cs2pr | |
- name: Get Composer Cache Directory | |
id: composer-cache | |
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT | |
- name: Configure Composer cache | |
uses: actions/[email protected] | |
with: | |
path: ${{ steps.composer-cache.outputs.dir }} | |
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | |
restore-keys: | | |
${{ runner.os }}-composer- | |
- name: Install Composer dependencies | |
run: composer install --prefer-dist --optimize-autoloader --no-progress --no-interaction | |
- name: Detect coding standard violations (PHPCS) | |
run: vendor/bin/phpcs -q --report=checkstyle --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 | cs2pr --graceful-warnings | |
#----------------------------------------------------------------------------------------------------------------------- | |
static-analysis-php: | |
name: 'Static Analysis: PHP' | |
runs-on: ubuntu-latest | |
needs: pre-run | |
if: needs.pre-run.outputs.changed-php-count > 0 || needs.pre-run.outputs.changed-gha-workflow-count > 0 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup PHP | |
uses: shivammathur/setup-php@v2 | |
with: | |
# phpstan requires PHP 7.1+. | |
php-version: '8.0' | |
extensions: dom, iconv, json, libxml, zip | |
tools: phpstan | |
- name: Get Composer Cache Directory | |
id: composer-cache | |
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT | |
- name: Configure Composer cache | |
uses: actions/[email protected] | |
with: | |
path: ${{ steps.composer-cache.outputs.dir }} | |
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | |
restore-keys: | | |
${{ runner.os }}-composer- | |
- name: Install Composer dependencies | |
run: composer install | |
- name: Static Analysis (PHPStan) | |
run: | | |
phpstan --version | |
phpstan analyse | |
#----------------------------------------------------------------------------------------------------------------------- | |
unit-test-js: | |
name: 'Unit test: JS' | |
runs-on: ubuntu-latest | |
needs: pre-run | |
if: needs.pre-run.outputs.changed-js-count > 0 || needs.pre-run.outputs.changed-gha-workflow-count > 0 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup Node | |
uses: actions/[email protected] | |
with: | |
node-version-file: '.nvmrc' | |
cache: npm | |
- name: Setup Jest cache | |
uses: actions/[email protected] | |
with: | |
path: ~/.jest-cache | |
key: ${{ runner.os }}-jest | |
- name: Install Node dependencies | |
run: npm ci | |
- name: Run unit tests (with coverage) | |
run: npm run test:js -- --ci --cacheDirectory="$HOME/.jest-cache" --collectCoverage | |
- name: Upload code coverage report | |
if: github.actor != 'dependabot[bot]' | |
uses: codecov/codecov-action@v3 | |
with: | |
file: build/logs/lcov.info | |
flags: javascript | |
fail_ci_if_error: true | |
#----------------------------------------------------------------------------------------------------------------------- | |
e2e-test-js: | |
name: 'E2E test: JS' | |
needs: pre-run | |
if: needs.pre-run.outputs.changed-file-count > 0 | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup PHP | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: '8.0' | |
- name: Setup Node | |
uses: actions/[email protected] | |
with: | |
node-version-file: '.nvmrc' | |
cache: npm | |
- name: Get Composer Cache Directory | |
id: composer-cache | |
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT | |
- name: Configure Composer cache | |
uses: actions/[email protected] | |
with: | |
path: ${{ steps.composer-cache.outputs.dir }} | |
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | |
restore-keys: | | |
${{ runner.os }}-composer- | |
- name: Install Node dependencies | |
run: npm ci | |
- name: Install Composer dependencies | |
run: composer install --prefer-dist --optimize-autoloader --no-progress --no-interaction | |
- name: Build plugin | |
run: npm run build:js | |
- name: Start Docker environment | |
run: npm run env:start:ci | |
env: | |
COMPOSE_INTERACTIVE_NO_CLI: true | |
- name: Run E2E tests | |
run: npm run test:e2e:ci | |
- name: Stop Docker environment | |
run: npm run env:stop:ci | |
if: always() | |
env: | |
COMPOSE_INTERACTIVE_NO_CLI: true | |
- name: Upload artifacts | |
uses: actions/upload-artifact@v3 | |
if: failure() | |
with: | |
name: amp-e2e-artifacts | |
path: artifacts | |
#----------------------------------------------------------------------------------------------------------------------- | |
# Adapted from workflow for running PHP unit tests on google/web-stories-wp. | |
# See https://github.com/google/web-stories-wp/blob/cb2ebada48039171e25c279bdb27d3712dd70b22/.github/workflows/continuous-integration-unit-php.yml | |
unit-test-php: | |
name: "Unit test${{ matrix.coverage && ' (with coverage)' || '' }}: PHP ${{ matrix.php }}, WP ${{ matrix.wp }}" | |
runs-on: ubuntu-latest | |
needs: pre-run | |
env: | |
WP_CORE_DIR: /tmp/wordpress | |
services: | |
mysql: | |
image: mariadb:latest | |
env: | |
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: true | |
MARIADB_DATABASE: wordpress_test | |
MARIADB_MYSQL_LOCALHOST_USER: 1 | |
MARIADB_MYSQL_LOCALHOST_GRANTS: USAGE | |
ports: | |
- 3306 | |
options: --health-cmd="healthcheck.sh --su-mysql --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=3 | |
continue-on-error: ${{ matrix.experimental == true }} | |
strategy: | |
fail-fast: false | |
matrix: | |
php: ['8.0'] | |
wp: ['latest'] | |
external-http: [false] | |
install-pwa-plugin: [true] | |
coverage: [false] | |
include: | |
- php: '8.3' | |
wp: 'trunk' | |
phpunit: '9.6' | |
experimental: true | |
- php: '8.2' | |
wp: 'trunk' | |
phpunit: '9.6' | |
- php: '8.1' | |
wp: 'trunk' | |
phpunit: '9.6' | |
- php: '8.0' | |
wp: 'trunk' | |
phpunit: '9.3' | |
multisite: true | |
- php: '8.0' | |
wp: 'latest' | |
phpunit: '9.3' | |
coverage: true | |
- php: '8.0' | |
wp: 'latest' | |
phpunit: '9.3' | |
external-http: true | |
- php: '7.4' | |
wp: 'latest' | |
phpunit: '9.3' | |
multisite: true | |
- php: '7.4' | |
wp: 'latest' | |
phpunit: '9.3' | |
external-http: true | |
- php: '7.4' | |
wp: '5.3' | |
phpunit: '7' | |
- php: '7.4' | |
wp: '5.3' | |
phpunit: '7' | |
external-http: true | |
steps: | |
# Note: The repeated `needs.pre-run.outputs.changed-php-count > 0` checks would be avoided if a step could short- | |
# circuit per <https://github.com/actions/runner/issues/662>. The reason why the if statement can't be put on the | |
# job as a whole is because the name is variable based on the matrix, and if the condition is not met then the | |
# name won't be interpolated in order to match the required jobs set up in branch protection. | |
- name: Notice | |
if: needs.pre-run.outputs.changed-php-count == 0 | |
run: echo "No PHP files were changed so no PHP unit tests will run" | |
- name: Checkout | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
uses: actions/checkout@v3 | |
- name: Setup PHP | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: ${{ matrix.php }} | |
extensions: curl, date, dom, gd, iconv, json, libxml, mysql, spl | |
tools: phpunit:${{ matrix.phpunit }} | |
coverage: ${{ matrix.coverage && 'xdebug' || 'none' }} | |
- name: Shutdown default MySQL service | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
run: sudo service mysql stop | |
- name: Verify MariaDB connection | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
run: | | |
while ! mysqladmin ping -h"127.0.0.1" -P"${{ job.services.mysql.ports[3306] }}" --silent; do | |
sleep 1 | |
done | |
- name: Setup Node | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
uses: actions/[email protected] | |
with: | |
node-version-file: '.nvmrc' | |
cache: npm | |
- name: Get Composer Cache Directory | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
id: composer-cache | |
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT | |
- name: Configure Composer cache | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
uses: actions/[email protected] | |
with: | |
path: ${{ steps.composer-cache.outputs.dir }} | |
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | |
restore-keys: | | |
${{ runner.os }}-composer- | |
- name: Install Composer dependencies | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
run: composer install --prefer-dist --ignore-platform-reqs --no-progress --no-interaction | |
# Since locally installed PHPUnit classes are loaded into the classmap, running tests with globally | |
# installed PHPUnit requires removing locally installed PHPUnit. Additionally, using the workflow matrix | |
# makes it simple for us to maintain different PHPUnit versions for various PHP versions. | |
- name: Remove locally installed PHPUnit | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
run: | | |
rm -rf vendor/phpunit | |
composer dump-autoload -o | |
- name: Install Node dependencies | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
run: npm ci | |
- name: Build plugin | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
run: npm run build:js | |
# Scan the logs for failing tests and surface that information by creating annotations and log file decorations. | |
- name: Setup problem matcher to provide annotations for PHPUnit | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
# The JSON file is provided by the `shivammathur/setup-php` action. See https://github.com/shivammathur/setup-php#problem-matchers. | |
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" | |
- name: Install WP tests | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
run: bash bin/ci/install-wp-tests.sh wordpress_test root '' 127.0.0.1:${{ job.services.mysql.ports['3306'] }} ${{ matrix.wp }} true | |
- name: Post install of WP tests | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
run: bash bin/ci/after-wp-install.sh ${{ matrix.wp }} ${{ matrix.install-pwa-plugin == true }} | |
- name: Copy plugin to WP plugins directory | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
run: cp -r "$PWD" "$WP_CORE_DIR/src/wp-content/plugins/amp" | |
- name: Setup required WP constants | |
run: | | |
echo "WP_ENVIRONMENT_TYPE=local" >> $GITHUB_ENV | |
- name: Run tests | |
if: ${{ matrix.coverage == false && needs.pre-run.outputs.changed-php-count > 0 }} | |
run: | | |
phpunit --version | |
phpunit --verbose | |
working-directory: ${{ env.WP_CORE_DIR }}/src/wp-content/plugins/amp | |
env: | |
WP_TESTS_DIR: /tmp/wordpress-tests-lib | |
- name: Run multisite tests | |
if: ${{ matrix.multisite == true && needs.pre-run.outputs.changed-php-count > 0 }} | |
run: | | |
phpunit --version | |
phpunit --verbose | |
working-directory: ${{ env.WP_CORE_DIR }}/src/wp-content/plugins/amp | |
env: | |
WP_TESTS_DIR: /tmp/wordpress-tests-lib | |
WP_MULTISITE: 1 | |
- name: Run tests with coverage | |
if: ${{ matrix.coverage == true && needs.pre-run.outputs.changed-php-count > 0 }} | |
run: | | |
phpunit --version | |
phpunit --verbose --coverage-clover ${{ env.WP_CORE_DIR }}/src/wp-content/plugins/amp/build/logs/clover.xml | |
working-directory: ${{ env.WP_CORE_DIR }}/src/wp-content/plugins/amp | |
env: | |
WP_TESTS_DIR: /tmp/wordpress-tests-lib | |
- name: Run external HTTP tests | |
if: ${{ matrix.external-http == true && needs.pre-run.outputs.changed-php-count > 0 }} | |
run: | | |
phpunit --version | |
phpunit --testsuite external-http --verbose | |
working-directory: ${{ env.WP_CORE_DIR }}/src/wp-content/plugins/amp | |
env: | |
WP_TESTS_DIR: /tmp/wordpress-tests-lib | |
- name: Upload code coverage report | |
if: ${{ matrix.coverage == true && needs.pre-run.outputs.changed-php-count > 0 && github.actor != 'dependabot[bot]' }} | |
uses: codecov/codecov-action@v3 | |
with: | |
file: ${{ env.WP_CORE_DIR }}/src/wp-content/plugins/amp/build/logs/clover.xml | |
flags: php,unit | |
fail_ci_if_error: true | |
#----------------------------------------------------------------------------------------------------------------------- | |
feature-test-php: | |
name: "Feature test${{ matrix.coverage && ' (with coverage)' || '' }}: PHP ${{ matrix.php }}, WP ${{ matrix.wp }}" | |
needs: pre-run | |
if: needs.pre-run.outputs.changed-php-count > 0 | |
runs-on: ubuntu-latest | |
env: | |
WP_VERSION: ${{ matrix.wp }} | |
services: | |
mysql: | |
image: mariadb:latest | |
env: | |
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: true | |
MARIADB_DATABASE: wordpress_test | |
MARIADB_MYSQL_LOCALHOST_USER: 1 | |
MARIADB_MYSQL_LOCALHOST_GRANTS: USAGE | |
ports: | |
- 3306 | |
options: --health-cmd="healthcheck.sh --su-mysql --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=3 | |
continue-on-error: ${{ matrix.experimental == true }} | |
strategy: | |
fail-fast: false | |
matrix: | |
# @TODO: Revisit this if we want to enable code coverage for feature tests. | |
coverage: [false] | |
php: ['7.4'] | |
wp: ['latest'] | |
include: | |
- php: '8.3' | |
wp: 'trunk' | |
experimental: true | |
- php: '8.2' | |
wp: 'trunk' | |
experimental: true | |
- php: '8.1' | |
wp: 'trunk' | |
- php: '8.0' | |
wp: 'latest' | |
- php: '7.4' | |
wp: '5.3' | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup PHP | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: ${{ matrix.php }} | |
extensions: curl, date, dom, gd, iconv, json, libxml, mysql, spl | |
coverage: ${{ matrix.coverage && 'pcov' || 'none' }} | |
ini-values: pcov.directory=. | |
- name: Shutdown default MySQL service | |
run: sudo service mysql stop | |
- name: Verify MariaDB connection | |
run: | | |
while ! mysqladmin ping -h"127.0.0.1" -P"${{ job.services.mysql.ports[3306] }}" --silent; do | |
sleep 1 | |
done | |
- name: Setup Node | |
uses: actions/[email protected] | |
with: | |
node-version-file: '.nvmrc' | |
cache: npm | |
- name: Get Composer Cache Directory | |
id: composer-cache | |
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT | |
- name: Configure Composer cache | |
uses: actions/[email protected] | |
with: | |
path: ${{ steps.composer-cache.outputs.dir }} | |
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | |
restore-keys: | | |
${{ runner.os }}-composer- | |
- name: Install Composer dependencies | |
run: composer install --prefer-dist --ignore-platform-reqs --no-progress --no-interaction | |
- name: Install Node dependencies | |
run: npm ci | |
- name: Build plugin | |
run: npm run build:js | |
# @TODO: Revisit this if we want to enable code coverage for feature tests. | |
# - name: Update PHPUnit to get latest php-code-coverage library | |
# if: ${{ matrix.coverage == true }} | |
# # phpdocumentor/reflection has to be removed as it makes use of an outdated dependency. | |
# # phpunit/phpunit has to be updated as the one in use provides an older version of phpunit/php-code-coverage, | |
# # but we need the v9.x branch. | |
# # It cannot be removed, as it is a requirement of wp-cli/wp-cli-tests as well. | |
# run: | | |
# composer remove --dev phpdocumentor/reflection | |
# composer require --dev --ignore-platform-reqs --update-with-all-dependencies phpunit/phpunit | |
- name: Configure DB environment | |
run: | | |
echo "MYSQL_HOST=127.0.0.1" >> $GITHUB_ENV | |
echo "MYSQL_TCP_PORT=${{ job.services.mysql.ports['3306'] }}" >> $GITHUB_ENV | |
echo "WP_CLI_TEST_DBROOTUSER=root" >> $GITHUB_ENV | |
echo "WP_CLI_TEST_DBROOTPASS=" >> $GITHUB_ENV | |
echo "WP_CLI_TEST_DBUSER=wp_cli_test" >> $GITHUB_ENV | |
echo "WP_CLI_TEST_DBPASS=password1" >> $GITHUB_ENV | |
echo "WP_CLI_TEST_DBHOST=127.0.0.1:${{ job.services.mysql.ports['3306'] }}" >> $GITHUB_ENV | |
- name: Prepare test database | |
run: composer prepare-tests | |
- name: Run tests | |
env: | |
BEHAT_CODE_COVERAGE: ${{ matrix.coverage }} | |
run: vendor/bin/behat | |
- name: Retrieve list of coverage files | |
if: ${{ matrix.coverage == true }} | |
run: | | |
FILES=$(ls -d -1 "$GITHUB_WORKSPACE/build/logs/clover-behat/"*.* | xargs echo | sed 's/ /,/g') | |
echo $FILES | |
echo "COVERAGE_FILES=$FILES" >> $GITHUB_ENV | |
- name: Upload code coverage report | |
if: ${{ matrix.coverage == true && github.actor != 'dependabot[bot]' }} | |
uses: codecov/codecov-action@v3 | |
with: | |
files: ${{ env.COVERAGE_FILES }} | |
flags: php,feature | |
fail_ci_if_error: true | |
#----------------------------------------------------------------------------------------------------------------------- | |
build-zip: | |
name: 'Build: ${{ matrix.build }} build ZIP' | |
# Only run if the PR was not authored by Dependabot and it is not a draft or not from a fork. | |
if: > | |
needs.pre-run.outputs.changed-file-count > 0 && | |
github.event.pull_request.draft == false && | |
github.event.pull_request.head.repo.fork == false && | |
github.event.pull_request.user.login != 'dependabot[bot]' | |
needs: pre-run | |
runs-on: ubuntu-latest | |
outputs: | |
branch-name: ${{ steps.retrieve-branch-name.outputs.branch_name }} | |
git-sha-8: ${{ steps.retrieve-git-sha-8.outputs.sha8 }} | |
strategy: | |
matrix: | |
build: ['dev', 'prod'] | |
steps: | |
- name: Check out source files | |
uses: actions/checkout@v3 | |
- name: Setup PHP | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: '7.4' | |
- name: Setup Node | |
uses: actions/[email protected] | |
with: | |
node-version-file: '.nvmrc' | |
cache: npm | |
- name: Get Composer Cache Directory | |
id: composer-cache | |
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT | |
- name: Configure Composer cache | |
uses: actions/[email protected] | |
with: | |
path: ${{ steps.composer-cache.outputs.dir }} | |
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} | |
restore-keys: | | |
${{ runner.os }}-composer- | |
- name: Install Composer dependencies | |
# Scripts are not ignored as they are needed to apply patches for the | |
# `sabberworm/php-css-parser` dependency. | |
run: composer install --prefer-dist --optimize-autoloader | |
- name: Install Node dependencies | |
run: npm ci | |
- name: Create destination directories | |
run: mkdir -p builds/${{ matrix.build }} | |
- name: Build plugin | |
run: | | |
npm run package:${{ matrix.build }} | |
mv amp.zip builds/${{ matrix.build }}/amp.zip | |
env: | |
LAST_PR_COMMIT_HASH: ${{ github.event.pull_request.head.sha }} | |
- name: Retrieve branch name | |
id: retrieve-branch-name | |
run: echo "branch_name=$(REF=${GITHUB_HEAD_REF:-$GITHUB_REF} && echo ${REF#refs/heads/} | sed 's/\//-/g')" >> $GITHUB_OUTPUT | |
- name: Retrieve git SHA-8 string | |
id: retrieve-git-sha-8 | |
run: echo "sha8=$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT | |
- name: Upload build as artifact | |
uses: actions/upload-artifact@v3 | |
with: | |
name: amp-${{ steps.retrieve-branch-name.outputs.branch_name }}-${{ steps.retrieve-git-sha-8.outputs.sha8 }}-${{ matrix.build }} | |
path: builds/${{ matrix.build }} | |
#----------------------------------------------------------------------------------------------------------------------- | |
upload-to-gcs: | |
name: Upload plugin ZIPs to Google Cloud Storage | |
runs-on: ubuntu-latest | |
needs: | |
- build-zip | |
steps: | |
- name: Download dev build | |
uses: actions/download-artifact@v3 | |
with: | |
name: amp-${{ needs.build-zip.outputs.branch-name }}-${{ needs.build-zip.outputs.git-sha-8 }}-dev | |
path: builds/dev | |
- name: Download prod build | |
uses: actions/download-artifact@v3 | |
with: | |
name: amp-${{ needs.build-zip.outputs.branch-name }}-${{ needs.build-zip.outputs.git-sha-8 }}-prod | |
path: builds/prod | |
- name: Setup Google Cloud SDK | |
uses: google-github-actions/setup-gcloud@v0 | |
with: | |
project_id: ${{ secrets.GCS_PROJECT_ID }} | |
service_account_key: ${{ secrets.GCS_APPLICATION_CREDENTIALS }} | |
- name: Upload dev build to bucket | |
run: gsutil cp -r builds/dev/amp.zip gs://ampwp_github_artifacts/${{ github.ref }}/dev/amp.zip | |
- name: Upload prod build to bucket | |
run: gsutil cp -r builds/prod/amp.zip gs://ampwp_github_artifacts/${{ github.ref }}/prod/amp.zip | |
#----------------------------------------------------------------------------------------------------------------------- | |
comment-on-pr: | |
name: Comment on PR with links to plugin ZIPs | |
# Only run this job if it's a PR. One way to check for that is if `github.head_ref` is not empty. | |
if: ${{ github.head_ref && github.head_ref != null }} | |
runs-on: ubuntu-latest | |
needs: upload-to-gcs | |
outputs: | |
comment_body: ${{ steps.get-comment-body.outputs.body }} | |
steps: | |
- name: Check if a comment was already made | |
id: find-comment | |
uses: peter-evans/find-comment@v2 | |
with: | |
issue-number: ${{ github.event.pull_request.number }} | |
comment-author: github-actions[bot] | |
body-includes: Plugin builds for | |
- name: Get comment body | |
id: get-comment-body | |
# Setting a multi-line output requires escaping line-feeds. See <https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings>. | |
run: | | |
body="Plugin builds for ${{ github.event.pull_request.head.sha }} are ready :bellhop_bell:! | |
- Download [development build](https://storage.googleapis.com/ampwp_github_artifacts/${{ github.ref }}/dev/amp.zip?${{ github.sha }}) | |
- Download [production build](https://storage.googleapis.com/ampwp_github_artifacts/${{ github.ref }}/prod/amp.zip?${{ github.sha }})" | |
delimiter="${body//$'\n'/'%0A'}" | |
echo "body<<${delimiter}" >> $GITHUB_OUTPUT | |
echo "$body" >> $GITHUB_OUTPUT | |
echo "${delimiter}" >> $GITHUB_OUTPUT | |
- name: Create comment on PR with links to plugin builds | |
if: ${{ steps.find-comment.outputs.comment-id == '' }} | |
uses: peter-evans/create-or-update-comment@v3 | |
with: | |
issue-number: ${{ github.event.pull_request.number }} | |
body: ${{ steps.get-comment-body.outputs.body }} | |
- name: Update comment on PR with links to plugin builds | |
if: ${{ steps.find-comment.outputs.comment-id != '' }} | |
uses: peter-evans/create-or-update-comment@v3 | |
with: | |
comment-id: ${{ steps.find-comment.outputs.comment-id }} | |
edit-mode: replace | |
body: ${{ steps.get-comment-body.outputs.body }} |