| | | 1 | | import type { ILogger } from '../../domain/ports/ILogger.js'; |
| | | 2 | | |
| | | 3 | | /** |
| | | 4 | | * Logger for the GitHub Actions runner, which reads every output line as a |
| | | 5 | | * possible workflow command. Messages can carry input-derived text (file |
| | | 6 | | * names, secret references), so each one is written as a single inert line: |
| | | 7 | | * otherwise a value such as `x\n::stop-commands::t` would switch off command |
| | | 8 | | * processing before the `::add-mask::` registrations that follow. |
| | | 9 | | */ |
| | | 10 | | export class GitHubActionsLogger implements ILogger { |
| | 42 | 11 | | constructor(private readonly inner: ILogger) {} |
| | | 12 | | |
| | | 13 | | info(message: string): void { |
| | 44 | 14 | | this.inner.info(toInertLine(message)); |
| | | 15 | | } |
| | | 16 | | |
| | | 17 | | warn(message: string): void { |
| | 1 | 18 | | this.inner.warn(toInertLine(message)); |
| | | 19 | | } |
| | | 20 | | |
| | | 21 | | error(message: string): void { |
| | 29 | 22 | | this.inner.error(toInertLine(message)); |
| | | 23 | | } |
| | | 24 | | } |
| | | 25 | | |
| | | 26 | | function toInertLine(message: string): string { |
| | 74 | 27 | | return ( |
| | | 28 | | message |
| | | 29 | | .replace(/\r/g, '\\r') |
| | | 30 | | .replace(/\n/g, '\\n') |
| | | 31 | | // Legacy `##[command]` syntax is recognized anywhere in a line. |
| | | 32 | | .replace(/##\[/g, '#\\#[') |
| | | 33 | | // `::command::` is recognized at the start, after whitespace as .NET |
| | | 34 | | // TrimStart sees it, which also includes NEL (U+0085). |
| | | 35 | | .replace(/^([\s\u0085]*)::/, '$1\\::') |
| | | 36 | | ); |
| | | 37 | | } |