GithubActionReporter.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Console\CI;
  11. use Symfony\Component\Console\Output\OutputInterface;
  12. /**
  13. * Utility class for Github actions.
  14. *
  15. * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
  16. */
  17. class GithubActionReporter
  18. {
  19. /**
  20. * @var \Symfony\Component\Console\Output\OutputInterface
  21. */
  22. private $output;
  23. /**
  24. * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L80-L85
  25. */
  26. private const ESCAPED_DATA = [
  27. '%' => '%25',
  28. "\r" => '%0D',
  29. "\n" => '%0A',
  30. ];
  31. /**
  32. * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L87-L94
  33. */
  34. private const ESCAPED_PROPERTIES = [
  35. '%' => '%25',
  36. "\r" => '%0D',
  37. "\n" => '%0A',
  38. ':' => '%3A',
  39. ',' => '%2C',
  40. ];
  41. /**
  42. * @param \Symfony\Component\Console\Output\OutputInterface $output
  43. */
  44. public function __construct($output)
  45. {
  46. $this->output = $output;
  47. }
  48. public static function isGithubActionEnvironment()
  49. {
  50. return false !== getenv('GITHUB_ACTIONS');
  51. }
  52. /**
  53. * Output an error using the Github annotations format.
  54. *
  55. * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
  56. * @param string $message
  57. * @param string|null $file
  58. * @param int|null $line
  59. * @param int|null $col
  60. */
  61. public function error($message, $file = null, $line = null, $col = null)
  62. {
  63. $this->log('error', $message, $file, $line, $col);
  64. }
  65. /**
  66. * Output a warning using the Github annotations format.
  67. *
  68. * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message
  69. * @param string $message
  70. * @param string|null $file
  71. * @param int|null $line
  72. * @param int|null $col
  73. */
  74. public function warning($message, $file = null, $line = null, $col = null)
  75. {
  76. $this->log('warning', $message, $file, $line, $col);
  77. }
  78. /**
  79. * Output a debug log using the Github annotations format.
  80. *
  81. * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message
  82. * @param string $message
  83. * @param string|null $file
  84. * @param int|null $line
  85. * @param int|null $col
  86. */
  87. public function debug($message, $file = null, $line = null, $col = null)
  88. {
  89. $this->log('debug', $message, $file, $line, $col);
  90. }
  91. /**
  92. * @param string $type
  93. * @param string $message
  94. * @param string|null $file
  95. * @param int|null $line
  96. * @param int|null $col
  97. */
  98. private function log($type, $message, $file = null, $line = null, $col = null)
  99. {
  100. // Some values must be encoded.
  101. $message = strtr($message, self::ESCAPED_DATA);
  102. if (!$file) {
  103. // No file provided, output the message solely:
  104. $this->output->writeln(sprintf('::%s::%s', $type, $message));
  105. return;
  106. }
  107. $this->output->writeln(sprintf('::%s file=%s,line=%s,col=%s::%s', $type, strtr($file, self::ESCAPED_PROPERTIES), strtr($line ?? 1, self::ESCAPED_PROPERTIES), strtr($col ?? 0, self::ESCAPED_PROPERTIES), $message));
  108. }
  109. }