Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

## HEAD (Unreleased)

**(none)**
- feat: strip ansi control characters from pull request comment
([#1231](https://github.com/pulumi/actions/pull/1231))

---

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ The action can be configured with the following arguments:
`true`. This is in an effort to reduce verbosity - if you want to have a
comment per PR run, please ensure that you set this to `false`.

- `comment-max-character` - (optional) Maximum number of characters of the Pulumi
Comment thread
jmrt47 marked this conversation as resolved.
Outdated
action result to be added to the PR. Default value is 64000.

- `expect-no-changes` - (optional) Return an error if any changes occur during
this update.

Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ inputs:
description: 'If true, a comment on the GitHub step summary will be created'
required: false
default: 'false'
comment-max-character:
description: 'Maximum number of characters of output added to the PR.'
required: false
default: "64000"
github-token:
description: 'Github Token'
required: false
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@actions/tool-cache": "^2.0.1",
"@pulumi/pulumi": "3.109.0",
"actions-parsers": "^1.0.2",
"ansi-to-html": "^0.7.2",
"dedent": "^0.7.0",
"envalid": "^7.3.1",
"got": "^11.8.6",
Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const defaultConfig: Record<string, string> = {
'pulumi-version': '^3',
'comment-on-pr': 'false',
'comment-on-summary': 'false',
'comment-max-character': '64000',
upsert: 'false',
remove: 'false',
refresh: 'false',
Expand Down Expand Up @@ -41,6 +42,7 @@ describe('config.ts', () => {
Object {
"cloudUrl": "file://~",
"command": "up",
"commentMaxCharacter": 64000,
"commentOnPr": false,
"commentOnPrNumber": undefined,
"commentOnSummary": false,
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export function makeConfig() {
commentOnPr: getBooleanInput('comment-on-pr'),
commentOnPrNumber: getNumberInput('comment-on-pr-number', {}),
commentOnSummary: getBooleanInput('comment-on-summary'),
commentMaxCharacter: getNumberInput('comment-max-character'),
upsert: getBooleanInput('upsert'),
remove: getBooleanInput('remove'),
refresh: getBooleanInput('refresh'),
Expand Down
30 changes: 25 additions & 5 deletions src/libs/__tests__/pr.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as gh from '@actions/github';
import gh from '@actions/github';
import { Config } from '../../config';
import { handlePullRequestMessage } from '../pr';

Expand All @@ -13,6 +13,7 @@ const projectName = 'myFirstProject';
const defaultOptions = {
command: 'preview',
stackName: 'staging',
commentMaxCharacter: 64000,
options: {},
} as Config;
const createComment = jest.fn();
Expand Down Expand Up @@ -50,7 +51,26 @@ describe('pr.ts', () => {

await handlePullRequestMessage(defaultOptions, projectName, 'test');
expect(createComment).toHaveBeenCalledWith({
body: '#### :tropical_drink: `preview` on myFirstProject/staging\n\n<details>\n<summary>Pulumi report</summary>\n\n```\ntest\n```\n\n</details>',
body: '#### :tropical_drink: `preview` on myFirstProject/staging\n\n<details>\n<summary>Pulumi report</summary>\n\n<pre>\ntest\n</pre>\n\n</details>',
issue_number: 123,
});
});

it('should convert ansi controll character to html and add to pull request message', async () => {
Comment thread
jmrt47 marked this conversation as resolved.
Outdated
// @ts-ignore
gh.context = {
payload: {
pull_request: {
number: 123,
},
},
};

process.env.GITHUB_REPOSITORY = 'pulumi/actions';

await handlePullRequestMessage(defaultOptions, projectName, '\x1b[30mblack\x1b[37mwhite');
expect(createComment).toHaveBeenCalledWith({
body: '#### :tropical_drink: `preview` on myFirstProject/staging\n\n<details>\n<summary>Pulumi report</summary>\n\n<pre>\n<span style="color:#000">black<span style="color:#AAA">white</span></span>\n</pre>\n\n</details>',
issue_number: 123,
});
});
Expand All @@ -74,7 +94,7 @@ describe('pr.ts', () => {

await handlePullRequestMessage(options, projectName, 'test');
expect(createComment).toHaveBeenCalledWith({
body: '#### :tropical_drink: `preview` on myFirstProject/staging\n\n<details>\n<summary>Pulumi report</summary>\n\n```\ntest\n```\n\n</details>',
body: '#### :tropical_drink: `preview` on myFirstProject/staging\n\n<details>\n<summary>Pulumi report</summary>\n\n<pre>\ntest\n</pre>\n\n</details>',
issue_number: 87,
});
});
Expand All @@ -101,7 +121,7 @@ describe('pr.ts', () => {

await handlePullRequestMessage(options, projectName, 'test');
expect(createComment).toHaveBeenCalledWith({
body: '#### :tropical_drink: `preview` on myFirstProject/staging\n\n<details>\n<summary>Pulumi report</summary>\n\n```\ntest\n```\n\n</details>',
body: '#### :tropical_drink: `preview` on myFirstProject/staging\n\n<details>\n<summary>Pulumi report</summary>\n\n<pre>\ntest\n</pre>\n\n</details>',
issue_number: 87,
});
});
Expand Down Expand Up @@ -142,7 +162,7 @@ describe('pr.ts', () => {
await handlePullRequestMessage(options, projectName, 'test');
expect(updateComment).toHaveBeenCalledWith({
comment_id: 2,
body: '#### :tropical_drink: `preview` on myFirstProject/staging\n\n<details>\n<summary>Pulumi report</summary>\n\n```\ntest\n```\n\n</details>',
body: '#### :tropical_drink: `preview` on myFirstProject/staging\n\n<details>\n<summary>Pulumi report</summary>\n\n<pre>\ntest\n</pre>\n\n</details>',
});
});
});
50 changes: 41 additions & 9 deletions src/libs/pr.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,41 @@
import * as core from '@actions/core';
import { context, getOctokit } from '@actions/github';
import * as dedent from 'dedent';
import AnsiToHtml from 'ansi-to-html';
import dedent from 'dedent';
import invariant from 'ts-invariant';
import { Config } from '../config';

function ansiToHtml(
message: string,
maxLength: number,
): [string, boolean] {
/**
* Converts an ansi string to html by for example removing color escape characters.
* message: ansi string to convert
* maxLength: Maximum number of characters of final message incl. HTML tags
*
* return message as html and information if message was trimmed because of length
*/
const convert = new AnsiToHtml();
let trimmed = false;

let htmlBody: string = convert.toHtml(message);

// Check if htmlBody exceeds max characters
if (htmlBody.length > maxLength) {

// trim input message by number of exceeded characters
const dif: number = htmlBody.length - maxLength;
message = message.substring(0, message.length - dif);
Comment thread
jmrt47 marked this conversation as resolved.
trimmed = true;

// convert trimmed message to html
htmlBody = convert.toHtml(message);
}

return [htmlBody, trimmed];
}

export async function handlePullRequestMessage(
config: Config,
projectName: string,
Expand All @@ -14,27 +46,27 @@ export async function handlePullRequestMessage(
command,
stackName,
editCommentOnPr,
commentMaxCharacter,
} = config;

const heading = `#### :tropical_drink: \`${command}\` on ${projectName}/${stackName}`;

const summary = '<summary>Pulumi report</summary>';

const rawBody = output.substring(0, 64_000);
// a line break between heading and rawBody is needed
// otherwise the backticks won't work as intended
const [htmlBody, trimmed]: [string, boolean] = ansiToHtml(output, commentMaxCharacter);

const body = dedent`
${heading}

<details>
${summary}

\`\`\`
${rawBody}
\`\`\`
<pre>
${htmlBody}
</pre>
${
rawBody.length === 64_000
? '**Warn**: The output was too long and trimmed.'
trimmed
? ':warning: **Warn**: The output was too long and trimmed.'
: ''
}
</details>
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"target": "es2015",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"allowJs": false,
"importHelpers": true,
"alwaysStrict": true,
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1716,6 +1716,13 @@ ansi-styles@^6.1.0, ansi-styles@^6.2.1:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==

ansi-to-html@^0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.7.2.tgz#a92c149e4184b571eb29a0135ca001a8e2d710cb"
integrity sha512-v6MqmEpNlxF+POuyhKkidusCHWWkaLcGRURzivcU3I9tv7k4JVhFcnukrM5Rlk2rUywdZuzYAZ+kbZqWCnfN3g==
dependencies:
entities "^2.2.0"

anymatch@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
Expand Down Expand Up @@ -2558,6 +2565,11 @@ enquirer@^2.3.5:
dependencies:
ansi-colors "^4.1.1"

entities@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==

env-paths@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
Expand Down