Mink Tests #2307
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: Mink Tests | |
on: | |
pull_request: | |
branches: | |
- main | |
workflow_dispatch: | |
inputs: | |
matrix: | |
description: matrix in json format | |
required: true | |
default: '{"include":[{"php-versions":"8.1","drupal":"~10.1.1","civicrm":"dev-master"}]}' | |
prurl: | |
description: PR Url | |
required: false | |
repourl: | |
description: Repo Url | |
required: false | |
repobranch: | |
description: Target Branch | |
required: false | |
notifyemail: | |
description: Email to notify | |
required: false | |
contactid: | |
description: Civi contact id | |
required: false | |
coreprurl: | |
description: Core PR Url | |
required: false | |
cividrupal8prurl: | |
description: civi-drupal-8 PR Url | |
required: false | |
jobs: | |
phpunit: | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJson(github.event.inputs.matrix) }} | |
name: D${{ matrix.drupal }} | Civi ${{ matrix.civicrm }} | ${{ github.event.inputs.repourl }} | |
services: | |
mysql: | |
image: mysql:5.7 | |
env: | |
MYSQL_ALLOW_EMPTY_PASSWORD: yes | |
MYSQL_DATABASE: db | |
ports: | |
- 3306 | |
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: shivammathur/setup-php@v2 | |
with: | |
php-version: ${{ matrix.php-versions }} | |
extensions: dom, curl, libxml, mbstring, zip, pdo, mysql, pdo_mysql, bcmath, soap, intl, gd, exif, iconv, :imagick | |
coverage: none | |
tools: composer:v2 | |
- name: starttimer | |
run: | | |
cd $GITHUB_WORKSPACE | |
date +%s > carrottimerfile | |
echo "EXITEARLY=n" >> $GITHUB_ENV | |
- name: Get composer cache directory | |
id: composercache | |
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT | |
- uses: actions/cache@v4 | |
with: | |
path: ${{ steps.composercache.outputs.dir }} | |
key: ${{ runner.os }}-${{ matrix.drupal }}-composer-${{ hashFiles('**/composer.json') }} | |
restore-keys: ${{ runner.os }}-composer- | |
- name: Setup problem matchers for PHPUnit | |
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" | |
- name: Download Drupal | |
run: | | |
COMPOSER_MEMORY_LIMIT=-1 composer create-project drupal/recommended-project:${{ matrix.drupal }} ~/drupal --no-interaction --no-install | |
cd ~/drupal | |
composer config extra.enable-patching true | |
composer config extra.compile-mode all | |
composer config minimum-stability dev | |
composer config prefer-stable true | |
composer config preferred-install auto | |
composer config --no-interaction --no-plugins allow-plugins.composer/installers true | |
composer config --no-interaction --no-plugins allow-plugins.drupal/core-composer-scaffold true | |
composer config --no-interaction --no-plugins allow-plugins.drupal/core-project-message true | |
composer config --no-interaction --no-plugins allow-plugins.civicrm/composer-compile-plugin true | |
composer config --no-interaction --no-plugins allow-plugins.civicrm/composer-downloads-plugin true | |
composer config --no-interaction --no-plugins allow-plugins.civicrm/civicrm-asset-plugin true | |
composer config --no-interaction --no-plugins allow-plugins.cweagans/composer-patches true | |
composer config --no-interaction --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true | |
composer install --no-interaction | |
# composer config repositories.0 composer https://packages.drupal.org/8 | |
COMPOSER_MEMORY_LIMIT=-1 composer require drupal/core-dev-pinned:${{ matrix.drupal }} | |
- name: Download CiviCRM ${{ matrix.civicrm }} | |
run: | | |
cd ~/drupal | |
COMPOSER_MEMORY_LIMIT=-1 composer require civicrm/civicrm-asset-plugin:'~1.1' civicrm/civicrm-{core,packages,drupal-8}:${{ matrix.civicrm }} | |
- name: Download mink-civicrm-helpers | |
run: | | |
cd ~/drupal | |
COMPOSER_MEMORY_LIMIT=-1 composer require semperit/minkcivicrmhelpers | |
- uses: nanasess/setup-chromedriver@master | |
- name: Run chromedriver | |
run: chromedriver & | |
- name: Run php built-in server | |
run: php -S 127.0.0.1:8080 -t ~/drupal/web & | |
- name: Get some code to test | |
if: ${{ github.event.inputs.repourl != 0 }} | |
run: | | |
mkdir -p ~/drupal/web/sites/default/files/civicrm/ext | |
cd ~/drupal/web/sites/default/files/civicrm/ext | |
if [ "${{ github.event.inputs.repobranch }}" != "" ]; then | |
git clone -b ${{ github.event.inputs.repobranch }} ${{ github.event.inputs.repourl }} thingtotest | |
else | |
git clone ${{ github.event.inputs.repourl }} thingtotest | |
fi | |
- name: Set identity | |
# Needed for `git am` | |
run: | | |
git config --global user.email "civicarrot@gmail.com" | |
git config --global user.name "CiviCARROT" | |
- name: Check if PR has closed early | |
if: ${{ github.event.inputs.prurl != 0 }} | |
run: | | |
# Check if the PR is still open since the process started, e.g. a rebase just before merge. | |
prurl=${{ github.event.inputs.prurl }} | |
temp1=${prurl%/-/merge_requests/*} | |
projectname=${temp1#https://*/} | |
# close enough? | |
urlencoded=${projectname//\//%2F} | |
domain=${temp1%/$projectname} | |
mrid=${prurl##*/} | |
mrstate=`curl -H "Authorization: Bearer ${{secrets.LABCO_API_KEY}}" ${domain}/api/v4/projects/${urlencoded}/merge_requests/${mrid} | jq -r .state` | |
if [ "$mrstate" != "opened" ]; then | |
echo "EXITEARLY=y" >> $GITHUB_ENV | |
fi | |
- name: Apply PR | |
if: ${{ (github.event.inputs.prurl != 0) && (env.EXITEARLY != 'y') }} | |
run: | | |
cd ~/drupal/web/sites/default/files/civicrm/ext/thingtotest | |
curl -L -o thingtopatch.patch ${{ github.event.inputs.prurl }}.patch | |
git am thingtopatch.patch | |
- name: Apply Core PR | |
if: ${{ (github.event.inputs.coreprurl != 0) && (env.EXITEARLY != 'y') }} | |
run: | | |
cd ~/drupal/vendor/civicrm/civicrm-core | |
curl -L -o thingtopatch.diff ${{ github.event.inputs.coreprurl }}.diff | |
git apply thingtopatch.diff | |
- name: Apply Civi-Drupal-8 PR | |
if: ${{ (github.event.inputs.cividrupal8prurl != 0) && (env.EXITEARLY != 'y') }} | |
run: | | |
cd ~/drupal/web/modules/contrib/civicrm | |
curl -L -o thingtopatch.diff ${{ github.event.inputs.cividrupal8prurl }}.diff | |
git apply thingtopatch.diff | |
- name: Download extension dependencies | |
if: ${{ (github.event.inputs.repourl != 0) && (env.EXITEARLY != 'y') }} | |
run: | | |
cd ~/drupal/web/sites/default/files/civicrm/ext | |
DEPS=`php -r '$xml = simplexml_load_file("thingtotest/info.xml"); $deps = array(); foreach ($xml->requires as $req) { foreach ($req->ext as $ext) { $deps[] = $ext; } } echo implode(" ", $deps);'` | |
if [ -n "$DEPS" ]; then | |
for e in $DEPS; do | |
# Might need to be tolerant of failure here since it's possible to have dependencies that | |
# aren't in universe and that could still get installed by the tests themselves. But this | |
# whole system is really only designed for publicly reachable repos at the moment. Also | |
# if you declare a dependency on a core extension, there's nothing to "download". | |
# By adding the `||` the exit code is the exit code of `echo`, which will be success. | |
$GITHUB_WORKSPACE/civicrm-cv/bin/cv api3 Extension.download install=0 key=$e || echo 'ignoring failure' | |
done | |
fi | |
- name: Run PHPUnit | |
if: ${{ env.EXITEARLY != 'y' }} | |
run: | | |
mkdir $BROWSERTEST_OUTPUT_DIRECTORY | |
cd ~/drupal/web/sites/default/files/civicrm/ext/thingtotest | |
# The xml config file should have a bootstrap attribute pointing to a proper bootstrap file, which needs to be similar to drupal's test bootstrap file. | |
# The full path is needed for the config file to make this work in drupal 10.2. It shouldn't be needed for the last argument, but seems to be needed in drupal 9.5. | |
~/drupal/vendor/bin/phpunit -c ~/drupal/web/sites/default/files/civicrm/ext/thingtotest/phpunit.mink.xml.dist ~/drupal/web/sites/default/files/civicrm/ext/thingtotest/tests/phpunit/Mink | |
env: | |
SYMFONY_DEPRECATIONS_HELPER: 999999 | |
DEV_EXTENSION_DIR: /home/runner/drupal/web/sites/default/files/civicrm/ext | |
SIMPLETEST_DB: mysql://root:@127.0.0.1:${{ job.services.mysql.ports[3306] }}/db | |
SIMPLETEST_BASE_URL: http://127.0.0.1:8080 | |
MINK_DRIVER_ARGS_WEBDRIVER: '["chrome", {"browserName":"chrome","chromeOptions":{"args":["--disable-gpu", "--no-sandbox", "--headless"]}}, "http://127.0.0.1:9515"]' | |
BROWSERTEST_OUTPUT_DIRECTORY: '${{ runner.temp }}/browser_output' | |
- name: Helper to make unique name for upload | |
run: | | |
# doing this on multiple lines to avoid quote-hell | |
cd ${{ runner.temp }} | |
echo '${{ matrix.drupal }}_${{ matrix.civicrm }}_${{ matrix.php-versions }}' > upload_helper.txt | |
sed -i -e 's/[^0-9a-zA-Z_.\-]//g' upload_helper.txt | |
echo "UPLOADNAME=$(cat upload_helper.txt)" >> $GITHUB_ENV | |
- uses: actions/upload-artifact@v4 | |
if: ${{ (failure() || success()) && (env.EXITEARLY != 'y') }} | |
with: | |
name: screenshots.${{ env.UPLOADNAME }} | |
# See https://www.drupal.org/project/drupal/issues/2992069#comment-12725521. Basically BROWSERTEST_OUTPUT_DIRECTORY | |
# is poorly named/documented. It only controls the location of a temp file that lists uris for the generated files. | |
# The actual location is ALWAYS `DRUPAL_ROOT . '/sites/simpletest/browser_output'`. See https://git.drupalcode.org/project/drupal/-/blob/af95c8490/core/tests/Drupal/Tests/BrowserHtmlDebugTrait.php#L145 | |
path: '/home/runner/drupal/web/sites/simpletest/browser_output' | |
- name: send notification email | |
if: ${{ failure() && (github.event.inputs.notifyemail != 0) && (github.event.inputs.notifyemail != '[REDACTED]') && (env.EXITEARLY != 'y') }} | |
uses: dawidd6/action-send-mail@v3 | |
with: | |
server_address: smtp.gmail.com | |
server_port: 465 | |
secure: true | |
username: ${{secrets.MAIL_USERNAME}} | |
# This can be a temporary app password, not the real password | |
password: ${{secrets.MAIL_PASSWORD}} | |
subject: CiviCARROT Mink tests ${{ github.event.inputs.repourl }} | |
body: Visit https://github.com/semperit/CiviCARROT/actions/runs/${{ github.run_id }} to view logs and artifacts. | |
to: ${{ github.event.inputs.notifyemail }} | |
from: civicarrot@gmail.com | |
- name: record stats | |
if: ${{ (success() || failure()) && (github.event.inputs.contactid != 0) }} | |
run: | | |
cd $GITHUB_WORKSPACE | |
STARTTIME=`cat carrottimerfile` | |
TIMEUSED=$(( `date +%s` - $STARTTIME )) | |
SPACEUSED=`du -s --block-size=1 /home/runner/drupal/web/sites/simpletest/browser_output | cut -f1` | |
echo "{\"type\":\"mink\",\"id\":${{ github.event.inputs.contactid }},\"bytes\":\"$SPACEUSED\",\"seconds\":$TIMEUSED,\"repo\":\"${{ github.event.inputs.repourl }}\",\"pr\":\"${{ github.event.inputs.prurl }}\",\"run_id\":\"${{ github.run_id }}\"}" | |
curl --user ${{secrets.REST_USER}}:${{secrets.REST_PASS}} -X POST -H "Content-type: application/json" -d "{\"type\":\"mink\",\"id\":${{ github.event.inputs.contactid }},\"bytes\":\"$SPACEUSED\",\"seconds\":$TIMEUSED,\"repo\":\"${{ github.event.inputs.repourl }}\",\"pr\":\"${{ github.event.inputs.prurl }}\",\"run_id\":\"${{ github.run_id }}\"}" https://civicrm.io/githubaction/${{ github.event.inputs.contactid }} | |
# It seems like there should be shorthand for this instead of 8 lines | |
- name: checkstatus1 | |
if: ${{ success() && (github.event.inputs.prurl != 0) }} | |
run: | | |
echo "RUNSTATUS=%E2%9C%94%EF%B8%8F+PASS" >> $GITHUB_ENV | |
- name: checkstatus2 | |
if: ${{ failure() && (github.event.inputs.prurl != 0) }} | |
run: | | |
echo "RUNSTATUS=%E2%9D%8C+FAIL" >> $GITHUB_ENV | |
- name: create comment on PR | |
if: ${{ (success() || failure()) && (github.event.inputs.prurl != 0) && (env.EXITEARLY != 'y') }} | |
run: | | |
prurl=${{ github.event.inputs.prurl }} | |
temp1=${prurl%/-/merge_requests/*} | |
projectname=${temp1#https://*/} | |
# close enough? | |
urlencoded=${projectname//\//%2F} | |
domain=${temp1%/$projectname} | |
mrid=${prurl##*/} | |
echo ${domain}/api/v4/projects/${urlencoded}/merge_requests/${mrid}/notes | |
curl -H "Authorization: Bearer ${{secrets.LABCO_API_KEY}}" -X POST ${domain}/api/v4/projects/${urlencoded}/merge_requests/${mrid}/notes?body=${{ env.RUNSTATUS }}:+Mink+Tests:+https:%2F%2Fgithub.com%2Fsemperit%2FCiviCARROT%2Factions%2Fruns%2F${{ github.run_id }} | |