Unit Tests #1764
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: Unit 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: Notification email | |
required: false | |
contactid: | |
description: Civi contact id | |
required: false | |
coreprurl: | |
description: Core 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 | |
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 cv | |
run: | | |
cd $GITHUB_WORKSPACE | |
git clone https://github.com/civicrm/cv.git civicrm-cv | |
cd civicrm-cv | |
# downloads-plugin is locked at 2.1 but that doesn't work with composer v2 | |
rm composer.lock | |
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_MEMORY_LIMIT=-1 composer install | |
- 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 --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 | |
- 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 }} | |
CANUSE95=`php -r 'echo version_compare("${{ matrix.civicrm }}", "5.65");'` | |
if [ "${{ matrix.civicrm }}" != "dev-master" -a "$CANUSE95" != "1" ]; then | |
COMPOSER_MEMORY_LIMIT=-1 composer require phpunit/phpunit:'^8.5' drush/drush | |
else | |
COMPOSER_MEMORY_LIMIT=-1 composer require phpunit/phpunit:'^9.5' drush/drush | |
fi | |
- name: Install Drupal | |
run: | | |
cd ~/drupal | |
./vendor/drush/drush/drush -y -l http://civi.localhost site-install standard --db-url='mysql://root:@127.0.0.1:${{ job.services.mysql.ports[3306] }}/db' --site-name=TestCivi --account-pass=admin | |
chmod +w web/sites/default | |
- name: Install CiviCRM | |
run: | | |
cd ~/drupal | |
$GITHUB_WORKSPACE/civicrm-cv/bin/cv core:install --cms-base-url=http://civi.localhost -m loadGenerated=1 | |
cd web/sites/default | |
sed -i -e 's#if (!defined('"'"'CIVICRM_SMARTY3_AUTOLOAD_PATH'"'"')) {#if (FALSE) {#' civicrm.settings.php | |
- 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: Download extension dependencies | |
if: ${{ (github.event.inputs.repourl != 0) && (env.EXITEARLY != 'y') }} | |
run: | | |
cd ~/drupal/web/sites/default/files/civicrm/ext | |
# Allow "unapproved" extensions | |
$GITHUB_WORKSPACE/civicrm-cv/bin/cv ev '\Civi::settings()->set("ext_repo_url", "https://civicrm.org/extdir/ver={ver}|cms={uf}|ready=");' | |
$GITHUB_WORKSPACE/civicrm-cv/bin/cv ev '\Civi::settings()->set("http_timeout", 60);' | |
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: | | |
export PATH=$PATH:$GITHUB_WORKSPACE/civicrm-cv/bin | |
cd ~/drupal | |
cv vars:fill | |
sed -i -e 's#dbUser:dbPass@dbHost/dbName#root:@127.0.0.1:${{ job.services.mysql.ports[3306] }}/db#' ~/.cv.json | |
export CIVICRM_UF=UnitTests | |
# export CIVICRM_SETTINGS=~/drupal/web/sites/default/civicrm.settings.php | |
cd ~/drupal/web/sites/default/files/civicrm/ext/thingtotest | |
# TODO: We could do something like glob and iterate through any folders that are not Mink? But these are the only ones that typically autoload anyway. | |
# This will use either phpunit.xml.dist or phpunit.xml depending on what they have, and hopefully that file points to a good bootstrap file | |
if [ -d tests/phpunit/CRM ]; then ~/drupal/vendor/bin/phpunit tests/phpunit/CRM; fi | |
if [ -d tests/phpunit/Civi ]; then ~/drupal/vendor/bin/phpunit tests/phpunit/Civi; fi | |
if [ -d tests/phpunit/api ]; then ~/drupal/vendor/bin/phpunit tests/phpunit/api; fi | |
env: | |
COMPOSER_MEMORY_LIMIT: -1 | |
- 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 Unit 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 )) | |
# TODO: SPACEUSED=`cat carrotspacefile` | |
SPACEUSED=00 | |
echo "{\"type\":\"plain\",\"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\":\"plain\",\"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 }}:+Unit+Tests:+https:%2F%2Fgithub.com%2Fsemperit%2FCiviCARROT%2Factions%2Fruns%2F${{ github.run_id }} | |