diff --git a/.php-censor.yml b/.php-censor.yml
index 9d0c0e80..03ea5b68 100644
--- a/.php-censor.yml
+++ b/.php-censor.yml
@@ -1,4 +1,5 @@
build_settings:
+ clone_depth: 1
ignore:
- vendor
- tests
@@ -13,6 +14,11 @@ test:
- phpunit.xml
coverage: true
+ php_mess_detector:
+ allow_failures: true
+ rules:
+ - phpmd.xml
+
php_code_sniffer:
standard: PSR2
encoding: UTF-8
@@ -27,6 +33,9 @@ test:
php_parallel_lint:
allow_failures: true
+ php_docblock_checker:
+ allow_failures: true
+
security_checker:
allow_failures: false
diff --git a/composer.json b/composer.json
index 85dfee1b..5909cce5 100644
--- a/composer.json
+++ b/composer.json
@@ -76,7 +76,7 @@
"codeception/codeception": "~2.3.0",
"phpmd/phpmd": "~2.6.0",
"sebastian/phpcpd": "~2.0.0",
- "squizlabs/php_codesniffer": "~3.2.0",
+ "squizlabs/php_codesniffer": "~2.8.0",
"block8/php-docblock-checker": "~1.3.0",
"phploc/phploc": "~4.0.0",
"jakub-onderka/php-parallel-lint": "~0.9.0",
diff --git a/composer.lock b/composer.lock
index ef6f9e1c..550dfd88 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,10 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "8ed0d649c464752b717de050e04cd313",
+ "content-hash": "6c8facd9ea26fd63006a35d445fac984",
"packages": [
{
"name": "behat/gherkin",
@@ -2959,37 +2959,64 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "3.2.3",
+ "version": "2.8.1",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "4842476c434e375f9d3182ff7b89059583aa8b27"
+ "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4842476c434e375f9d3182ff7b89059583aa8b27",
- "reference": "4842476c434e375f9d3182ff7b89059583aa8b27",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d",
+ "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d",
"shasum": ""
},
"require": {
"ext-simplexml": "*",
"ext-tokenizer": "*",
"ext-xmlwriter": "*",
- "php": ">=5.4.0"
+ "php": ">=5.1.2"
},
"require-dev": {
- "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+ "phpunit/phpunit": "~4.0"
},
"bin": [
- "bin/phpcs",
- "bin/phpcbf"
+ "scripts/phpcs",
+ "scripts/phpcbf"
],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.x-dev"
+ "dev-master": "2.x-dev"
}
},
+ "autoload": {
+ "classmap": [
+ "CodeSniffer.php",
+ "CodeSniffer/CLI.php",
+ "CodeSniffer/Exception.php",
+ "CodeSniffer/File.php",
+ "CodeSniffer/Fixer.php",
+ "CodeSniffer/Report.php",
+ "CodeSniffer/Reporting.php",
+ "CodeSniffer/Sniff.php",
+ "CodeSniffer/Tokens.php",
+ "CodeSniffer/Reports/",
+ "CodeSniffer/Tokenizers/",
+ "CodeSniffer/DocGenerators/",
+ "CodeSniffer/Standards/AbstractPatternSniff.php",
+ "CodeSniffer/Standards/AbstractScopeSniff.php",
+ "CodeSniffer/Standards/AbstractVariableSniff.php",
+ "CodeSniffer/Standards/IncorrectPatternException.php",
+ "CodeSniffer/Standards/Generic/Sniffs/",
+ "CodeSniffer/Standards/MySource/Sniffs/",
+ "CodeSniffer/Standards/PEAR/Sniffs/",
+ "CodeSniffer/Standards/PSR1/Sniffs/",
+ "CodeSniffer/Standards/PSR2/Sniffs/",
+ "CodeSniffer/Standards/Squiz/Sniffs/",
+ "CodeSniffer/Standards/Zend/Sniffs/"
+ ]
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
@@ -3006,7 +3033,7 @@
"phpcs",
"standards"
],
- "time": "2018-02-20T21:35:23+00:00"
+ "time": "2017-03-01T22:17:45+00:00"
},
{
"name": "swiftmailer/swiftmailer",
diff --git a/docs/en/README.md b/docs/en/README.md
index 02b8c982..963bb57f 100644
--- a/docs/en/README.md
+++ b/docs/en/README.md
@@ -78,7 +78,7 @@ Plugins
* [Campfire](plugins/campfire.md) - `campfire`
* [Email](plugins/email.md) - `email`
-* [FlowDock](plugins/flowdock_notify.md) - `flowdock_notify`
+* FlowDock - `flowdock_notify`
* [HipChat](plugins/hipchat_notify.md) - `hipchat_notify`
* [IRC](plugins/irc.md) - `irc`
* [Slack](plugins/slack_notify.md) - `slack_notify`
diff --git a/docs/en/plugins/flowdock_notify.md b/docs/en/plugins/flowdock_notify.md
deleted file mode 100644
index aa18edfa..00000000
--- a/docs/en/plugins/flowdock_notify.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Plugin FlowdockNotify
-=====================
-
-This plugin joins a [Flowdock](https://www.flowdock.com/) room and sends a user-defined message, for example a
-"Build Succeeded" message.
-
-Installation
-------------
-
-The plugin depends on `mremi/flowdock` library. To use FlowdockNotify plugin you should install dependency:
-
-```
-composer require "mremi/flowdock"
-```
diff --git a/docs/en/plugins/hipchat_notify.md b/docs/en/plugins/hipchat_notify.md
index d83ece35..d783af65 100644
--- a/docs/en/plugins/hipchat_notify.md
+++ b/docs/en/plugins/hipchat_notify.md
@@ -1,18 +1,9 @@
-Plugin HipchatNotify
+Plugin Hipchat Notify
=====================
This plugin joins a [HipChat](https://www.hipchat.com/) room and sends a user-defined message, for example a
"Build Succeeded" message.
-Installation
-------------
-
-The plugin depends on `hipchat/hipchat-php` library. To use HipchatNotify plugin you should install dependency:
-
-```
-composer require "hipchat/hipchat-php"
-```
-
Configuration
-------------
diff --git a/docs/en/plugins/slack_notify.md b/docs/en/plugins/slack_notify.md
index 259c5c79..07222902 100644
--- a/docs/en/plugins/slack_notify.md
+++ b/docs/en/plugins/slack_notify.md
@@ -1,18 +1,9 @@
-Plugin SlackNotify
+Plugin Slack Notify
===================
This plugin joins a [Slack](https://www.slack.com/) room and sends a user-defined message, for example a "Build
Succeeded" message.
-Installation
-------------
-
-The plugin depends on `maknz/slack` library. To use SlackNotify plugin you should install dependency:
-
-```
-composer require "maknz/slack"
-```
-
Configuration
-------------
diff --git a/public/assets/js/app.js b/public/assets/js/app.js
index 644d7974..c37723cd 100644
--- a/public/assets/js/app.js
+++ b/public/assets/js/app.js
@@ -498,3 +498,17 @@ var Lang = {
return string;
}
};
+
+jquery(document).ready(function() {
+ jquery('#delete-build').on('click', function (e) {
+ e.preventDefault();
+
+ var buildId = this.data('buildId');
+ var projectId = this.data('projectId');
+
+ confirmDelete(APP_URL + 'build/delete/' + buildId)
+ .onCloseConfirmed = function () {
+ window.location = APP_URL + 'project/view/' + projectId;
+ };
+ });
+});
diff --git a/src/Controller/BuildController.php b/src/Controller/BuildController.php
index 3db8143b..7430449a 100644
--- a/src/Controller/BuildController.php
+++ b/src/Controller/BuildController.php
@@ -10,6 +10,7 @@ use PHPCensor\Helper\AnsiConverter;
use PHPCensor\Helper\Lang;
use PHPCensor\Http\Response\RedirectResponse;
use PHPCensor\Model\Build;
+use PHPCensor\Model\Project;
use PHPCensor\Model\User;
use PHPCensor\Service\BuildService;
use PHPCensor\WebController;
@@ -47,8 +48,6 @@ class BuildController extends WebController
}
/**
- * View a specific build.
- *
* @param integer $buildId
*
* @throws NotFoundException
@@ -143,6 +142,77 @@ class BuildController extends WebController
$this->layout->actions = $actions;
}
+ /**
+ * @param integer $buildId
+ *
+ * @throws NotFoundException
+ */
+ public function viewLog($buildId)
+ {
+ $build = BuildFactory::getBuildById($buildId);
+
+ if (!$build) {
+ throw new NotFoundException(Lang::get('build_x_not_found', $buildId));
+ }
+
+ /** @var Project $project */
+ $project = Factory::getStore('Project')->getByPrimaryKey($build->getProjectId());
+
+ /** @var \PHPCensor\Store\BuildErrorStore $errorStore */
+ $errorStore = Factory::getStore('BuildError');
+
+ $this->view->build = $build;
+ $this->view->totalErrors = $errorStore->getErrorTotalForBuild($build->getId());
+
+ $this->layout->title = Lang::get('build_n', $buildId);
+ $this->layout->subtitle = $build->getProjectTitle();
+
+ switch ($build->getStatus()) {
+ case 0:
+ $this->layout->skin = 'blue';
+ break;
+
+ case 1:
+ $this->layout->skin = 'yellow';
+ break;
+
+ case 2:
+ $this->layout->skin = 'green';
+ break;
+
+ case 3:
+ $this->layout->skin = 'red';
+ break;
+ }
+
+ $rebuildLabel = Lang::get('rebuild_now');
+ $rebuildLink = APP_URL . 'build/rebuild/' . $build->getId();
+
+ $deleteLabel = Lang::get('delete_build');
+ $deleteLink = APP_URL . 'build/delete/' . $build->getId();
+
+ $actions = '';
+ if (!$project->getArchived()) {
+ $actions .= sprintf(
+ '%s',
+ $rebuildLink,
+ $rebuildLabel
+ );
+ }
+
+ if ($this->currentUserIsAdmin()) {
+ $actions .= sprintf(
+ '%s',
+ $build->getId(),
+ $build->getProjectId(),
+ $deleteLink,
+ $deleteLabel
+ );
+ }
+
+ $this->layout->actions = $actions;
+ }
+
/**
* Returns an array of the JS plugins to include.
* @return array
diff --git a/src/Controller/WebhookController.php b/src/Controller/WebhookController.php
index 2f987039..e810479c 100644
--- a/src/Controller/WebhookController.php
+++ b/src/Controller/WebhookController.php
@@ -592,11 +592,11 @@ class WebhookController extends Controller
}
/**
+ * Called by Gogs Webhooks:
+ *
* @param string $projectId
*
* @return array
- *
- * @throws Exception
*/
public function gogs($projectId)
{
@@ -605,17 +605,15 @@ class WebhookController extends Controller
Project::TYPE_GIT,
]);
- $contentType = !empty($_SERVER['CONTENT_TYPE'])
- ? $_SERVER['CONTENT_TYPE']
- : null;
-
- switch ($contentType) {
+ switch ($_SERVER['CONTENT_TYPE']) {
+ case 'application/json':
+ $payload = json_decode(file_get_contents('php://input'), true);
+ break;
case 'application/x-www-form-urlencoded':
$payload = json_decode($this->getParam('payload'), true);
break;
- case 'application/json':
default:
- $payload = json_decode(file_get_contents('php://input'), true);
+ return ['status' => 'failed', 'error' => 'Content type not supported.', 'responseCode' => 401];
}
// Handle Push web hooks:
diff --git a/src/Helper/Xml.php b/src/Helper/Xml.php
deleted file mode 100644
index e3b91876..00000000
--- a/src/Helper/Xml.php
+++ /dev/null
@@ -1,85 +0,0 @@
-data = preg_replace(self::PATTERN, '', $bucket->data);
- $consumed += $bucket->datalen;
-
- stream_bucket_append($out, $bucket);
- }
-
- return PSFS_PASS_ON;
- }
-}
-
-class Xml
-{
- /**
- * @param $filePath
- *
- * @return null|\SimpleXMLElement
- */
- public static function loadFromFile($filePath)
- {
- stream_filter_register('xml_utf8_clean', 'PHPCensor\Helper\XmlUtf8CleanFilter');
-
- try {
- $xml = simplexml_load_file('php://filter/read=xml_utf8_clean/resource=' . $filePath);
- } catch (\Exception $ex) {
- $xml = null;
- } catch (\Throwable $ex) { // since php7
- $xml = null;
- }
-
- if (!$xml) {
- // from https://stackoverflow.com/questions/7766455/how-to-handle-invalid-unicode-with-simplexml/8092672#8092672
- $oldUse = libxml_use_internal_errors(true);
-
- libxml_clear_errors();
-
- $dom = new \DOMDocument("1.0", "UTF-8");
-
- $dom->strictErrorChecking = false;
- $dom->validateOnParse = false;
- $dom->recover = true;
-
- $dom->loadXML(strtr(
- file_get_contents($filePath),
- ['"' => "'"] // " in attribute names may mislead the parser
- ));
-
- /** @var \LibXMLError $xmlError */
- $xmlError = libxml_get_last_error();
- if ($xmlError) {
- $warning = sprintf('L%s C%s: %s', $xmlError->line, $xmlError->column, $xmlError->message);
- print 'WARNING: ignored errors while reading phpunit result, '.$warning."\n";
- }
-
- if (!$dom->hasChildNodes()) {
- new \SimpleXMLElement('');
- }
-
- $xml = simplexml_import_dom($dom);
-
- libxml_clear_errors();
- libxml_use_internal_errors($oldUse);
- }
-
- return $xml;
- }
-}
diff --git a/src/Plugin/Codeception.php b/src/Plugin/Codeception.php
index 585aea4e..d5e8e1d4 100644
--- a/src/Plugin/Codeception.php
+++ b/src/Plugin/Codeception.php
@@ -145,7 +145,8 @@ class Codeception extends Plugin implements ZeroConfigPluginInterface
}
}
- $parser = new Parser($this->builder, ($outputPath . 'report.xml'));
+ $xml = file_get_contents($outputPath . 'report.xml', false);
+ $parser = new Parser($this->builder, $xml);
$output = $parser->parse();
$meta = [
diff --git a/src/Plugin/Util/PhpUnitResultJunit.php b/src/Plugin/Util/PhpUnitResultJunit.php
index 14ec1c7f..3e149105 100644
--- a/src/Plugin/Util/PhpUnitResultJunit.php
+++ b/src/Plugin/Util/PhpUnitResultJunit.php
@@ -2,8 +2,6 @@
namespace PHPCensor\Plugin\Util;
-use PHPCensor\Helper\Xml;
-
/**
* Class PhpUnitResultJunit parses the results for the PhpUnitV2 plugin
*
@@ -26,11 +24,11 @@ class PhpUnitResultJunit extends PhpUnitResult
$suites = $this->loadResultFile();
- if ($suites) {
- foreach ($suites->xpath('//testcase') as $testCase) {
- $this->parseTestcase($testCase);
- }
+ foreach ($suites->xpath('//testcase') as $testCase) {
+ $this->parseTestcase($testCase);
}
+ $suites['failures'];
+ $suites['errors'];
return $this;
}
@@ -141,7 +139,44 @@ class PhpUnitResultJunit extends PhpUnitResult
return new \SimpleXMLElement(''); // new empty element
}
- return Xml::loadFromFile($this->outputFile);
+ try {
+ $suites = simplexml_load_file($this->outputFile);
+ } catch (\Exception $ex) {
+ $suites = null;
+ } catch (\Throwable $ex) { // since php7
+ $suites = null;
+ }
+ if (!$suites) {
+ // from https://stackoverflow.com/questions/7766455/how-to-handle-invalid-unicode-with-simplexml/8092672#8092672
+ $oldUse = libxml_use_internal_errors(true);
+ libxml_clear_errors();
+ $dom = new \DOMDocument("1.0", "UTF-8");
+ $dom->strictErrorChecking = false;
+ $dom->validateOnParse = false;
+ $dom->recover = true;
+ $dom->loadXML(strtr(
+ file_get_contents($this->outputFile),
+ array('"' => "'") // " in attribute names may mislead the parser
+ ));
+
+ /**
+ * @var \LibXMLError
+ */
+ $xmlError = libxml_get_last_error();
+ if ($xmlError) {
+ $warning = sprintf('L%s C%s: %s', $xmlError->line, $xmlError->column, $xmlError->message);
+ print 'WARNING: ignored errors while reading phpunit result, '.$warning."\n";
+ }
+ if (!$dom->hasChildNodes()) {
+ $this->internalProblem('xml file with no content');
+ }
+ $suites = simplexml_import_dom($dom);
+
+ libxml_clear_errors();
+ libxml_use_internal_errors($oldUse);
+ }
+
+ return $suites;
}
/**
@@ -150,5 +185,7 @@ class PhpUnitResultJunit extends PhpUnitResult
private function internalProblem($description)
{
throw new \RuntimeException($description);
+
+ // alternative to error throwing: append to $this->errors
}
}
diff --git a/src/Plugin/Util/TestResultParsers/Codeception.php b/src/Plugin/Util/TestResultParsers/Codeception.php
index 90fcbb2e..dfd97cae 100644
--- a/src/Plugin/Util/TestResultParsers/Codeception.php
+++ b/src/Plugin/Util/TestResultParsers/Codeception.php
@@ -3,7 +3,6 @@
namespace PHPCensor\Plugin\Util\TestResultParsers;
use PHPCensor\Builder;
-use PHPCensor\Helper\Xml;
/**
* Class Codeception
@@ -12,49 +11,23 @@ use PHPCensor\Helper\Xml;
*/
class Codeception implements ParserInterface
{
- /**
- * @var Builder
- */
protected $builder;
-
- /**
- * @var string
- */
- protected $xmlPath;
-
- /**
- * @var array
- */
+ protected $resultsXml;
protected $results;
-
- /**
- * @var int
- */
- protected $totalTests = 0;
-
- /**
- * @var int
- */
- protected $totalTimeTaken = 0;
-
- /**
- * @var int
- */
- protected $totalFailures = 0;
-
- /**
- * @var int
- */
- protected $totalErrors = 0;
+ protected $totalTests;
+ protected $totalTimeTaken;
+ protected $totalFailures;
+ protected $totalErrors;
/**
* @param Builder $builder
- * @param string $xmlPath
+ * @param $resultsXml
*/
- public function __construct(Builder $builder, $xmlPath)
+ public function __construct(Builder $builder, $resultsXml)
{
- $this->builder = $builder;
- $this->xmlPath = $xmlPath;
+ $this->builder = $builder;
+ $this->resultsXml = $resultsXml;
+ $this->totalTests = 0;
}
/**
@@ -63,43 +36,42 @@ class Codeception implements ParserInterface
public function parse()
{
$rtn = [];
- $this->results = Xml::loadFromFile($this->xmlPath);
+ $this->results = new \SimpleXMLElement($this->resultsXml);
- if ($this->results) {
- foreach ($this->results->testsuite as $testSuite) {
- $this->totalTests += (int)$testSuite['tests'];
- $this->totalTimeTaken += (float)$testSuite['time'];
- $this->totalFailures += (int)$testSuite['failures'];
- $this->totalErrors += (int)$testSuite['errors'];
+ // calculate total results
+ foreach ($this->results->testsuite as $testSuite) {
+ $this->totalTests += (int)$testSuite['tests'];
+ $this->totalTimeTaken += (float)$testSuite['time'];
+ $this->totalFailures += (int)$testSuite['failures'];
+ $this->totalErrors += (int)$testSuite['errors'];
- foreach ($testSuite->testcase as $testCase) {
- $testResult = [
- 'suite' => (string)$testSuite['name'],
- 'file' => str_replace($this->builder->buildPath, '/', (string) $testCase['file']),
- 'name' => (string)$testCase['name'],
- 'feature' => (string)$testCase['feature'],
- 'assertions' => (int)$testCase['assertions'],
- 'time' => (float)$testCase['time']
- ];
+ foreach ($testSuite->testcase as $testCase) {
+ $testResult = [
+ 'suite' => (string)$testSuite['name'],
+ 'file' => str_replace($this->builder->buildPath, '/', (string) $testCase['file']),
+ 'name' => (string)$testCase['name'],
+ 'feature' => (string)$testCase['feature'],
+ 'assertions' => (int)$testCase['assertions'],
+ 'time' => (float)$testCase['time']
+ ];
- if (isset($testCase['class'])) {
- $testResult['class'] = (string) $testCase['class'];
- }
-
- // PHPUnit testcases does not have feature field. Use class::method instead
- if (!$testResult['feature']) {
- $testResult['feature'] = sprintf('%s::%s', $testResult['class'], $testResult['name']);
- }
-
- if (isset($testCase->failure) || isset($testCase->error)) {
- $testResult['pass'] = false;
- $testResult['message'] = isset($testCase->failure) ? (string)$testCase->failure : (string)$testCase->error;
- } else {
- $testResult['pass'] = true;
- }
-
- $rtn[] = $testResult;
+ if (isset($testCase['class'])) {
+ $testResult['class'] = (string) $testCase['class'];
}
+
+ // PHPUnit testcases does not have feature field. Use class::method instead
+ if (!$testResult['feature']) {
+ $testResult['feature'] = sprintf('%s::%s', $testResult['class'], $testResult['name']);
+ }
+
+ if (isset($testCase->failure) || isset($testCase->error)) {
+ $testResult['pass'] = false;
+ $testResult['message'] = isset($testCase->failure) ? (string)$testCase->failure : (string)$testCase->error;
+ } else {
+ $testResult['pass'] = true;
+ }
+
+ $rtn[] = $testResult;
}
}
diff --git a/src/View/Build/errors.phtml b/src/View/Build/errors.phtml
index c7b87be6..979f502d 100644
--- a/src/View/Build/errors.phtml
+++ b/src/View/Build/errors.phtml
@@ -21,7 +21,9 @@ foreach ($errors as $error):
|
getIsNew()): ?>
- = Lang::get('new'); ?>
+
+ = Lang::get('new'); ?>
+
|
@@ -29,19 +31,25 @@ foreach ($errors as $error):
= Lang::get($error->getSeverityString()); ?>
|
- = Lang::get($error->getPlugin()); ?> |
- = $error->getFile(); ?> |
+
+ = Lang::get($error->getPlugin()); ?>
+ |
- getLineStart() == $error->getLineEnd() || !$error->getLineEnd()) {
- echo $error->getLineStart();
- } else {
- echo ($error->getLineStart() . ' - ' . $error->getLineEnd());
- }
- ?>
+ = $error->getFile(); ?>
|
- = htmlspecialchars(trim($error->getMessage())); ?> |
+
+
+ getLineStart() == $error->getLineEnd() || !$error->getLineEnd()): ?>
+ = $error->getLineStart(); ?>
+
+ = ($error->getLineStart() . ' - ' . $error->getLineEnd()); ?>
+
+
+ |
+
+ = htmlspecialchars(trim($error->getMessage())); ?>
+ |
diff --git a/src/View/Build/viewLog.phtml b/src/View/Build/viewLog.phtml
new file mode 100644
index 00000000..a09bc27d
--- /dev/null
+++ b/src/View/Build/viewLog.phtml
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ | = Lang::get('build_source'); ?> |
+
+ = Lang::get($build->getSourceHumanize()); ?>
+ |
+
+
+ | = Lang::get('commit'); ?> |
+
+
+ = substr($build->getCommitId(), 0, 7); ?>
+
+ |
+
+
+
+ | = Lang::get('committer'); ?> |
+
+ = $build->getCommitterEmail(); ?>
+ |
+
+
+
+ | = Lang::get('commit_message'); ?> |
+
+ = htmlspecialchars($build->getCommitMessage()); ?>
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | = Lang::get('created'); ?> |
+
+ = ($build->getCreateDate() ? $build->getCreateDate()->format('Y-m-d H:i:s') : ''); ?>
+ |
+
+
+
+ | = Lang::get('started'); ?> |
+
+ = ($build->getStartDate() ? $build->getStartDate()->format('Y-m-d H:i:s') : ''); ?>
+ |
+
+
+
+ | = Lang::get('finished'); ?> |
+
+ = ($build->getFinishDate() ? $build->getFinishDate()->format('Y-m-d H:i:s') : ''); ?>
+ |
+
+
+
+ | = Lang::get('duration'); ?> |
+
+ = $build->getDuration(); ?> = Lang::get('seconds'); ?>
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
= AnsiConverter::convert($build->getLog()); ?>
+
+
+
diff --git a/src/View/WidgetBuildErrors/index.phtml b/src/View/WidgetBuildErrors/index.phtml
index 363ae597..2d42181d 100644
--- a/src/View/WidgetBuildErrors/index.phtml
+++ b/src/View/WidgetBuildErrors/index.phtml
@@ -2,6 +2,10 @@
use PHPCensor\Helper\Lang;
+/**
+ * @var string $projects
+ */
+
?>