This week I wanted to add PHPCS Code Sniff to the Buddy.Works deploy Pipeline. I did not want the deploy to fail if any sniffs were found, I simply wanted to have the team emailed with any found sniffs. (for now)
Unfortunately the built in buddy.deploy PHPCS action does not have the ability to email out, and the Email Action cannot attach files. (Buddy support told me they have this feature in their backlog)
I had to come up with my own solution, so here it is....
At first I got happy. There seemed a way to pass the PHPCS result to a 'settable' action variable, and then re-use that on the email. Their example claims you can use this to email out actions logs.
https://buddy.works/blog/new-feature-passing-parameters
Don't be fooled by this. It kind of works. The issue is that the variable only seems to be able to hold 255 characters! How useless is that! Definately not able to pass log data like their suggestion claims. Way to short.
My next thoughts were to use my own emailing. Simple enough, using bash to send out emails.
Again, not so simple. The PHPCS buddy action uses a PHP docker image, and it has zero mail sending capabilities.
Logically, the next step would be to just use my own built docker image, with mail capbilities setup. This would work, but just seems like soooo much effort, for just sending mail.
If not using mail sending (exim/postfix/sendmail) configured on the linux docker image, whats next?
Mandrill (or insert your favourite email sending platform here). We already use Mandrill, so it is the logical choice.
My next attempt was to use CURL, via bash script, and simply call the Mandrill send API. This kind of worked, but was prone to failure. The failure was injecting the PHPCS result into the CURL send. It required a lot of string processing, ensuring the content was JSON complient. (mandrill uses JSON as payload for send)
After some hours messing around with this, and getting partial success, I had another idea:
Mandill supplies a PHP library to facilitate sending. (https://bitbucket.org/mailchimp/mandrill-api-php/src/master/)
I am already on a PHP capable docker image, so I could just use PHP to effect the send. Formatting and manipulating the string content in PHP would be MUCH easier than BASH.
The ONLY issue I had was that I did not want to have to store a PHP script somwehere, which then needs to be injected into the PHPCS action's docker image (easy enough with a wget), but having another script, 'detached' from this action did not sit nice with me.
The result/answer was to just place the PHP code INLINE in the action BASH script.
Some variable used in the script below are set via the buddy action variables section. The code is used in teh PHPCS action RUN section on buddy.
composer require magento-ecg/coding-standard mandrill/mandrill
[ -d "code_sniff" ] || mkdir code_sniff
phpcs --config-set ignore_warnings_on_exit 1
phpcs --config-set ignore_errors_on_exit 1
phpcs --report-file=./code_sniff/sniff.txt --standard=./vendor/magento-ecg/coding-standard/Ecg ${PATH_TO_SNIFF}
php_cwd=`php << 'EOF'
<?php
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/vendor/mandrill/mandrill/src/Mandrill.php';
try {
$mandrill = new Mandrill();
$message = array(
'text' => file_get_contents( __DIR__ . "/code_sniff/sniff.txt" ),
'subject' => "PHPCS SNIFF for deploy $BUDDY_PIPELINE_NAME ${BUDDY_EXECUTION_ID}",
'from_email' => "${EMAIL}",
'from_name' => "${EMAIL}",
'to' => array(
array(
'email' => "${EMAIL}",
'name' => "${EMAIL}",
'type' => 'to'
)
)
);
$result = $mandrill->messages->send($message);
print_r($result);
} catch(Mandrill_Error $e) {
echo 'A mandrill error occurred: ' . get_class($e) . ' - ' . $e->getMessage();
throw $e;
}
?>
EOF`