jbzoo/ci-report-converter

该工具可以将不同的错误报告标准转换为与流行的CI系统(TeamCity、IntelliJ IDEA、GitHub Actions等)深度融合

7.2.1 2024-01-28 14:03 UTC

README

CI Coverage Status Psalm Coverage Psalm Level CodeFactor
Stable Version Total Downloads Docker Pulls Dependents GitHub License

为什么?

我相信你已经熟悉了各种测试、代码标准检查、linters等工具的庞大动物园。这些工具的输出通常不被流行的CI系统(TeamCity、GitHub等)支持。如果你使用的工具将错误报告保存为junit.xml格式,那么它几乎可以与所有现代开发软件很好地工作。

但是...我的经验告诉我,这只是一般情况,并不是规则。例如,我真的非常喜欢老式的phpmd工具(也许你对它的好处有另一种看法。至少,这只是一个例子)。它与TeamCity/PhpStorm/GitHub的集成并不好。每次我都要花费大量时间在日志中查找结果。尽管我真的想看到即时且打印良好的错误报告。

因此,我开发了一个转换器,它改变报告格式,以与CI系统和JetBrain IDE深度集成。

嗯...这可能在你看来是个无用的东西,而你最喜欢的超级工具在TeamCity/PhpStorm上运行得很好。只需看看下面的示例

安装

composer require jbzoo/ci-report-converter
php ./vendor/bin/ci-report-converter --help

# OR use phar file
wget https://github.com/JBZoo/CI-Report-Converter/releases/latest/download/ci-report-converter.phar
chmod +x ./ci-report-converter.phar
./ci-report-converter.phar --help

# OR just pull the Docker Image
docker run --rm jbzoo/ci-report-converter --help

作为GitHub Action使用

操作允许您将错误报告转换为GitHub注释格式

- uses: jbzoo/ci-report-converter@master # or see the specific version on releases page
  with:
    # File path with the original report format. If not set or empty, then the STDIN is used.
    # Required: true
    input-file: ./build/checkstyle.xml

    # Source format. Available options: checkstyle, junit, phpmd-json, phpmnd, pmd-cpd, psalm-json
    # Default value: checkstyle
    # Required: true
    input-format: checkstyle

    # Will exit with the code=1, if any violations are found.
    # Default value: no
    non-zero-code: yes

    # File path with the result report format. If not set or empty, then the STDOUT is used.
    output-file: ./build/junit.xml

    # Target format. Available options: gitlab-json, github-cli, junit, plain, tc-inspections, tc-tests
    # Default value: github-cli
    # Required: true
    output-format: junit

    # If option is set, all absolute file paths will be converted to relative once.
    # Default value: .
    root-path: ./custom/project/path

    # Set custom name of root group/suite (if it's possible).
    # Required: true
    suite-name: My Tests

示例GitHub Action工作流程

name: Linters

on:
  pull_request:
    branches:
      - "*"

jobs:
  linters:
    name: PHPcs
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v2

      - name: PHP Code Sniffer
        run: ./vendor/bin/phpcs --report=checkstyle --standard=PSR12 -q ./src > ./build/phpcs-checkstyle.xml

      - name: Converting checkstyle.xml to Github Annotations
        uses: jbzoo/ci-report-converter@master
        with:
          input-file: build/phpcs-checkstyle.xml

可用方向

目前,报告转换支持以下格式

此外,您可以通过 teamcity:stats 跟踪 TeamCity 中的代码指标

终端中的帮助描述

转换

$ php ./vendor/bin/ci-report-converter convert --help
Description:
  Convert one report format to another one

Usage:
  convert [options]

Options:
  -S, --input-format=INPUT-FORMAT      Source format. Available options: checkstyle, junit, phpmd-json, phpmnd, pmd-cpd, psalm-json [default: "checkstyle"]
  -I, --input-file[=INPUT-FILE]        File path with the original report format. If not set or empty, then the STDIN is used.
  -T, --output-format=OUTPUT-FORMAT    Target format. Available options: gitlab-json, github-cli, junit, plain, tc-inspections, tc-tests [default: "tc-tests"]
  -O, --output-file[=OUTPUT-FILE]      File path with the result report format. If not set or empty, then the STDOUT is used.
  -R, --root-path[=ROOT-PATH]          If option is set, all absolute file paths will be converted to relative once. [default: "."]
  -N, --suite-name=SUITE-NAME          Set custom name of root group/suite (if it's possible).
  -F, --tc-flow-id[=TC-FLOW-ID]        Custom flowId in TeamCity output. Default value is PID of the tool.
  -Q, --non-zero-code[=NON-ZERO-CODE]  Will exit with the code=1, if any violations are found. [default: "no"]
      --no-progress                    Disable progress bar animation for logs. It will be used only for text output format.
      --mute-errors                    Mute any sort of errors. So exit code will be always "0" (if it's possible).
                                       It has major priority then --non-zero-on-error. It's on your own risk!
      --stdout-only                    For any errors messages application will use StdOut instead of StdErr. It's on your own risk!
      --non-zero-on-error              None-zero exit code on any StdErr message.
      --timestamp                      Show timestamp at the beginning of each message.It will be used only for text output format.
      --profile                        Display timing and memory usage information.
      --output-mode=OUTPUT-MODE        Output format. Available options:
                                       text - Default text output format, userfriendly and easy to read.
                                       cron - Shortcut for crontab. It's basically focused on human-readable logs output.
                                       It's combination of --timestamp --profile --stdout-only --no-progress -vv.
                                       logstash - Logstash output format, for integration with ELK stack.
                                        [default: "text"]
      --cron                           Alias for --output-mode=cron. Deprecated!
  -h, --help                           Display help for the given command. When no command is given display help for the list command
  -q, --quiet                          Do not output any message
  -V, --version                        Display this application version
      --ansi|--no-ansi                 Force (or disable --no-ansi) ANSI output
  -n, --no-interaction                 Do not ask any interactive question
  -v|vv|vvv, --verbose                 Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

TeamCity中的自定义指标

为了澄清方法的用法,请查看下面的 示例和截图

$ php ./vendor/bin/ci-report-converter teamcity:stats --help
Description:
  Push code metrics to TeamCity Stats

Usage:
  teamcity:stats [options]

Options:
  -S, --input-format=INPUT-FORMAT  Source format. Available options: junit-xml, pdepend-xml, phploc-json, phpmetrics-xml, phpunit-clover-xml
  -I, --input-file[=INPUT-FILE]    File path with the original report format. If not set or empty, then the STDIN is used.
  -O, --output-file[=OUTPUT-FILE]  File path with the result report format. If not set or empty, then the STDOUT is used.
  -R, --root-path[=ROOT-PATH]      If option is set, all absolute file paths will be converted to relative once. [default: "."]
  -F, --tc-flow-id[=TC-FLOW-ID]    Custom flowId in TeamCity output. Default value is PID of the tool.
      --no-progress                Disable progress bar animation for logs. It will be used only for text output format.
      --mute-errors                Mute any sort of errors. So exit code will be always "0" (if it's possible).
                                   It has major priority then --non-zero-on-error. It's on your own risk!
      --stdout-only                For any errors messages application will use StdOut instead of StdErr. It's on your own risk!
      --non-zero-on-error          None-zero exit code on any StdErr message.
      --timestamp                  Show timestamp at the beginning of each message.It will be used only for text output format.
      --profile                    Display timing and memory usage information.
      --output-mode=OUTPUT-MODE    Output format. Available options:
                                   text - Default text output format, userfriendly and easy to read.
                                   cron - Shortcut for crontab. It's basically focused on human-readable logs output.
                                   It's combination of --timestamp --profile --stdout-only --no-progress -vv.
                                   logstash - Logstash output format, for integration with ELK stack.
                                    [default: "text"]
      --cron                       Alias for --output-mode=cron. Deprecated!
  -h, --help                       Display help for the given command. When no command is given display help for the list command
  -q, --quiet                      Do not output any message
  -V, --version                    Display this application version
      --ansi|--no-ansi             Force (or disable --no-ansi) ANSI output
  -n, --no-interaction             Do not ask any interactive question
  -v|vv|vvv, --verbose             Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

示例

JetBrains IDE(IntelliJ IDEA、PhpStorm、WebStorm等)

该工具的独特功能之一是将报告转换为与 JetBrains IDE 和 TeamCity 兼容的单元测试格式。以下示例展示了如何使用 JetBrains IDE UI 显示任何类型的风格问题。是的,我知道集成不是最干净的,也不算特别美观。然而,这段代码/截图展示了该方法的可用性。

PHPcs in JetBrains PhpStorm

注意:我认为编码风格问题与其他类型错误具有相同的严重程度。因此,我更愿意使用与常规PHPUnit测试相同的流程来检查代码的质量。就像“一键操作”!此外,您还将获得一个惊人的额外奖励——导航项目并获取有关错误的详细信息。

总体思路相当简单

  • 我们几乎使用任何测试工具。
  • 它将报告保存到文件或以xml/json格式输出错误到StdOut。
  • CI-Report-Converter更改报告格式。它将结果保存到某个地方或直接在StdOut中输出。
  • ???
  • 获利。

在下一个示例中,我们将看到如何将JetBrains IDE UI与Code Sniffer深度集成。我以PHPcs为例。这是PHP中最受欢迎的代码检查器。然而,这种方法与编程语言或单元测试框架无关。

<?php declare(strict_types=1);

use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase;

/**
 * Here's an example based on PHPUnit and PhpStorm, but you are not limited to PHP language.
 * This is just an example to show the idea.
 * So you can use any sort language to integrate style tests with JetBrains IDE.
 */
class CheckStyleExamplesTest extends TestCase
{
    /**
     * The short example which uses pipe as way to pass error report.
     */
    public function testPipelineWay(): void
    {
        echo shell_exec(                       # Execute command via shell and return the complete output as a string.
            'php ./vendor/bin/phpcs' .         # Path to bin of third-party tool (PHP Code Sniffer is just example).
            ' --report=checkstyle' .           # Output format of PHPcs. ci-report-converter expects it by default as `--input-format` option.
            ' --standard=PSR12 -q ./src' .     # The custom tool options. For phpcs `-q` is important!
            ' | ' .                            # The pipe operator, it passes the output of one command as input to another. See https://en.wikipedia.org/wiki/Pipeline_(Unix)
            ' ./ci-report-converter.phar'      # The converter does all the magic. Look at help description ( --help) to lean more about options and default values.
        );

        # Usually PHPUnit expects at least one assert in a test.
        # Otherwise, it may show useless warning messages. It depends on PHPUnit version and your configurations.
        # So, just in case, we make a fake assertion.
        Assert::assertTrue(true);
    }

    /**
     * The super detailed example which uses files as way to pass error report.
     */
    public function testXmlFileWay(): void
    {
        shell_exec(                                     # Execute command via shell and return the complete output as a string.
            'php ./vendor/bin/phpcs' .                  # Path to bin of third-party tool (PHP Code Sniffer is just example).
            ' --report=checkstyle' .                    # Output format of PHPcs. CI-Report-Converter expects it by default as `--input-format` option.
            ' --report-file=./build/phpcs-report.xml' . # Save result of phpcs work in XML file in "checkstyle" format.
            ' --standard=PSR12 -q ./src' .              # The custom tool options. For phpcs `-q` is important!
            ' || true > /dev/null'                      # We don't expect any output of phpcs and ignore error exit codes.
                                                        # Lol, we are very self-confident. Actually, we need only XML file, that's it.
        );

        // I've shown all the options explicitly just to add transparency.
        // In fact, this example does the same thing as the code above in `testPipelineWay()`.
        echo shell_exec(
            './ci-report-converter.phar' .              # The path to bin file of CI-Report-Converter. It depends of your installation way. See above.
            ' --input-format=checkstyle' .              # Source reporting format. Default value is "checkstyle".
            ' --input-file=./build/phpcs-report.xml' .  # Using prepared file on previous step as source.
            ' --output-format=tc-tests' .               # Target reporting format. Default value is "tc-tests".
            ' --suite-name=PHPcs' .                     # Define the name of group. See screenshot below.
            ' --root-path=`pwd`'                        # Specify the project path for pretty printing paths in UI. Default value is `.` (current dir).
        );

        # The same reason like in `testPipelineWay()`.
        Assert::assertTrue(true);
    }
}

内部发生了什么。还可以查看源文件作为现成的示例

cd  ~/your/project/root/directory
php ./vendor/bin/phpunit ./tests/examples/CheckStyleExamples.php --teamcity

# or
php ./vendor/bin/phpcs --report=checkstyle --standard=PSR12 -q ./src | ./ci-report-converter.phar

Mess Detector(phpmd-json)

屏幕截图

PHPmd in JetBrains PhpStorm

php ./vendor/bin/phpmd ./src json cleancode | ./ci-report-converter.phar -Sphpmd-json

Magic Number Detector(phpmnd)

屏幕截图

PHPmd in JetBrains PhpStorm

php ./vendor/bin/phpmnd ./src --hint --quiet --xml-output=./build/phpmnd-report.xml
./ci-report-converter.phar --root-path=./src --input-file=./build/phpmnd-report.xml --input-format=phpmnd

复制/粘贴检测器(pmd-cpd)

屏幕截图

PHPcpd in JetBrains PhpStorm

php ./vendor/bin/phpcpd ./src --log-pmd=./build/phpcpd-report.xml
./ci-report-converter.phar --input-file=./build/phpcpd-report.xml --input-format=pmd-cpd

PHPStan(checkstyle)

屏幕截图

PHPstan in JetBrains PhpStorm

php ./vendor/bin/phpstan analyse --error-format=checkstyle --no-progress ./src | ./ci-report-converter.phar

Psalm(psalm-json)

屏幕截图

PHP Psalm in JetBrains PhpStorm

php ./vendor/bin/psalm --output-format=json | ./ci-report-converter.phar --input-format="psalm-json"

Phan(checkstyle)

屏幕截图

PHP Psalm in JetBrains PhpStorm

php ./vendor/bin/phan.phar --directory=./src --output-mode=checkstyle |  ./ci-report-converter.phar

TeamCity - 将样式问题视为失败的单元测试

使用选项--output-format=tc-tests将任何风格报告转换为TeamCity的单元测试格式。

Style issues as failed tests in TeamCity

TeamCity - 将样式问题视为代码审查

使用选项--output-format=tc-inspections将任何风格报告转换为TeamCity的单元测试格式。

Style Issue As Code Inspections in TeamCity

TeamCity - 报告的统计值

PHPDepend.xml > TeamCity 中的示例

./vendor/bin/pdepend.phar --summary-xml="./build/pdepend-summary.xml" --quiet ./src
./ci-report-converter.phar teamcity:stats --input-format="pdepend-xml" --input-file="./build/pdepend-summary.xml"

PHPloc.json > TeamCity 中的示例

./vendor/bin/phploc ./src --log-json="./build/phploc.json" --quiet
./ci-report-converter.phar teamcity:stats --input-format="phploc-json" --input-file="./build/phploc.json"

PHPUnitClover.xml > TeamCity 中的示例

./vendor/bin/phpunit --coverage-clover ./build/phpunit-report.xml
./ci-report-converter.phar teamcity:stats --input-format="phpunit-clover-xml" --input-file="./build/phpunit-report.xml"

JUnit.xml > TeamCity 中的示例

./vendor/bin/phpunit --coverage-xml ./build/phpunit-junit.xml
./ci-report-converter.phar teamcity:stats --input-format="junit-xml" --input-file="./build/phpunit-junit.xml"

PHPMetrics.xml > TeamCity 中的示例

./vendor/bin/phpmetrics  ./src --report-violations="./build/phpmetrics-report.xml"
./ci-report-converter.phar teamcity:stats --input-format="phpmetrics-xml" --input-file="./build/phpmetrics-report.xml"

Style issues as failed tests in TeamCity

GitHub Actions

您可以在这里找到很多实际示例,并查看YML文件中的真实示例

GitHub Actions 1

GitHub Actions 1

GitLab CI

使用选项--output-format=gitlab-json将报告转换为Gitlab JSON格式。

还可以查看如何实现GitLab自定义报告

GitLab Code Quality Report

将工具作为SDK生成报告

此外,您还可以将工具的源代码用作您工具/项目的报告SDK。

PS:更多示例即将推出。

JUnit.xml(API)

use JBZoo\CIReportConverter\Converters\JUnitConverter;
use JBZoo\CIReportConverter\Formats\Source\SourceCaseOutput;
use JBZoo\CIReportConverter\Formats\Source\SourceSuite;

$class = \JBZoo\PHPUnit\ExampleTest::class;
$className = str_replace('\\', '.', $class);
$filename = './tests/ExampleTest.php';
$line = 28;

$suite = new SourceSuite('Suite');
$case = $suite->addTestCase('Test Name');
$case->time = 0.001824;
$case->file = $filename;
$case->line = $line;
$case->class = $class;
$case->classname = $className;
$case->assertions = 5;
$case->stdOut = 'Some std output';
$case->errOut = 'Some err output';
$case->failure = new SourceCaseOutput('Failure', 'Failure Message', 'Failure Details');
$case->error = new SourceCaseOutput('Error', 'Error Message', 'Error Details');
$case->warning = new SourceCaseOutput('Warning', 'Warning Message', 'Warning Details');
$case->skipped = new SourceCaseOutput('Skipped', 'Skipped Message', 'Skipped Details');

echo (new JUnitConverter())->fromInternal($suite);
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
  <testsuite name="Suite" tests="1" assertions="5" errors="1" warnings="1" failures="1" skipped="1" time="0.001824">
    <testcase name="Test Name" class="JBZoo\PHPUnit\ExampleTest" classname="JBZoo.PHPUnit.ExampleTest" file="./tests/ExampleTest.php" line="28" assertions="5" time="0.001824">
      <failure type="Failure" message="Failure Message">Failure Details</failure>
      <warning type="Warning" message="Warning Message">Warning Details</warning>
      <error type="Error" message="Error Message">Error Details</error>
      <system-out>Some std output
Some err output</system-out>
      <skipped/>
    </testcase>
  </testsuite>
</testsuites>

GitHub Actions(API)

use JBZoo\CIReportConverter\Formats\GithubActions\GithubActions;

$ghActions = new GithubActions();
$case0 = $ghActions->addCase('src/Root.php');
$case0->line = 789;
$case0->column = null;
$case0->message = 'Something went wrong #0';

$suite1 = $ghActions->addSuite('src/File.php');
$case1 = $suite1->addCase('src/Class.php');
$case1->line = 123;
$case1->column = 4;
$case1->message = 'Something went wrong #1';

echo $ghActions->__toString();
::error file=src/Root.php,line=789::Something went wrong #0

::group::src/File.php
::error file=src/Class.php,line=123,col=4::Something went wrong #1
::endgroup::

贡献

# Fork the repo and build project
make build

# Make your local changes

# Run all tests and check code style
make test
make codestyle

# Create your pull request and check all tests in CI

许可证

MIT

另请参阅

  • Composer-Diff - 查看composer update后包发生了什么变化。
  • Composer-Graph - 基于mermaid-js的composer.json依赖关系图可视化。
  • Mermaid-PHP - 使用mermaid脚本语言生成图表和流程图。
  • Utils - 收集有用的PHP函数、迷你类和代码片段,供日常使用。
  • Image - 提供面向对象的方式操作图像,尽可能简单。
  • Data - 扩展实现ArrayObject。使用文件作为配置/数组。
  • Retry - 提供多种回退策略和抖动支持的PHP库,提供重试/回退功能。
  • SimpleTypes - 转换任何值和度量——货币、重量、汇率、长度等。