jbzoo / ci-report-converter
该工具可以将不同的错误报告标准转换为与流行的CI系统(TeamCity、IntelliJ IDEA、GitHub Actions等)深度融合
Requires
- php: ^8.1
- ext-dom: *
- ext-hash: *
- ext-simplexml: *
- jbzoo/cli: ^7.1.8
- jbzoo/data: ^7.1
- jbzoo/markdown: ^7.0
- jbzoo/utils: ^7.1
- symfony/console: >=6.4
Requires (Dev)
- jbzoo/mermaid-php: ^7.2
- jbzoo/toolbox-dev: ^7.1
- roave/security-advisories: dev-master
README
- 为什么?
- 安装
- 作为GitHub Action使用
- 可用方向
- 终端中的帮助描述
- 示例
- 贡献
- 许可证
- 另请参阅
为什么?
我相信你已经熟悉了各种测试、代码标准检查、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
可用方向
目前,报告转换支持以下格式
- 输入格式
- checkstyle - 最流行的错误报告类型。适用于Phan、PHPcs等。
- junit - 另一种非常流行的错误报告类型。通常,该格式用于显示单元测试结果。
- phpmd-json - 最详细的PHPMD报告。
- phpmnd - 我只知道 PHP Magic Numbers Detector。
- psalm-json - Psalm 的最详细报告。
- pmd-cpd - 这是 PMD-CPD XML 格式。一个示例工具是 Copy/Paste Detector。
- 输出格式
- gitlab-json - GitLab 自定义报告。
- junit - 最流行的报告方式。
- tc-tests - TeamCity/PhpStorm/JetBrains 中的测试报告。
- tc-inspections - TeamCity 中的检查报告。
此外,您可以通过 teamcity:stats
跟踪 TeamCity 中的代码指标。
- JUnit.xml > TeamCity 中的示例
- PHPUnitClover.xml > TeamCity 中的示例
- PHPDepend.xml > TeamCity 中的示例
- PHPloc.json > TeamCity 中的示例
- PHPMetrics.xml > 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 显示任何类型的风格问题。是的,我知道集成不是最干净的,也不算特别美观。然而,这段代码/截图展示了该方法的可用性。
注意:我认为编码风格问题与其他类型错误具有相同的严重程度。因此,我更愿意使用与常规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)
php ./vendor/bin/phpmd ./src json cleancode | ./ci-report-converter.phar -Sphpmd-json
Magic Number Detector(phpmnd)
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)
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)
php ./vendor/bin/phpstan analyse --error-format=checkstyle --no-progress ./src | ./ci-report-converter.phar
Psalm(psalm-json)
php ./vendor/bin/psalm --output-format=json | ./ci-report-converter.phar --input-format="psalm-json"
Phan(checkstyle)
php ./vendor/bin/phan.phar --directory=./src --output-mode=checkstyle | ./ci-report-converter.phar
TeamCity - 将样式问题视为失败的单元测试
使用选项--output-format=tc-tests
将任何风格报告转换为TeamCity的单元测试格式。
TeamCity - 将样式问题视为代码审查
使用选项--output-format=tc-inspections
将任何风格报告转换为TeamCity的单元测试格式。
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"
./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"
./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"
GitHub Actions
您可以在这里找到很多实际示例,并查看YML文件中的真实示例。
GitLab CI
使用选项--output-format=gitlab-json
将报告转换为Gitlab JSON格式。
还可以查看如何实现GitLab自定义报告。
将工具作为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 - 转换任何值和度量——货币、重量、汇率、长度等。