Compare commits
24 Commits
Author | SHA1 | Date |
---|---|---|
Michal Kleiner | 9881c03c22 | |
Guy Sartorelli | e8517ebfb0 | |
Michal Kleiner | 28ca036345 | |
Guy Sartorelli | 16caad30b2 | |
Maxime Rainville | 6f6c30bdcc | |
Guy Sartorelli | f918209e35 | |
Maxime Rainville | 714de64252 | |
Steve Boyd | d9d245a0da | |
Guy Sartorelli | 9d5f8fce7d | |
Guy Sartorelli | f12698f47f | |
Guy Sartorelli | 6f0d1c84f2 | |
Guy Sartorelli | 15a8bca241 | |
Steve Boyd | 94ff5b621c | |
Will Rossiter | 0e4867f736 | |
Steve Boyd | 7e59b7e88b | |
Steve Boyd | e4b8934148 | |
Guy Sartorelli | 737ac0d8ed | |
Steve Boyd | 3378dc7a99 | |
Steve Boyd | 58caa67c96 | |
Steve Boyd | 7be4c0dbf3 | |
Guy Sartorelli | 7ba4acc4b2 | |
Steve Boyd | a76c3b89ea | |
Guy Sartorelli | 7f6c03b0cb | |
Will Rossiter | 3e3907d14c |
|
@ -0,0 +1,11 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
name: CI
|
||||
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1
|
|
@ -0,0 +1,16 @@
|
|||
name: Dispatch CI
|
||||
|
||||
on:
|
||||
# At 1:20 PM UTC, only on Wednesday and Thursday
|
||||
schedule:
|
||||
- cron: '20 13 * * 3,4'
|
||||
|
||||
jobs:
|
||||
dispatch-ci:
|
||||
name: Dispatch CI
|
||||
# Only run cron on the silverstripe account
|
||||
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dispatch CI
|
||||
uses: silverstripe/gha-dispatch-ci@v1
|
|
@ -0,0 +1,17 @@
|
|||
name: Keepalive
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
# The 4th of every month at 10:50am UTC
|
||||
schedule:
|
||||
- cron: '50 10 4 * *'
|
||||
|
||||
jobs:
|
||||
keepalive:
|
||||
name: Keepalive
|
||||
# Only run cron on the silverstripe account
|
||||
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Keepalive
|
||||
uses: silverstripe/gha-keepalive@v1
|
|
@ -1,15 +0,0 @@
|
|||
inherit: true
|
||||
|
||||
build:
|
||||
nodes:
|
||||
analysis:
|
||||
tests:
|
||||
override: [php-scrutinizer-run]
|
||||
|
||||
checks:
|
||||
php:
|
||||
code_rating: true
|
||||
duplication: true
|
||||
|
||||
filter:
|
||||
paths: [src/*, tests/*]
|
|
@ -1,4 +0,0 @@
|
|||
version: ~> 1.0
|
||||
|
||||
import:
|
||||
- silverstripe/silverstripe-travis-shared:config/provision/standard-jobs-range.yml
|
|
@ -1,11 +1,7 @@
|
|||
# SilverStripe Environment Checker Module
|
||||
# Silverstripe Environment Checker Module
|
||||
|
||||
[![Build Status](https://api.travis-ci.com/silverstripe/silverstripe-environmentcheck.svg?branch=2)](https://travis-ci.com/silverstripe/silverstripe-environmentcheck)
|
||||
[![SilverStripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
|
||||
[![Code Quality](https://scrutinizer-ci.com/g/silverstripe/silverstripe-environmentcheck/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/silverstripe/silverstripe-environmentcheck/?branch=master)
|
||||
[![Code Coverage](https://codecov.io/gh/silverstripe/silverstripe-environmentcheck/branch/master/graph/badge.svg)](https://codecov.io/gh/silverstripe/silverstripe-environmentcheck)
|
||||
[![Version](http://img.shields.io/packagist/v/silverstripe/environmentcheck.svg?style=flat-square)](https://packagist.org/packages/silverstripe/environmentcheck)
|
||||
[![License](http://img.shields.io/packagist/l/silverstripe/environmentcheck.svg?style=flat-square)](LICENSE.md)
|
||||
[![CI](https://github.com/silverstripe/silverstripe-environmentcheck/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-environmentcheck/actions/workflows/ci.yml)
|
||||
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
|
||||
|
||||
This module adds an API for running environment checks to your API.
|
||||
|
||||
|
@ -15,10 +11,10 @@ This module adds an API for running environment checks to your API.
|
|||
|
||||
## Requirements
|
||||
|
||||
* SilverStripe 4.x
|
||||
* Silverstripe 4.x
|
||||
* PHP 7.3
|
||||
|
||||
For SilverStripe 3.x support, please use a `1.x` tagged release.
|
||||
For Silverstripe 3.x support, please use a `1.x` tagged release.
|
||||
|
||||
## Aren't these just unit tests?
|
||||
|
||||
|
@ -86,6 +82,7 @@ SilverStripe\EnvironmentCheck\EnvironmentCheckSuite:
|
|||
* `HasClassCheck`: Check that the given class exists.
|
||||
This can be used to check that PHP modules or features are installed.
|
||||
* `FileWriteableCheck`: Check that the given file is writeable.
|
||||
* `FileAccessibilityAndValidationCheck`: Check that a given file is accessible and optionally matches a given format.
|
||||
* `FileAgeCheck`: Checks for the maximum age of one or more files or folders.
|
||||
Useful for files which should be frequently auto-generated,
|
||||
like static caches, as well as for backup files and folders.
|
||||
|
@ -111,7 +108,7 @@ SilverStripe\EnvironmentCheck\EnvironmentChecker:
|
|||
from_email_address: admin@test.com
|
||||
```
|
||||
|
||||
Errors can be logged via the standard SilverStripe PSR-3 compatible logging. Each check will cause an individual log
|
||||
Errors can be logged via the standard Silverstripe PSR-3 compatible logging. Each check will cause an individual log
|
||||
entry. You can choose to enable logging separately for warnings and errors, identified through the
|
||||
result of `EnvironmentCheck->check()`.
|
||||
|
|
@ -38,4 +38,4 @@
|
|||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
|
||||
|
||||
<testsuites>
|
||||
|
|
|
@ -43,7 +43,7 @@ class SolrIndexCheck implements EnvironmentCheck
|
|||
if (!empty($brokenCores)) {
|
||||
return [
|
||||
EnvironmentCheck::ERROR,
|
||||
'The following indexes are unavailable: ' . implode($brokenCores ?? '', ', ')
|
||||
'The following indexes are unavailable: ' . implode(', ', $brokenCores)
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -43,8 +43,11 @@ class DevCheckController extends Controller
|
|||
$suite = $name;
|
||||
}
|
||||
|
||||
$checker = new EnvironmentChecker($suite, 'Environment status');
|
||||
$checker->setRequest($request);
|
||||
/** @var EnvironmentChecker */
|
||||
$checker = EnvironmentChecker::create($suite, 'Environment status')
|
||||
->setRequest($request)
|
||||
->setIncludeDetails(true);
|
||||
|
||||
$checker->init($this->config()->permission);
|
||||
|
||||
return $checker;
|
||||
|
|
|
@ -28,7 +28,6 @@ class DevHealthController extends Controller
|
|||
public function index()
|
||||
{
|
||||
// health check does not require permission to run
|
||||
|
||||
$checker = new EnvironmentChecker('health', 'Site health');
|
||||
$checker->setErrorCode(500);
|
||||
|
||||
|
|
|
@ -40,6 +40,11 @@ class EnvironmentChecker extends RequestHandler
|
|||
*/
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $includeDetails = false;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
@ -172,19 +177,31 @@ class EnvironmentChecker extends RequestHandler
|
|||
$response->setStatusCode($this->errorCode);
|
||||
}
|
||||
|
||||
$resultText = $result->customise([
|
||||
$data = [
|
||||
'URL' => Director::absoluteBaseURL(),
|
||||
'Title' => $this->title,
|
||||
'Name' => $this->checkSuiteName,
|
||||
'ErrorCode' => $this->errorCode,
|
||||
])->renderWith(__CLASS__);
|
||||
'ErrorCode' => $this->errorCode
|
||||
];
|
||||
|
||||
$emailContent = $result->customise(array_merge($data, [
|
||||
'IncludeDetails' => true
|
||||
]))->renderWith(__CLASS__);
|
||||
|
||||
if (!$this->includeDetails) {
|
||||
$webContent = $result->customise(array_merge($data, [
|
||||
'IncludeDetails' => false
|
||||
]))->renderWith(__CLASS__);
|
||||
} else {
|
||||
$webContent = $emailContent;
|
||||
}
|
||||
|
||||
if ($this->config()->get('email_results') && !$result->ShouldPass()) {
|
||||
$email = new Email(
|
||||
$this->config()->get('from_email_address'),
|
||||
$this->config()->get('to_email_address'),
|
||||
$this->title,
|
||||
$resultText
|
||||
$emailContent
|
||||
);
|
||||
$email->send();
|
||||
}
|
||||
|
@ -213,7 +230,7 @@ class EnvironmentChecker extends RequestHandler
|
|||
return $response;
|
||||
}
|
||||
|
||||
$response->setBody($resultText);
|
||||
$response->setBody($webContent);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
@ -229,73 +246,92 @@ class EnvironmentChecker extends RequestHandler
|
|||
Injector::inst()->get(LoggerInterface::class)->log($level, $message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the HTTP status code that should be returned when there's an error.
|
||||
*
|
||||
* @param int $errorCode
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setErrorCode($errorCode)
|
||||
{
|
||||
$this->errorCode = $errorCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Set whether to include the full breakdown of services
|
||||
*
|
||||
* @param bool $includeDetails
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setIncludeDetails($includeDetails)
|
||||
{
|
||||
$this->includeDetails = $includeDetails;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 2.0.0 Use config API instead
|
||||
* @param string $from
|
||||
*/
|
||||
public static function set_from_email_address($from)
|
||||
{
|
||||
Deprecation::notice('2.0', 'Use config API instead');
|
||||
Deprecation::notice('2.0.0', 'Use config API instead');
|
||||
static::config()->set('from_email_address', $from);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @deprecated 2.0.0 Use config API instead
|
||||
* @return null|string
|
||||
*/
|
||||
public static function get_from_email_address()
|
||||
{
|
||||
Deprecation::notice('2.0', 'Use config API instead');
|
||||
Deprecation::notice('2.0.0', 'Use config API instead');
|
||||
return static::config()->get('from_email_address');
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @deprecated 2.0.0 Use config API instead
|
||||
* @param string $to
|
||||
*/
|
||||
public static function set_to_email_address($to)
|
||||
{
|
||||
Deprecation::notice('2.0', 'Use config API instead');
|
||||
Deprecation::notice('2.0.0', 'Use config API instead');
|
||||
static::config()->set('to_email_address', $to);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @deprecated 2.0.0 Use config API instead
|
||||
* @return null|string
|
||||
*/
|
||||
public static function get_to_email_address()
|
||||
{
|
||||
Deprecation::notice('2.0', 'Use config API instead');
|
||||
Deprecation::notice('2.0.0', 'Use config API instead');
|
||||
return static::config()->get('to_email_address');
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @deprecated 2.0.0 Use config API instead
|
||||
* @param bool $results
|
||||
*/
|
||||
public static function set_email_results($results)
|
||||
{
|
||||
Deprecation::notice('2.0', 'Use config API instead');
|
||||
Deprecation::notice('2.0.0', 'Use config API instead');
|
||||
static::config()->set('email_results', $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @deprecated 2.0.0 Use config API instead
|
||||
* @return bool
|
||||
*/
|
||||
public static function get_email_results()
|
||||
{
|
||||
Deprecation::notice('2.0', 'Use config API instead');
|
||||
Deprecation::notice('2.0.0', 'Use config API instead');
|
||||
return static::config()->get('email_results');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,16 +64,18 @@
|
|||
<h1 class="$Status">$Title: $Status</h1>
|
||||
<h2 class="website">Site: $URL</h2>
|
||||
|
||||
<% if $IncludeDetails %>
|
||||
<table>
|
||||
<tr><th>Check</th> <th>Status</th> <th>Message</th></tr>
|
||||
<% loop $Details %>
|
||||
<tr><td>$Check</td> <td class="$Status">$Status</td> <td>$Message.XML</td></tr>
|
||||
<% end_loop %>
|
||||
</table>
|
||||
<% end_if %>
|
||||
|
||||
<% if $ShouldPass %>
|
||||
<p>Site is available</p>
|
||||
<p class="subtext">(you may check for the presence of the text 'Site is available' rather than an HTTP $ErrorCode error on this page, if you prefer.)</p>
|
||||
<p>Site is available</p>
|
||||
<p class="subtext">(you may check for the presence of the text 'Site is available' rather than an HTTP $ErrorCode error on this page, if you prefer.<% if not $IncludeDetails %> Full details are available for logged in users at <a href="{$AbsoluteBaseURL}dev/check/">dev/check</a><% end_if %>)</p>
|
||||
<% else %>
|
||||
<% if $Name == "check" %>
|
||||
<p><b>A subsystem of the site is unavailable, but the site remains operational</b></p>
|
||||
|
|
|
@ -28,4 +28,14 @@ class DevCheckControllerTest extends SapphireTest
|
|||
|
||||
$this->assertInstanceOf(EnvironmentChecker::class, $controller->index($request));
|
||||
}
|
||||
|
||||
public function testCheckIncludesDetails()
|
||||
{
|
||||
$controller = new DevCheckController();
|
||||
$request = new HTTPRequest('GET', 'example.com');
|
||||
|
||||
$response = $controller->index($request)->index();
|
||||
|
||||
$this->assertStringContainsString('<table>', $response->getBody());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,4 +37,15 @@ class DevHealthControllerTest extends SapphireTest
|
|||
|
||||
$this->assertInstanceOf(EnvironmentChecker::class, $controller->index($request));
|
||||
}
|
||||
|
||||
|
||||
public function testHealthDoesNotIncludeDetails()
|
||||
{
|
||||
$controller = new DevHealthController();
|
||||
$request = new HTTPRequest('GET', 'example.com');
|
||||
|
||||
$response = $controller->index($request)->index();
|
||||
|
||||
$this->assertFalse(strpos($response->getBody(), '<table>'));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue