Skip to content

Commit

Permalink
Added static check and GitHub workflow for it (#137)
Browse files Browse the repository at this point in the history
* Added static check and GitHub workflow for it

* Marked test_php_static_check.sh as executable

* Give human readable names to stages in test-php-static-check.yml

* Revert back to `return new CompletedFuture(null)` in `ElasticHttpTransport::send`

* Fixed issues found by static analysis in the changes from main

* Added ability to run multiple PHP version to test_php_static_check.sh

* Fixed PHP versions format in test-php-static-check.yml matrix

* Switched to generated list of the supported PHP versions

Generating list of the supported PHP versions by reading from ./elastic-otel-php.properties

* Make new workflow names more aligned with the existing

* echo -n instead of echo in generate-php-versions.yml

* Fixed issues with list generation

* Refactored to have only one workflows triggered on PR

* Refactored workflows

* Cleaned up for better diff
  • Loading branch information
SergeyKleyman authored Nov 27, 2024
1 parent 3d75448 commit 113e075
Show file tree
Hide file tree
Showing 24 changed files with 448 additions and 164 deletions.
28 changes: 16 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,27 @@ concurrency:
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
test-sources-license:
uses: ./.github/workflows/test-sources-license.yml

test-php-static-check:
uses: ./.github/workflows/test-php-static-check.yml

build-native:
uses: ./.github/workflows/build-native.yml
with:
build_arch: all

tests-phpt:
needs:
- build-native
uses: ./.github/workflows/test-phpt.yml
with:
build_arch: all

build-php-deps:
uses: ./.github/workflows/build-php-deps.yml

test-sources-license:
uses: ./.github/workflows/test-sources-license.yml

build-packages:
needs:
- build-native
Expand All @@ -42,20 +52,14 @@ jobs:
with:
build_arch: all

tests-phpt:
needs:
- build-native
uses: ./.github/workflows/test-phpt.yml
with:
build_arch: all

# The very last job to report whether the Workflow passed.
# This will act as the Branch Protection gatekeeper
ci:
needs:
- build-packages
- tests-phpt
- test-sources-license
- test-php-static-check
- tests-phpt
- build-packages
runs-on: ubuntu-latest
steps:
- name: report
Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/generate-php-versions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---

# Generates list of supported PHP versions by reading supported_php_versions property in ./elastic-otel-php.properties
name: generate-php-versions

on:
workflow_call:
outputs:
php-versions:
description: "Generated list of supported PHP versions"
value: ${{ jobs.generate-php-versions.outputs.php-versions }}

permissions:
contents: read

jobs:
generate-php-versions:
name: generate-php-versions
timeout-minutes: 5
runs-on: ubuntu-latest
outputs:
php-versions: ${{ steps.generate.outputs.php-versions }}
steps:
- uses: actions/checkout@v4
- id: generate
run: |
source ./tools/read_properties.sh
read_properties elastic-otel-php.properties PROJECT_PROPERTIES
PHP_VERSIONS=${PROJECT_PROPERTIES_SUPPORTED_PHP_VERSIONS//[()]/}
echo "PHP_VERSIONS: ${PHP_VERSIONS}"
PHP_VERSIONS_JSON=$(echo -n ${PHP_VERSIONS} | jq --raw-input --slurp --compact-output 'split(" ") | map(select(length > 0)) | map({ "php-version": . } )')
echo "php-versions={\"include\":${PHP_VERSIONS_JSON}}"
echo "php-versions={\"include\":${PHP_VERSIONS_JSON}}" >> $GITHUB_OUTPUT
28 changes: 28 additions & 0 deletions .github/workflows/test-php-static-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---

name: test-php-static-check

on:
workflow_call: ~
workflow_dispatch: ~

permissions:
contents: read

jobs:
generate-php-versions:
uses: ./.github/workflows/generate-php-versions.yml

static-check:
runs-on: ubuntu-latest
needs: generate-php-versions
timeout-minutes: 30
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.generate-php-versions.outputs.php-versions) }}
env:
PHP_VERSION: ${{ matrix.php-version }}
steps:
- uses: actions/checkout@v4
- name: Invoke test_php_static_check.sh
run: ./tools/build/test_php_static_check.sh --php_versions "${PHP_VERSION}"
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#generated version file
# Generated files
prod/php/ElasticOTel/PhpPartVersion.php
prod/php/ElasticOTel/Log/LogFeature.php

Expand Down
36 changes: 13 additions & 23 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
},
"require-dev": {
"php-parallel-lint/php-console-highlighter": "^1.0",
"php-parallel-lint/php-parallel-lint": "1.3.2",
"phpstan/phpstan": "1.11.4",
"phpstan/phpstan-phpunit": "^1.3.15",
"phpunit/phpunit": "^9.6||^10.5",
"slevomat/coding-standard": "8.14.1",
"squizlabs/php_codesniffer": "3.8.1"
"php-parallel-lint/php-parallel-lint": "1.4.0",
"phpstan/phpstan": "2.0.2",
"phpstan/phpstan-phpunit": "^2.0.1",
"phpunit/phpunit": "^10.5",
"slevomat/coding-standard": "8.15.0",
"squizlabs/php_codesniffer": "3.11.1"
},
"autoload-dev": {
"psr-4": {
Expand All @@ -44,7 +44,8 @@
"sort-packages": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true,
"php-http/discovery": true
"php-http/discovery": true,
"tbachert/spi": true
}
},
"scripts": {
Expand All @@ -62,32 +63,21 @@
"phpcbf ./prod/php/",
"phpcbf ./tests/"
],
"fix_code_format_for": [
"phpcbf"
],
"phpstan-junit-report-for-ci": [
"phpstan analyse --error-format=junit ./prod/php/ --level max --memory-limit=1G | tee build/elastic-otel-phpstan-junit.xml",
"phpstan analyse --error-format=junit ./tests/ --level max --memory-limit=1G --error-format=junit | tee build/tests-phpstan-junit.xml"
],
"phpstan": [
"phpstan analyse ./prod/php/ --level max --memory-limit=1G",
"phpstan analyse ./tests/ --level max --memory-limit=1G"
"phpstan analyse ./prod/php/",
"phpstan analyse ./tests/"
],
"static_check": [
"composer run-script -- parallel-lint",
"composer run-script -- php_codesniffer_check",
"composer run-script -- phpstan"
],
"run_unit_tests": [
"phpunit"
],
"run_component_tests": [
"phpunit"
],
"run_tests": [
"composer run-script -- run_unit_tests",
"composer run-script -- run_component_tests"
],
"static_check_and_run_tests": [
"composer run-script -- static_check",
"composer run-script -- run_tests"
]
}
}
3 changes: 3 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@
</rule>

<!-- other sniffs to include -->

<exclude-pattern>*/prod/php/ElasticOTel/Log/LogFeature.php</exclude-pattern>
<exclude-pattern>*/prod/php/ElasticOTel/PhpPartVersion.php</exclude-pattern>
</ruleset>
11 changes: 3 additions & 8 deletions phpstan.dist.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@ includes:

parameters:
bootstrapFiles:
- tests/bootstrap.php
- ./tests/bootstrap.php

reportUnmatchedIgnoredErrors: false

ignoreErrors:
#
# elastic_otel_* functions are provided by the extension
#
- '#^Function elastic_otel_[a-z_]* not found\.$#'
level: max

reportUnmatchedIgnoredErrors: false
40 changes: 23 additions & 17 deletions prod/php/ElasticOTel/BootstrapStageLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@

use Throwable;

require __DIR__ . DIRECTORY_SEPARATOR . 'Log' . DIRECTORY_SEPARATOR . 'LogFeature.php';

/**
* Code in this file is part of implementation internals, and thus it is not covered by the backward compatibility.
*
Expand Down Expand Up @@ -94,15 +92,18 @@ public static function writeLineToStdErr(string $text): void
}
}

public static function nullableToLog(mixed $str): mixed
public static function nullableToLog(null|int|string $str): string
{
return $str === null ? 'null' : $str;
return $str === null ? 'null' : strval($str);
}

public static function configure(int $maxEnabledLevel, string $phpSrcCodeRootDir, string $rootNamespace): void
{
/** @noinspection PhpIncludeInspection */
require __DIR__ . DIRECTORY_SEPARATOR . 'Log' . DIRECTORY_SEPARATOR . 'LogFeature.php';

self::$maxEnabledLevel = $maxEnabledLevel;
if(is_int($pid = getmypid())) {
if (is_int($pid = getmypid())) {
self::$pid = $pid;
}

Expand All @@ -116,7 +117,10 @@ public static function configure(int $maxEnabledLevel, string $phpSrcCodeRootDir
. '; classNamePrefixToRemove: ' . self::$classNamePrefixToRemove
. '; maxEnabledLevel: ' . self::levelToString($maxEnabledLevel)
. '; pid: ' . self::nullableToLog(self::$pid),
__FILE__, __LINE__, __CLASS__, __FUNCTION__
__FILE__,
__LINE__,
__CLASS__,
__FUNCTION__
);
}

Expand Down Expand Up @@ -179,7 +183,10 @@ public static function logCriticalThrowable(Throwable $throwable, string $messag
$message . '.'
. ' ' . get_class($throwable) . ': ' . $throwable->getMessage()
. PHP_EOL . 'Stack trace:' . PHP_EOL . $throwable->getTraceAsString(),
$file, $line, $class, $func
$file,
$line,
$class,
$func
);
}

Expand All @@ -191,12 +198,12 @@ private static function isPrefixOf(string $prefix, string $text, bool $isCaseSen
}

return substr_compare(
$text /* <- haystack */,
$prefix /* <- needle */,
0 /* <- offset */,
$prefixLen /* <- length */,
!$isCaseSensitive /* <- case_insensitivity */
) === 0;
$text /* <- haystack */,
$prefix /* <- needle */,
0 /* <- offset */,
$prefixLen /* <- length */,
!$isCaseSensitive /* <- case_insensitivity */
) === 0;
}

private static function processSourceCodeFilePathForLog(string $file): string
Expand Down Expand Up @@ -232,13 +239,12 @@ private static function logWithLevel(int $statementLevel, string $message, strin
/**
* elastic_otel_* functions are provided by the extension
*
* @noinspection PhpFullyQualifiedNameUsageInspection, PhpUndefinedFunctionInspection
* @phpstan-ignore-next-line
* @noinspection PhpFullyQualifiedNameUsageInspection, PhpUndefinedClassInspection, PhpUndefinedFunctionInspection
*/
\elastic_otel_log_feature(
\elastic_otel_log_feature( // @phpstan-ignore function.notFound
0 /* $isForced */,
$statementLevel,
Log\LogFeature::BOOTSTRAP,
Log\LogFeature::BOOTSTRAP, // @phpstan-ignore class.notFound
self::LOG_CATEGORY,
self::processSourceCodeFilePathForLog($file),
$line,
Expand Down
49 changes: 49 additions & 0 deletions prod/php/ElasticOTel/ElasticOTelPhpPartVersion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

declare(strict_types=1);

namespace Elastic\OTel;

use Elastic\OTel\Util\StaticClassTrait;

/**
* Code in this file is part of implementation internals, and thus it is not covered by the backward compatibility.
*
* @internal
*/
final class ElasticOTelPhpPartVersion
{
use StaticClassTrait;

public static function get(): string
{
/**
* @var string $phpPartVersion
*
* Constant \Elastic\OTel\ELASTIC_OTEL_PHP_VERSION is defined in the generated file prod/php/ElasticOTel/PhpPartVersion.php
*
* @noinspection PhpUnnecessaryFullyQualifiedNameInspection, PhpUndefinedConstantInspection
*/
$phpPartVersion = \Elastic\OTel\ELASTIC_OTEL_PHP_VERSION; // @phpstan-ignore constant.notFound
return $phpPartVersion;
}
}
Loading

0 comments on commit 113e075

Please sign in to comment.