A Composer plugin that scaffolds TEN7's GitHub Actions and workflow files into Drupal projects.
This is a transitional project, allowing TEN7 to build testing infrastructure for existing lullabot/drainpipe projects and preparing for the switch to Pantheon-based deployments on GitHub.
This will install lullabot/drainpipe as a dependency, but Drainpipe
actions are only installed on sites that use Drainpipe. Because this depends
on a certain version of Drainpipe, it is best to run composer remove --dev lullabot/drainpipe-dev -W and composer remove lullabot/drainpipe so that
the version constraint equals what is installed by this repo.
🗒️The intent is that this repo should be updated regularly to the latest version of Drainpipe. All Drainpipe features are available to the site if that is desired, however, most Pantheon-related functionality is incorporated into the equivalent workflows on this project.
This tool is predicated on the assumption that you want to run code tests with your GitHub deployments to Pantheon.
Most important is a Playwright test setup
in a directory called test/playwright.
If you have a BrowserStack account, you can install the
browserstack-node-sdk
which will install a browserstack.yml file in the test/playwright directory.
For the CodeTests, it is also important to have a phpunit configuration on
your site. In most Drupal setups, this will be at least partly set up on
installation. If there are no tests, Unit and ExistingSite steps will be
skipped.
As is mentioned below, This is not necessary as the tests can be run locally;
however, if your site has php-based tests you want run, these can be a
useful check on every run.
This repo is not listed at packagist so you need to add the following to your "repositories[]" in composer.json.
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/ten7/github-code-testing"
}
]
}Then you can run the following, though nothing will change in your codebase until you define "GitHub" in "extras" explained below.
Note: It is best to use the latest version when requiring this. Check the tags at https://github.com/ten7/github-code-testing.
composer require "ten7/github-code-testing^1.0.7-beta"Add a code_testing key to the extra section of your project's
composer.json. Under github, declare which workflows to scaffold using a
context key and a list of workflow names.
SSH_PRIVATE_KEYis needed for all actions.SSH_KNOWN_HOSTSis also needed for all actions.TERMINUS_MACHINE_TOKENis required for all actionsPANTHEON_REVIEW_RUN_INSTALLERis required for Drainpipe actionsPANTHEON_SITE_NAMEis the required by Drainpipe actions. It is the UUID for the site. It's annoying to have this in both variables and secrets. It really should just be a variable unless at some point Pantheon allows renaming a site and the UUID serves it's real purpose of being the constant identifier.BROWSERSTACK_USERNAMEis the short key indicating the username (should be the company-wide/repo-holder's username at browserstack.com)BROWSERSTACK_ACCESS_KEYis the hash at the same account at browserstack.com
BROWSERSTACK_PRIMARY_BRANCHis the branch (edge, main, master) that browserstack tests should be run on.BROWSERSTACK_TESTS_ENABLEDis a boolean that indicates if browserstack tests should be run at all.TESTING_NEEDS_SEARCH_INDEXINGis a boolean that determines if tests run on the site require a build to run the search_api index. This should be set to eithertrueorfalse(which is the same as not having it)PANTHEON_SITE_NAMEis the human-friendly site name that is used in multi-dev URLs: https:/dev-[site-name].pantheonsite.io
On PRs some labels can be used for triggering actions these include
skip-wipewhich prevents a build from wiping the files and db and starting from scratch on every pushbuild multidevis required to build a Pantheon review app for the PR at all. It only controls whether the multidev environment gets built - whether tests actually run against it once built is a separate check (seebrowserstackbelow).test renovateis required for testRenovate to run at all. The workflow's job is gated on this label, so without it nothing runs - it's not just a time-saving option. See below.browserstackBy default browserstack tests are never run on PRs even ifBROWSERSTACK_TESTS_ENABLED=true. Add this label if a PR should also run browserstack tests. This is useful if a PR includes significant theme changes. Less "expensive" standard CodeTests or Playwright tests. So use this with care.⚠️ This label currently gates Playwright tests on PR review apps too, not just BrowserStack. Both workflows call the samedecide-test-runaction, which defaults its PR-label check tobrowserstack. Without the label, neither suite runs against the review app. This gate does not apply to the edge/main push path, where both suites always run.
This automatically loads all the lullabot/drainpipe actions that are needed for the specific tasks. There is no need to call Drainpipe separately unless you have specific additional requirements for those. Just be sure not to overlap functionality.
{
"extras": [
{
"code_testing": {
"github": {
"drainpipe": [
"PlaywrightTests",
"BrowserStackTests",
"PantheonBuildEdge",
"PantheonBuildMain",
"PantheonReviewApps",
"CodeTests",
"LockDiff"
]
}
}
}
]
}Playwright and BrowserStack tests depend on at least one of the "Pantheon*" workflows completing, and run against a Pantheon environment. There are two independent paths:
- Push to edge/main: the matching
Pantheon Buildworkflow deploys, then tests run automatically against that environment. A push tomaintests against thedevmultidev, not amainone - that's Pantheon's own environment naming, not something this plugin adds. - Pull requests:
Pantheon Review Appsonly builds a multidev if the PR has thebuild multidevlabel, and tests then only run against it if the PR also has thebrowserstacklabel (see PR Labels above).
name: string ("Pantheon
Build " plus the configured primary branch). If you rename
drainpipePantheonBuildEdge.yml or drainpipePantheonBuildMain.yml, update
decide-test-run's build-workflow-prefix input to match, or tests will
silently stop running after every deploy.
These are set up to use two different scripts in your
tests/playwright/package.json file described below. PlaywrightTests is
expecting a script called test:ci-playwright and the BrowserStackTests
expect a script called test:browserstack (see below).
CodeTests and LockDiff can be run independently of a build.
CodeTests is not necessary as all of what it does can be run locally. test:ci-ddev (see below). To run this on a PR you must add the
label playwright-tests.
Writing php existing-site and unit tests are beyond the scope of this README but here are some expectations you will need to set up. You can learn more at Running PHPUnit Tests
The CodeTests workflow expects the following tasks:
- test:existing-site
- test:unit
The assumption is that all your custom modules are annotated with at least one common group. Replace [your_group] in the code below with whatever that group name is.
tasks:
test:existing-site:
desc: "Runs the test suite in development mode"
cmds:
- echo "🔬 Running existing-site tests in development mode..."
- exec ./vendor/bin/phpunit --testsuite existing-site --group [your_group]
test:unit:
desc: "Runs the unit tests in development mode"
cmds:
- echo "🔬 Running unit tests in development mode..."
- exec ./vendor/bin/phpunit --testsuite unit --group [your_group]You also need to run the following (or, at a bare minimum, drupal/core-dev).
composer require --dev drupal/core-dev --with-all-dependencies
composer require --dev weitzman/drupal-test-traits --with-all-dependencies
composer require --dev weitzman/logintrait --with-all-dependenciesThis is installed by Drainpipe, but may not actually get installed. If you
want to use this, and you have instructions in a renovate.json and have it
configured on GitHub, you need to add the following to extra.code_testing.
testRenovate runs on pull requests (opened, synchronized, reopened, or
labeled), and its job only runs if the PR also carries the test renovate
label - without it, the job is skipped entirely.
{
"extras": [
{
"code_testing": {
"github": {
"test": [
"Renovate"
]
}
}
}
]
}For sites that use a deployment solution such as pantheon's GitHub builder, the options are simpler.
{
"extras":[
{
"code_testing": {
"github": {
"deployment": [
"PlaywrightTests",
"BrowserStackTests",
"CodeTests",
"LockDiff"
]
}
}
}]}Each entry maps to a workflow file using the pattern {context}{Name}.yml. The
example above would scaffold:
drainpipePlaywrightTests.ymldeploymentBrowserStackTests.ymldeploymentCodeTests.ymltestRenovate.yml
It's entirely possible to skip the "extras:code_testing" section and just copy
the desired files from ./vendor/ten7/scaffold/.github/workflows, but this
should not be necessary. If there need to be new changes, they should be
made here with broadly abstracted steps and making use of updates users can
make in their repos (secrets/variables/labels) or with specifically required
scripts test/playwright/package.json
| Context | Use when |
|---|---|
drainpipe |
The project uses Drainpipe for its build and deploy pipeline |
deployment |
The project uses a non-Drainpipe deployment pipeline |
test |
Standalone test utilities (e.g., Renovate) |
See the directory scaffold/.github/workflows.
All actions under .github/actions/code-testing/ are scaffolded
unconditionally. They have no effect unless referenced by a workflow. Each
action has a description defining what it does.
This plugin also installs certain lullabot/drainpipe actions as needed.
Workflows not declared in code_testing are never written to
.github/workflows/, so they never appear in the GitHub Actions tab. This keeps
Pantheon-specific or Drainpipe-specific workflows out of projects that don't use
them.
This project expects tests to be in a directory ./test/playwright.
To install playwright, create a directory in the repo root:
mkdir -p test/playwrightSwitch to the new directory and run:
npm init playwright@latestDon't add the GitHub action if requested. This repo handles that work. For best results, answer all other questions with the defaults.
Specifics on how to write your tests and what to test for is beyond the scope for this repo. Each site may have different requirements and levels of thoroughness.
In the package.json file you will need to create scripts that you want to run as follows:
- test:ci-ddev
- test:ci-pantheon
- test:browserstack
These tests should define what should be run by npm. An example might be:
{
"scripts": {
"test:ci-ddev": "playwright test --project=func-chromium",
"test:ci-pantheon": "playwright test --grep='@smoke' --project=func-chromium",
"test:browserstack": "BROWSERSTACK_BUILD=true browserstack-node-sdk playwright test --grep='@browserstack'"
}
}The test:browserstack should be configured differently based on the rules for
developing with BrowserStack that are beyond the scope of this repo.
These are some simple guidelines to help you with making the best use of this tool.
- If you have a paid Browserstack Automate account, you probably don't need to
include the
PlaywrightTestsworkflow. - It is unlikely to be useful to run both
PlaywrightTestsand includeplaywright-testsas a label in your repo to run them onCodeTestsas well. - Visual regression tests are notoriously flaky. It may be useful to include in each test a warming function to load the page before actually testing it.
- Visual regression tests can also be very time-consuming as both the GitHub runner VMs and the Pantheon Multidevs are much slower than a live site or your local DDEV environment.