From f0b00fd201c7ddf14e1572a10d5fb4577c4bd6a2 Mon Sep 17 00:00:00 2001 From: Luke Tomlinson Date: Wed, 28 Jul 2021 17:34:31 -0400 Subject: [PATCH] Add notice annotation and support more annotation fields (#855) * Add support for notice annotation and additional properties * Add additional tests * Update readme * Change casing for endLine and endColumn * Update utils.ts * Update README.md * Rename files to have internal- nomenclature * Revert "Rename files to have internal- nomenclature" This reverts commit 7911689f296f7e630ac6670334dd677d9db3fb1c. * Update utils.ts --- docs/assets/annotations.png | Bin 0 -> 46675 bytes docs/problem-matchers.md | 2 +- packages/core/README.md | 50 ++++++++++++++++++ packages/core/__tests__/core.test.ts | 47 +++++++++++++++++ packages/core/src/command.ts | 2 +- packages/core/src/core.ts | 76 ++++++++++++++++++++++++--- packages/core/src/utils.ts | 25 +++++++++ 7 files changed, 194 insertions(+), 8 deletions(-) create mode 100644 docs/assets/annotations.png diff --git a/docs/assets/annotations.png b/docs/assets/annotations.png new file mode 100644 index 0000000000000000000000000000000000000000..f21002209020a801a7e555a988f2cde54b6eb70d GIT binary patch literal 46675 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 literal 0 HcmV?d00001 diff --git a/docs/problem-matchers.md b/docs/problem-matchers.md index 520d26ba..e496b299 100644 --- a/docs/problem-matchers.md +++ b/docs/problem-matchers.md @@ -6,7 +6,7 @@ Problem Matchers are a way to scan the output of actions for a specified regex p Currently, GitHub Actions limit the annotation count in a workflow run. -- 10 warning annotations and 10 error annotations per step +- 10 warning annotations, 10 error annotations, and 10 notice annotations per step - 50 annotations per job (sum of annotations from all the steps) - 50 annotations per run (separate from the job annotations, these annotations aren’t created by users) diff --git a/packages/core/README.md b/packages/core/README.md index deffaa5d..6681502d 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -92,6 +92,8 @@ try { // Do stuff core.info('Output to the actions build log') + + core.notice('This is a message that will also emit an annotation') } catch (err) { core.error(`Error ${err}, action may still succeed though`); @@ -115,6 +117,54 @@ const result = await core.group('Do something async', async () => { }) ``` +#### Annotations + +This library has 3 methods that will produce [annotations](https://docs.github.com/en/rest/reference/checks#create-a-check-run). +```js +core.error('This is a bad error. This will also fail the build.') + +core.warning('Something went wrong, but it\'s not bad enough to fail the build.') + +core.notice('Something happened that you might want to know about.') +``` + +These will surface to the UI in the Actions page and on Pull Requests. They look something like this: + +![Annotations Image](../../docs/assets/annotations.png) + +These annotations can also be attached to particular lines and columns of your source files to show exactly where a problem is occuring. + +These options are: +```typescript +export interface AnnotationProperties { + /** + * A title for the annotation. + */ + title?: string + + /** + * The start line for the annotation. + */ + startLine?: number + + /** + * The end line for the annotation. Defaults to `startLine` when `startLine` is provided. + */ + endLine?: number + + /** + * The start column for the annotation. Cannot be sent when `startLine` and `endLine` are different values. + */ + startColumn?: number + + /** + * The start column for the annotation. Cannot be sent when `startLine` and `endLine` are different values. + * Defaults to `startColumn` when `startColumn` is provided. + */ + endColumn?: number +} +``` + #### Styling output Colored output is supported in the Action logs via standard [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code). 3/4 bit, 8 bit and 24 bit colors are all supported. diff --git a/packages/core/__tests__/core.test.ts b/packages/core/__tests__/core.test.ts index 5be8df4e..f5ccec3b 100644 --- a/packages/core/__tests__/core.test.ts +++ b/packages/core/__tests__/core.test.ts @@ -2,6 +2,7 @@ import * as fs from 'fs' import * as os from 'os' import * as path from 'path' import * as core from '../src/core' +import {toCommandProperties} from '../src/utils' /* eslint-disable @typescript-eslint/unbound-method */ @@ -269,6 +270,20 @@ describe('@actions/core', () => { assertWriteCalls([`::error::Error: ${message}${os.EOL}`]) }) + it('error handles parameters correctly', () => { + const message = 'this is my error message' + core.error(new Error(message), { + title: 'A title', + startColumn: 1, + endColumn: 2, + startLine: 5, + endLine: 5 + }) + assertWriteCalls([ + `::error title=A title,line=5,endLine=5,col=1,endColumn=2::Error: ${message}${os.EOL}` + ]) + }) + it('warning sets the correct message', () => { core.warning('Warning') assertWriteCalls([`::warning::Warning${os.EOL}`]) @@ -285,6 +300,38 @@ describe('@actions/core', () => { assertWriteCalls([`::warning::Error: ${message}${os.EOL}`]) }) + it('warning handles parameters correctly', () => { + const message = 'this is my error message' + core.warning(new Error(message), { + title: 'A title', + startColumn: 1, + endColumn: 2, + startLine: 5, + endLine: 5 + }) + assertWriteCalls([ + `::warning title=A title,line=5,endLine=5,col=1,endColumn=2::Error: ${message}${os.EOL}` + ]) + }) + + it('annotations map field names correctly', () => { + const commandProperties = toCommandProperties({ + title: 'A title', + startColumn: 1, + endColumn: 2, + startLine: 5, + endLine: 5 + }) + expect(commandProperties.title).toBe('A title') + expect(commandProperties.col).toBe(1) + expect(commandProperties.endColumn).toBe(2) + expect(commandProperties.line).toBe(5) + expect(commandProperties.endLine).toBe(5) + + expect(commandProperties.startColumn).toBeUndefined() + expect(commandProperties.startLine).toBeUndefined() + }) + it('startGroup starts a new group', () => { core.startGroup('my-group') assertWriteCalls([`::group::my-group${os.EOL}`]) diff --git a/packages/core/src/command.ts b/packages/core/src/command.ts index 05e1261a..2796fce9 100644 --- a/packages/core/src/command.ts +++ b/packages/core/src/command.ts @@ -6,7 +6,7 @@ import {toCommandValue} from './utils' // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ -interface CommandProperties { +export interface CommandProperties { [key: string]: any } diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts index c5c36fa4..e57d9f15 100644 --- a/packages/core/src/core.ts +++ b/packages/core/src/core.ts @@ -1,6 +1,6 @@ import {issue, issueCommand} from './command' import {issueCommand as issueFileCommand} from './file-command' -import {toCommandValue} from './utils' +import {toCommandProperties, toCommandValue} from './utils' import * as os from 'os' import * as path from 'path' @@ -31,6 +31,38 @@ export enum ExitCode { Failure = 1 } +/** + * Optional properties that can be sent with annotatation commands (notice, error, and warning) + * See: https://docs.github.com/en/rest/reference/checks#create-a-check-run for more information about annotations. + */ +export interface AnnotationProperties { + /** + * A title for the annotation. + */ + title?: string + + /** + * The start line for the annotation. + */ + startLine?: number + + /** + * The end line for the annotation. Defaults to `startLine` when `startLine` is provided. + */ + endLine?: number + + /** + * The start column for the annotation. Cannot be sent when `startLine` and `endLine` are different values. + */ + startColumn?: number + + /** + * The start column for the annotation. Cannot be sent when `startLine` and `endLine` are different values. + * Defaults to `startColumn` when `startColumn` is provided. + */ + endColumn?: number +} + //----------------------------------------------------------------------- // Variables //----------------------------------------------------------------------- @@ -199,17 +231,49 @@ export function debug(message: string): void { /** * Adds an error issue * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. */ -export function error(message: string | Error): void { - issue('error', message instanceof Error ? message.toString() : message) +export function error( + message: string | Error, + properties: AnnotationProperties = {} +): void { + issueCommand( + 'error', + toCommandProperties(properties), + message instanceof Error ? message.toString() : message + ) } /** - * Adds an warning issue + * Adds a warning issue * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. */ -export function warning(message: string | Error): void { - issue('warning', message instanceof Error ? message.toString() : message) +export function warning( + message: string | Error, + properties: AnnotationProperties = {} +): void { + issueCommand( + 'warning', + toCommandProperties(properties), + message instanceof Error ? message.toString() : message + ) +} + +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +export function notice( + message: string | Error, + properties: AnnotationProperties = {} +): void { + issueCommand( + 'notice', + toCommandProperties(properties), + message instanceof Error ? message.toString() : message + ) } /** diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 2f1d60ce..8596b5f4 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -1,6 +1,9 @@ // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ +import {AnnotationProperties} from './core' +import {CommandProperties} from './command' + /** * Sanitizes an input into a string so it can be passed into issueCommand safely * @param input input to sanitize into a string @@ -13,3 +16,25 @@ export function toCommandValue(input: any): string { } return JSON.stringify(input) } + +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +export function toCommandProperties( + annotationProperties: AnnotationProperties +): CommandProperties { + if (!Object.keys(annotationProperties).length) { + return {} + } + + return { + title: annotationProperties.title, + line: annotationProperties.startLine, + endLine: annotationProperties.endLine, + col: annotationProperties.startColumn, + endColumn: annotationProperties.endColumn + } +}