Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions .github/actions/wordpress-host-test/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
name: WordPress Host Test
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible follow-up: Since the pipeline in .github/workflows/tests.yml also appears to be intended as a template to be adopted by hosting providers in their own pipelines, that might possibly be dropped when/if this PR gets merged.

description: >
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: >
author: WordPress.org
description: >

Run the WordPress Host Test on a remote system reachable via SSH
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Run the WordPress Host Test on a remote system reachable via SSH
Runs the WordPress PHPUnit test suite on a remote system reachable via SSH and reports the results.


inputs:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we list all required inputs first?

report-api-key:
description: >
API key for reporting test results back to wordpress.org; if omitted,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While wordpress.org is the default, reports can be submitted to any site running the https://github.com/WordPress/phpunit-test-reporter plugin.

test result reporting will be skipped.
required: false
remote-test-dir:
description: >
Remote directory in which tests will be run
required: true
database-host:
description: >
Database host for running the unit tests
required: true
database-user:
description: >
Database user for running the unit tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we end all descriptions with periods, please?

required: true
database-password:
description: >
Database password for running the unit tests
required: true
database-name:
description: >
Database name for running the unit tests
required: true
ssh-connect:
description: >
SSH connection string (in the format username@host) for connecting to the
hosting environment under test.
required: true
ssh-private-key:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ssh-private-key:
ssh-private-key-base64:

All other inputs match the corresponding environment variable name consumed by the runner itself. The exceptions to this are the WPT_DB_* variables that are expanded to spell out database here, which I think makes sense.

description: >
A base64-encoded SSH private key.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description for each input passing sensitive values should explicitly note that the values should be configured as GitHub Actions repository or organization secrets to ensure that they are properly obfuscated in the logs.

required: true
test-filter:
description: A regular expression to filter tests that should be run.
default: '.*'
runs:
using: "composite"
steps:
- name: Checkout repository
uses: actions/checkout@v4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
uses: actions/checkout@v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

Third-party actions should always be pinned to a specific SHA value, which is currently the only immutable release supported (🤞 GH public roadmap).

with:
repository: WordPress/phpunit-test-runner
path: runner
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
path: runner
persist-credentials: false
path: runner

Unless credentials are explicitly required later in the job, credential persistence should always be disabled.


- name: Set up PHP
uses: shivammathur/setup-php@cf4cade2721270509d5b1c766ab3549210a39a2a # v2.33.0
with:
php-version: '8.4'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be configurable through an optional input. This would ensure that the version of PHP on configured on the runner matches the one being tested so that Composer will install the correct dependencies.

I think that 8.4 is a good default. We should note in the input description that this will default to the latest version of PHP officially supported by WordPress in wordpress-develop@trunk.

coverage: none

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, the version of Node.js used here will always match the version being used in https://github.com/wordpress/wordpress-develop at the commit being tested.

I believe that this should checkout only the .nvmrc file using actions/checkout

Suggested change
name: Checkout .nvmrc file from wordpress-develop
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
repository: 'WordPress/wordpress-develop'
persist-credentials: false
sparse-checkout: '.nvmrc'
sparse-checkout-cone-mode: false

This would allow the actions/setup-node call below to use something like:

              node-version-file: '.nvmrc'

- name: Install NodeJS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason not to pass cache: 'npm' here?

uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 20

- name: Prepare SSH private key
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if there was a reason why you decided to configure the key here instead of relying on the prepare.php script to take care of it? I don't think this is an issue, but just wanted to know if there was a specific reason.

shell: bash
if: ${{ inputs.ssh-private-key }}
run: |
mkdir -p ~/.ssh
echo '${{ inputs.ssh-private-key }}' | base64 -d > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa

# This is added as a separate step to catch SSH connection errors (bad
# credentials, or similar) early, since prepare.php takes a while before
# even attempting an SSH connection.
- name: Test SSH connectivity
shell: bash
run: |
ssh -o StrictHostKeyChecking=no ${{ inputs.ssh-connect }} whoami

- name: Prepare environment
env:
WPT_PREPARE_DIR: /tmp/wp-tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the ${{ runner.temp }} context work here? It may be better to ensure that the directory is reliably accessible/writable.

WPT_TEST_DIR: ${{ inputs.remote-test-dir }}
WPT_DB_NAME: ${{ inputs.database-name }}
WPT_DB_USER: ${{ inputs.database-user }}
WPT_DB_PASSWORD: ${{ inputs.database-password }}
WPT_DB_HOST: ${{ inputs.database-host }}
WPT_SSH_CONNECT: ${{ inputs.ssh-connect }}
run: php prepare.php
shell: bash
working-directory: ./runner

- name: Run unit tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- name: Run unit tests
- name: Run PHPUnit tests

run: php test.php
continue-on-error: true
shell: bash
working-directory: ./runner
env:
WPT_PREPARE_DIR: /tmp/wp-tests
WPT_TEST_DIR: ${{ inputs.remote-test-dir }}
WPT_DB_NAME: ${{ inputs.database-name }}
WPT_DB_USER: ${{ inputs.database-user }}
WPT_DB_PASSWORD: ${{ inputs.database-password }}
WPT_DB_HOST: ${{ inputs.database-host }}
WPT_SSH_CONNECT: ${{ inputs.ssh-connect }}
WPT_PHPUNIT_CMD: >
cd ${{ inputs.remote-test-dir }} &&
./vendor/phpunit/phpunit/phpunit
--dont-report-useless-tests
-c tests/phpunit/multisite.xml
--filter '${{ inputs.test-filter }}'

- name: Report the results
run: php report.php
continue-on-error: true
if: ${{ inputs.report-api-key }}
shell: bash
working-directory: ./runner
env:
WPT_REPORT_API_KEY: ${{ inputs.report-api-key }}
WPT_PREPARE_DIR: /tmp/wp-tests
WPT_TEST_DIR: ${{ inputs.remote-test-dir }}
WPT_DB_NAME: ${{ inputs.database-name }}
WPT_DB_USER: ${{ inputs.database-user }}
WPT_DB_PASSWORD: ${{ inputs.database-password }}
WPT_DB_HOST: ${{ inputs.database-host }}
WPT_SSH_CONNECT: ${{ inputs.ssh-connect }}

- name: Cleanup
run: php cleanup.php
shell: bash
working-directory: ./runner
env:
WPT_PREPARE_DIR: /tmp/wp-tests
WPT_TEST_DIR: ${{ inputs.remote-test-dir }}
WPT_DB_NAME: ${{ inputs.database-name }}
WPT_DB_USER: ${{ inputs.database-user }}
WPT_DB_PASSWORD: ${{ inputs.database-password }}
WPT_DB_HOST: ${{ inputs.database-host }}
WPT_SSH_CONNECT: ${{ inputs.ssh-connect }}
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,55 @@ journalctl -u wordpressphpunittestrunner.timer
journalctl -n 120 -u wordpressphpunittestrunner.service
```

### Running using GitHub actions

You can also use the GitHub action in `.github/actions/wordpress-host-test` to automatically run this test suite on your host. Since this action will usually run on GitHub's infrastructure, the action presumes that the actual hosting environment will be reachable via SSH.

To run the GitHub action using a schedule, create a new GitHub repository with the following action:

```yaml
name: Run WordPress Unit Tests
on:
schedule:
- cron: 0 0 * * *
workflow_dispatch:
jobs:
run-tests:
name: Run Test Suite
runs-on: ubuntu-latest
steps:
- uses: WordPress/phpunit-test-runner/.github/actions/wordpress-host-test@master
with:
report-api-key: '${{ secrets.REPORT_API_KEY }}'
ssh-connect: '${{ secrets.SSH_CONNECT }}'
ssh-private-key: '${{ secrets.SSH_PRIVATE_KEY }}'
remote-test-dir: /files/wordpress-host-test
database-host: ${{ secrets.DATABASE_HOST }}
database-user: ${{ secrets.DATABASE_USER }}
database-name: ${{ secrets.DATABASE_NAME }}
database-password: ${{ secrets.DATABASE_PASSWORD }}
```

The action also makes it easy to use matrix builds to run the same test suite across a whole matrix of different environments:

```yaml
name: Run WordPress Unit Tests
on: # [...]
jobs:
run-tests:
strategy:
matrix:
ssh-target:
- user@php-8.4-host.example
- user@php-8.3-host.example
- user@php-8.2-host.example
steps:
- uses: WordPress/phpunit-test-runner/.github/actions/wordpress-host-test@master
with:
ssh-connect: '${{ matrix.ssh-target }}'
# ...
```

## Contributing

If you have questions about the process or run into test failures along the way, please [open an issue in the project repository](https://github.com/WordPress/phpunit-test-runner/issues) and we’ll help diagnose/get the documentation updated. Alternatively, you can also pop into the `#hosting` channel on [WordPress.org Slack](https://make.wordpress.org/chat/) for help.
Expand Down