Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 31 additions & 132 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
@@ -1,140 +1,39 @@
name: PHP Tests
name: CI

on:
push:
branches:
- main
- release/*
- support/*
pull_request:
branches:
- main

jobs:
lint:
name: Static analysis for php ${{ matrix.php }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
php: ['8.2', '8.3', '8.4']
os: ['ubuntu-latest']

steps:
- name: Checkout code base
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: phpcs

- name: Setup dependencies
run: composer require -n --no-progress overtrue/phplint

- name: PHP Lint
if: ${{ ! cancelled() }}
run: ./vendor/bin/phplint -n --exclude={^vendor/.*} -- .

- name: PHP CodeSniffer
if: ${{ ! cancelled() }}
run: phpcs -wps --colors

test:
name: Unit tests with php ${{ matrix.php }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}

env:
phpunit-version: 10.0

strategy:
fail-fast: false
matrix:
php: ['8.2', '8.3', '8.4']
os: ['ubuntu-latest']

services:
mysql:
image: mariadb
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: icinga_unittest
MYSQL_USER: icinga_unittest
MYSQL_PASSWORD: icinga_unittest
options: >-
--health-cmd "mariadb -s -uroot -proot -e'SHOW DATABASES;' 2> /dev/null | grep icinga_unittest > test"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 3306/tcp

pgsql:
image: postgres
env:
POSTGRES_USER: icinga_unittest
POSTGRES_PASSWORD: icinga_unittest
POSTGRES_DB: icinga_unittest
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432/tcp

steps:
- name: Checkout code base
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: phpunit:${{ matrix.phpunit-version || env.phpunit-version }}

- name: Setup Icinga Web
run: |
git clone --depth 1 https://github.com/Icinga/icingaweb2.git _icingaweb2
ln -s `pwd` _icingaweb2/modules/notifications

- name: Setup Libraries
run: |
mkdir _libraries
git clone --depth 1 -b snapshot/nightly https://github.com/Icinga/icinga-php-library.git _libraries/ipl
git clone --depth 1 -b snapshot/nightly https://github.com/Icinga/icinga-php-thirdparty.git _libraries/vendor

- name: Checkout Icinga Notifications Daemon
run: |
git clone --depth 1 -b main https://github.com/Icinga/icinga-notifications.git _notifications_daemon

- name: Initialize Icinga Web
run: |
mysql --host="127.0.0.1" --port="${{ job.services.mysql.ports['3306'] }}" --user="root" --password="root" \
-e "CREATE DATABASE icingaweb; CREATE USER icingaweb@'%' IDENTIFIED BY 'icingaweb'; GRANT ALL ON icingaweb.* TO icingaweb@'%';"
PGPASSWORD=icinga_unittest psql --host="127.0.0.1" --port="${{ job.services.pgsql.ports['5432'] }}" \
--username "icinga_unittest" -c "CREATE DATABASE icingaweb;"

- name: PHPUnit
env:
ICINGAWEB_LIBDIR: _libraries
ICINGAWEB_PATH: _icingaweb2
ICINGA_NOTIFICATIONS_SCHEMA: _notifications_daemon/schema
MYSQL_TESTDB: icinga_unittest
MYSQL_TESTDB_HOST: 127.0.0.1
MYSQL_TESTDB_PORT: ${{ job.services.mysql.ports['3306'] }}
MYSQL_TESTDB_USER: icinga_unittest
MYSQL_TESTDB_PASSWORD: icinga_unittest
MYSQL_ICINGAWEBDB: icingaweb
MYSQL_ICINGAWEBDB_PASSWORD: icingaweb
MYSQL_ICINGAWEBDB_USER: icingaweb
PGSQL_TESTDB: icinga_unittest
PGSQL_TESTDB_HOST: 127.0.0.1
PGSQL_TESTDB_PORT: ${{ job.services.pgsql.ports['5432'] }}
PGSQL_TESTDB_USER: icinga_unittest
PGSQL_TESTDB_PASSWORD: icinga_unittest
PGSQL_ICINGAWEBDB: icingaweb
PGSQL_ICINGAWEBDB_PASSWORD: icinga_unittest
PGSQL_ICINGAWEBDB_USER: icinga_unittest
run: phpunit --bootstrap _icingaweb2/test/php/bootstrap.php
php:
name: PHP
uses: Icinga/github-actions/.github/workflows/php.yml@main
with:
databases: true
dependencies: |
{
"./vendor/icingaweb2-modules/icingadb" : "https://github.com/Icinga/icingadb-web.git",
"./vendor/notifications_daemon" : "https://github.com/Icinga/icinga-notifications.git"
}
setup-commands: |
# Only run setup commands if test databases are available which is only the case for PHPUnit jobs
[ -z "${MYSQL_TESTDB_PORT}" ] && exit 0
mysql --host="${MYSQL_TESTDB_HOST}" --port=${MYSQL_TESTDB_PORT} --user=root --password="${MYSQL_TESTDB_PASSWORD}" \
-e "CREATE DATABASE icingaweb; CREATE USER icingaweb@'%' IDENTIFIED BY 'icingaweb'; GRANT ALL ON icingaweb.* TO icingaweb@'%';"
[ -z "${PGSQL_TESTDB_PORT}" ] && exit 0
PGPASSWORD="${PGSQL_TESTDB_PASSWORD}" psql --host="${PGSQL_TESTDB_HOST}" --port=${PGSQL_TESTDB_PORT} \
--username "${PGSQL_TESTDB_USER}" -c "CREATE DATABASE icingaweb;"
env: |
{
"ICINGAWEB_PATH" : "./vendor/icingaweb2",
"ICINGA_NOTIFICATIONS_SCHEMA" : "./vendor/notifications_daemon/schema",
"MYSQL_ICINGAWEBDB" : "icingaweb",
"MYSQL_ICINGAWEBDB_PASSWORD" : "icingaweb",
"MYSQL_ICINGAWEBDB_USER" : "icingaweb",
"PGSQL_ICINGAWEBDB" : "icingaweb",
"PGSQL_ICINGAWEBDB_PASSWORD" : "icinga_unittest",
"PGSQL_ICINGAWEBDB_USER" : "icinga_unittest"
}
16 changes: 0 additions & 16 deletions .github/workflows/phpstan.yml

This file was deleted.

1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@
# Except those related to Git and GitHub
!.git*
!.github
!.phpcs.xml
27 changes: 0 additions & 27 deletions .phpcs.xml

This file was deleted.

4 changes: 2 additions & 2 deletions application/forms/RotationConfigForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -583,13 +583,13 @@ public function removeRotation(int $id): void
/**
* Remove all versions of the rotation from the database
*
* @param int|null $priority The priority of the rotations to remove.
* @param ?int $priority
*
* @return void
*
* @throws LogicException If the priority is not set
*/
public function wipeRotation(int $priority = null): void
public function wipeRotation(?int $priority = null): void
{
$priority = $priority ?? $this->getValue('priority');
if ($priority === null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
*
* @return ResponseInterface
*/
public function execute(ServerRequestInterface $request = null): ResponseInterface
public function execute(?ServerRequestInterface $request = null): ResponseInterface
{
if ($request === null) {
$request = new ServerRequest('GET', '/'); // initial dummy request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

class Error404Response extends Response
{
public function __construct(string $endpointName = null)
public function __construct(?string $endpointName = null)
{
parent::__construct(
response: 404,
Expand Down
2 changes: 1 addition & 1 deletion library/Notifications/Api/V1/ContactGroups.php
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ public function prepareRow(stdClass $row): void
*
* @throws HttpException if the username already exists
*/
private function assertUniqueName(string $name, int $contactgroupId = null): void
private function assertUniqueName(string $name, ?int $contactgroupId = null): void
{
$stmt = (new Select())
->from('contactgroup')
Expand Down
2 changes: 1 addition & 1 deletion library/Notifications/Api/V1/Contacts.php
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ private function removeContact(int $id): void
*
* @throws HttpException if the username already exists
*/
private function assertUniqueUsername(string $username, int $contactId = null): void
private function assertUniqueUsername(string $username, ?int $contactId = null): void
{
$stmt = (new Select())
->from('contact')
Expand Down
10 changes: 9 additions & 1 deletion library/Notifications/Common/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,15 @@ private static function getConnection(): Connection

$config->options = [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ];
if ($config->db === 'mysql') {
$config->options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET SESSION SQL_MODE='STRICT_TRANS_TABLES"
// As of PHP 8.5, driver-specific constants of the PDO class are deprecated,
// but the replacement constants are only available since PHP 8.4.
if (version_compare(PHP_VERSION, '8.4.0', '<')) {
$mysqlAttrInitCommand = PDO::MYSQL_ATTR_INIT_COMMAND;
} else {
$mysqlAttrInitCommand = Pdo\Mysql::ATTR_INIT_COMMAND;
}

$config->options[$mysqlAttrInitCommand] = "SET SESSION SQL_MODE='STRICT_TRANS_TABLES"
. ",NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
}

Expand Down
9 changes: 4 additions & 5 deletions library/Notifications/Daemon/Daemon.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
use React\EventLoop\Loop;
use React\EventLoop\LoopInterface;

use function Clue\React\Block\await;
use function React\Promise\Timer\sleep;
use function React\Async\delay;

class Daemon extends EventEmitter
{
Expand Down Expand Up @@ -262,7 +261,7 @@ protected function processNotifications(): void
/** @var IncidentHistory $notification */
$notificationsToProcess = [];
foreach ($notifications as $notification) {
if (isset($connections[$notification->contact_id])) {
if ($notification->contact_id !== null && isset($connections[$notification->contact_id])) {
ObjectsRendererHook::register($notification->incident->object);
$notificationsToProcess[] = $notification;

Expand Down Expand Up @@ -321,8 +320,8 @@ protected function run(): void

$endMs = (int) (microtime(true) * 1000);
if (($endMs - $beginMs) < 3000) {
// run took less than 3 seconds; sleep for the remaining duration to prevent heavy db loads
await(sleep((3000 - ($endMs - $beginMs)) / 1000));
// run took less than 3 seconds; delay for the remaining duration to prevent heavy db loads
delay((3000 - ($endMs - $beginMs)) / 1000);
}
}
self::$logger::debug(self::PREFIX . "cancellation triggered; exiting loop");
Expand Down
4 changes: 2 additions & 2 deletions library/Notifications/Model/Behavior/IcingaCustomVars.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function isSelectableColumn(string $name): bool
|| str_starts_with($name, self::SERVICE_PREFIX);
}

public function rewriteColumn($column, ?string $relation = null): null
public function rewriteColumn(mixed $column, ?string $relation = null): null
{
return null;
}
Expand All @@ -53,7 +53,7 @@ public function rewriteColumnDefinition(ColumnDefinition $def, string $relation)
));
}

public function rewriteCondition(Filter\Condition $condition, $relation = null): Filter\Condition|Filter\Rule|null
public function rewriteCondition(Filter\Condition $condition, ?string $relation = null): ?Filter\Condition
{
if (! $this->isSelectableColumn($condition->metaData()->get('columnName', ''))) {
return null;
Expand Down
7 changes: 5 additions & 2 deletions library/Notifications/Model/Behavior/IdTagAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function setQuery(Query $query): static
return $this;
}

public function rewriteColumn($column, ?string $relation = null)
public function rewriteColumn(mixed $column, ?string $relation = null): ?AliasedExpression
{
if ($column === 'id_tags') {
$path = ($relation ?? $this->query->getModel()->getTableAlias()) . '.object_id_tag';
Expand Down Expand Up @@ -64,6 +64,8 @@ public function rewriteColumn($column, ?string $relation = null)
$this->query->getResolver()->qualifyColumn('value', $pathAlias)
));
}

return null;
}

public function isSelectableColumn(string $name): bool
Expand Down Expand Up @@ -104,7 +106,8 @@ public function rewriteColumnDefinition(ColumnDefinition $def, string $relation)
{
}

public function rewriteCondition(Filter\Condition $condition, $relation = null)
public function rewriteCondition(Filter\Condition $condition, ?string $relation = null): null
{
return null;
}
}
4 changes: 2 additions & 2 deletions library/Notifications/Model/Behavior/ObjectTags.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ObjectTags implements RewriteColumnBehavior, QueryAwareBehavior
/** @var ?Query */
protected ?Query $query = null;

public function setQuery(Query $query): self
public function setQuery(Query $query): static
{
$this->query = $query;

Expand Down Expand Up @@ -48,7 +48,7 @@ public function rewriteCondition(Filter\Condition $condition, $relation = null):
return $filterAll;
}

public function rewriteColumn($column, $relation = null): AliasedExpression
public function rewriteColumn(mixed $column, $relation = null): AliasedExpression
{
/** @var string $relation */
/** @var string $column */
Expand Down
2 changes: 1 addition & 1 deletion library/Notifications/Test/ApiTestBackends.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ abstract protected static function initializeNotificationsDb(Connection $db, str
*
* @return array<string, array{0: Connection, 1: Url}>
*/
final public function apiTestBackends(): array
final public static function apiTestBackends(): array
{
self::initializeBackends();

Expand Down
Loading
Loading