Skip to content

Mink Tests

Mink Tests #2307

Workflow file for this run

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 }}