Skip to content

Commit

Permalink
fix: Implemented output truncation and suppression on Github comments (
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielMSchmidt authored Sep 26, 2024
1 parent 56b8ec8 commit 4789b15
Show file tree
Hide file tree
Showing 10 changed files with 1,408 additions and 1,316 deletions.
6 changes: 6 additions & 0 deletions .projenrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ const inputs = {
required: false,
type: "string",
},
suppressOutput: {
description: "Whether to suppress the output of the action in PR comments",
default: "false",
required: false,
type: "boolean",
},
};

const repoName = "terraform-cdk-action";
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The Terraform CDK GitHub Action allows you to run CDKTF as part of your CI/CD wo
| updateComment | Whether to update the last comment on the PR rather than adding a new comment | `false` | true |
| customNpxArgs | The additional CLI arguments to pass to npx as part of the cdktf-cli execution. | `false` | |
| cdktfArgs | The additional CLI arguments to pass to cdktf as part of the cdktf-cli execution. | `false` | |
| suppressOutput | Whether to suppress the output of the action in PR comments | `false` | false |
<!-- action-docs-inputs -->

## Example Configurations
Expand Down
4 changes: 4 additions & 0 deletions action.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2,625 changes: 1,318 additions & 1,307 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

18 changes: 10 additions & 8 deletions src/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function postComment(
output: string | undefined,
outputTitle: Error | string
): Promise<void> {
output = output ? commentController.truncateOutput(output) : undefined;
return commentController.postCommentOnPr(
`### ${title}
Expand Down Expand Up @@ -129,6 +130,7 @@ export async function run(): Promise<void> {
updateComment: input.updateComment,
customNpxArgs: input.customNpxArgs,
cdktfArgs: input.cdktfArgs,
suppressOutput: input.suppressOutput,
};
const octokit = github.getOctokit(inputs.githubToken);
const commentController = new CommentController({
Expand Down Expand Up @@ -159,7 +161,7 @@ export async function run(): Promise<void> {
commentController,
"❌ Error synthesizing the Terraform CDK Application",
undefined,
output,
inputs.suppressOutput ? undefined : output,
error
)
);
Expand All @@ -180,22 +182,22 @@ export async function run(): Promise<void> {
commentController,
`✅ Successfully planned Terraform CDK Stack '${inputs.stackName}'`,
runUrl,
output,
inputs.suppressOutput ? undefined : output,
"Show Plan"
)
: postComment(
commentController,
`🟰 No changes in Terraform CDK Stack '${inputs.stackName}'`,
runUrl,
output,
inputs.suppressOutput ? undefined : output,
"Show Plan"
),
(error, output, runUrl) =>
postComment(
commentController,
`❌ Error planning Terraform CDK Stack '${inputs.stackName}'`,
runUrl,
output,
inputs.suppressOutput ? undefined : output,
error
)
);
Expand All @@ -216,22 +218,22 @@ export async function run(): Promise<void> {
commentController,
`✅ Successfully applied Terraform CDK Stack '${inputs.stackName}'`,
runUrl,
output,
inputs.suppressOutput ? undefined : output,
"Show Run"
)
: postComment(
commentController,
`🟰 No changes to apply in Terraform CDK Stack '${inputs.stackName}'`,
runUrl,
output,
inputs.suppressOutput ? undefined : output,
"Show Run"
),
(error, output, runUrl) =>
postComment(
commentController,
`❌ Error applying Terraform CDK Stack '${inputs.stackName}'`,
runUrl,
output,
inputs.suppressOutput ? undefined : output,
error
)
);
Expand Down Expand Up @@ -259,7 +261,7 @@ export async function run(): Promise<void> {
commentController,
`❌ Error destroying the Terraform CDK Application '${inputs.stackName}'`,
undefined,
output,
inputs.suppressOutput ? undefined : output,
error
)
);
Expand Down
11 changes: 11 additions & 0 deletions src/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ export class CommentController {

return !previousComment ? null : previousComment;
}

public truncateOutput(output: string): string {
// Github max comment length is 65536, but we want to leave room for the rest of the comment content
const maxOutputLength = 65000;
if (output.length > maxOutputLength) {
return `... Output truncated to the last ${maxOutputLength} characters ...\n\n${output.substring(
output.length - maxOutputLength
)}`;
}
return output;
}
}
const hashString = (str: string) => {
return crypto.createHash("md5").update(str).digest("hex");
Expand Down
1 change: 1 addition & 0 deletions src/inputs.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export interface Inputs {
updateComment: boolean;
customNpxArgs: string;
cdktfArgs: string;
suppressOutput: boolean;
}
55 changes: 55 additions & 0 deletions test/comment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ describe("comment", () => {
updateComment: true,
customNpxArgs: "",
cdktfArgs: "",
suppressOutput: false,
};

const pullRequestData = {
Expand Down Expand Up @@ -179,6 +180,60 @@ describe("comment", () => {
expect(createComment).not.toBeCalled();
});

it("should successfully truncate comment if it exceeds the limit", async () => {
const maxOutputLength = 65536;
const commentController = new CommentController({
inputs: defaultInput,
context,
octokit,
});
const commentBody = `${"a".repeat(maxOutputLength + 1)}\nlong-message`;
const truncatedBody = commentController.truncateOutput(commentBody);
const expectedBody = `<!-- terraform cdk action for options with hash ${hash} -->\n${truncatedBody}`;
const actual = await commentController.postCommentOnPr(truncatedBody);
expect(actual).toBeUndefined();
expect(createComment).not.toBeCalled();
expect(updateComment).toBeCalledWith({
body: expectedBody,
comment_id: "comment_id_2",
});
expect(expectedBody.length).toBeLessThanOrEqual(65536);
});

it("should not truncate comment if it does not exceed the limit", async () => {
const commentController = new CommentController({
inputs: defaultInput,
context,
octokit,
});
const commentBody = "short-message";
const truncatedBody = commentController.truncateOutput(commentBody);
const expectedBody = `<!-- terraform cdk action for options with hash ${hash} -->\n${truncatedBody}`;
const actual = await commentController.postCommentOnPr(truncatedBody);
expect(actual).toBeUndefined();
expect(createComment).not.toBeCalled();
expect(updateComment).toBeCalledWith({
body: expectedBody,
comment_id: "comment_id_2",
});
expect(expectedBody.length).toBeLessThanOrEqual(65536);
});

it("should omit output in comment if suppressOutput is true", async () => {
const commentController = new CommentController({
inputs: { ...defaultInput, suppressOutput: true },
context,
octokit,
});
const actual = await commentController.postCommentOnPr("some-message");
expect(actual).toBeUndefined();
expect(createComment).not.toBeCalled();
expect(updateComment).toBeCalledWith({
body: `<!-- terraform cdk action for options with hash ${hash} -->\nsome-message`,
comment_id: "comment_id_2",
});
});

it("should get pull_number via API if not running on PR", async () => {
issuesAndPullRequests.mockResolvedValueOnce(pullRequestData);
paginate.mockResolvedValueOnce(commentDataWithTag);
Expand Down

0 comments on commit 4789b15

Please sign in to comment.