From 9d950b6220f2824d169b3d9507cae4200dc6a85e Mon Sep 17 00:00:00 2001 From: Umang Galaiya Date: Wed, 1 Jun 2022 20:33:14 +0530 Subject: [PATCH 1/6] Read body from file --- dist/index.js | 21 ++++++++++++++------- index.js | 21 ++++++++++++++------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/dist/index.js b/dist/index.js index fb6b8232..3dfb657d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -8573,6 +8573,7 @@ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { const { inspect } = __nccwpck_require__(3837); +const { readFileSync } = __nccwpck_require__(7147); const core = __nccwpck_require__(2186); const github = __nccwpck_require__(5438); @@ -8645,6 +8646,7 @@ async function run() { issueNumber: core.getInput("issue-number"), commentId: core.getInput("comment-id"), body: core.getInput("body"), + file: core.getInput("file"), editMode: core.getInput("edit-mode"), reactions: core.getInput("reactions") ? core.getInput("reactions") @@ -8667,14 +8669,19 @@ async function run() { const octokit = github.getOctokit(inputs.token); + let bodyToUse = inputs.body; + if (inputs.file) { + bodyToUse = readFileSync(inputs.file, "utf8"); + } + if (inputs.commentId) { // Edit a comment - if (!inputs.body && !inputs.reactions) { - core.setFailed("Missing either comment 'body' or 'reactions'."); + if (!inputs.body && !inputs.reactions && !inputs.file) { + core.setFailed("Missing either comment 'body', 'file', or 'reactions'."); return; } - if (inputs.body) { + if (bodyToUse) { var commentBody = ""; if (editMode == "append") { // Get the comment body @@ -8686,7 +8693,7 @@ async function run() { commentBody = comment.body + "\n"; } - commentBody = commentBody + inputs.body; + commentBody = commentBody + bodyToUse; core.debug(`Comment body: ${commentBody}`); await octokit.rest.issues.updateComment({ owner: repo[0], @@ -8704,15 +8711,15 @@ async function run() { } } else if (inputs.issueNumber) { // Create a comment - if (!inputs.body) { - core.setFailed("Missing comment 'body'."); + if (!inputs.body && !inputs.file) { + core.setFailed("Missing comment 'body' or 'file'."); return; } const { data: comment } = await octokit.rest.issues.createComment({ owner: repo[0], repo: repo[1], issue_number: inputs.issueNumber, - body: inputs.body, + body: bodyToUse, }); core.info( `Created comment id '${comment.id}' on issue '${inputs.issueNumber}'.` diff --git a/index.js b/index.js index ce6c3a8c..0f17f97c 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,5 @@ const { inspect } = require("util"); +const { readFileSync } = require("fs"); const core = require("@actions/core"); const github = require("@actions/github"); @@ -71,6 +72,7 @@ async function run() { issueNumber: core.getInput("issue-number"), commentId: core.getInput("comment-id"), body: core.getInput("body"), + file: core.getInput("file"), editMode: core.getInput("edit-mode"), reactions: core.getInput("reactions") ? core.getInput("reactions") @@ -93,14 +95,19 @@ async function run() { const octokit = github.getOctokit(inputs.token); + let bodyToUse = inputs.body; + if (inputs.file) { + bodyToUse = readFileSync(inputs.file, "utf8"); + } + if (inputs.commentId) { // Edit a comment - if (!inputs.body && !inputs.reactions) { - core.setFailed("Missing either comment 'body' or 'reactions'."); + if (!inputs.body && !inputs.reactions && !inputs.file) { + core.setFailed("Missing either comment 'body', 'file', or 'reactions'."); return; } - if (inputs.body) { + if (bodyToUse) { var commentBody = ""; if (editMode == "append") { // Get the comment body @@ -112,7 +119,7 @@ async function run() { commentBody = comment.body + "\n"; } - commentBody = commentBody + inputs.body; + commentBody = commentBody + bodyToUse; core.debug(`Comment body: ${commentBody}`); await octokit.rest.issues.updateComment({ owner: repo[0], @@ -130,15 +137,15 @@ async function run() { } } else if (inputs.issueNumber) { // Create a comment - if (!inputs.body) { - core.setFailed("Missing comment 'body'."); + if (!inputs.body && !inputs.file) { + core.setFailed("Missing comment 'body' or 'file'."); return; } const { data: comment } = await octokit.rest.issues.createComment({ owner: repo[0], repo: repo[1], issue_number: inputs.issueNumber, - body: inputs.body, + body: bodyToUse, }); core.info( `Created comment id '${comment.id}' on issue '${inputs.issueNumber}'.` From 63c92e5e904af139385992558719087aaa687435 Mon Sep 17 00:00:00 2001 From: Umang Galaiya Date: Wed, 1 Jun 2022 23:29:04 +0530 Subject: [PATCH 2/6] Improve code, add support for fileEncoding --- dist/index.js | 37 +++++++++++++++++++++++++++++-------- index.js | 37 +++++++++++++++++++++++++++++-------- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/dist/index.js b/dist/index.js index 3dfb657d..109b40a8 100644 --- a/dist/index.js +++ b/dist/index.js @@ -8573,7 +8573,7 @@ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { const { inspect } = __nccwpck_require__(3837); -const { readFileSync } = __nccwpck_require__(7147); +const { readFileSync, existsSync } = __nccwpck_require__(7147); const core = __nccwpck_require__(2186); const github = __nccwpck_require__(5438); @@ -8647,6 +8647,7 @@ async function run() { commentId: core.getInput("comment-id"), body: core.getInput("body"), file: core.getInput("file"), + fileEncoding: core.getInput("file-encoding") || 'utf8', editMode: core.getInput("edit-mode"), reactions: core.getInput("reactions") ? core.getInput("reactions") @@ -8667,13 +8668,20 @@ async function run() { return; } - const octokit = github.getOctokit(inputs.token); + if (inputs.file && inputs.body) { + core.setFailed("Only one of 'file' or 'body' can be set."); + return; + } - let bodyToUse = inputs.body; if (inputs.file) { - bodyToUse = readFileSync(inputs.file, "utf8"); + if (!existsSync(inputs.file)) { + core.setFailed(`File '${inputs.file}' does not exist.`); + return; + } } + const octokit = github.getOctokit(inputs.token); + if (inputs.commentId) { // Edit a comment if (!inputs.body && !inputs.reactions && !inputs.file) { @@ -8681,7 +8689,9 @@ async function run() { return; } - if (bodyToUse) { + const body = getBodyOrFile(inputs); + + if (body) { var commentBody = ""; if (editMode == "append") { // Get the comment body @@ -8693,7 +8703,7 @@ async function run() { commentBody = comment.body + "\n"; } - commentBody = commentBody + bodyToUse; + commentBody = commentBody + body; core.debug(`Comment body: ${commentBody}`); await octokit.rest.issues.updateComment({ owner: repo[0], @@ -8711,15 +8721,18 @@ async function run() { } } else if (inputs.issueNumber) { // Create a comment - if (!inputs.body && !inputs.file) { + const body = getBodyOrFile(inputs); + + if (!body) { core.setFailed("Missing comment 'body' or 'file'."); return; } + const { data: comment } = await octokit.rest.issues.createComment({ owner: repo[0], repo: repo[1], issue_number: inputs.issueNumber, - body: bodyToUse, + body, }); core.info( `Created comment id '${comment.id}' on issue '${inputs.issueNumber}'.` @@ -8743,6 +8756,14 @@ async function run() { } } +function getBodyOrFile (inputs) { + if (inputs.body) { + return inputs.body; + } else if (inputs.file) { + return readFileSync(inputs.file, inputs.fileEncoding); + } +} + run(); })(); diff --git a/index.js b/index.js index 0f17f97c..1017e11f 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ const { inspect } = require("util"); -const { readFileSync } = require("fs"); +const { readFileSync, existsSync } = require("fs"); const core = require("@actions/core"); const github = require("@actions/github"); @@ -73,6 +73,7 @@ async function run() { commentId: core.getInput("comment-id"), body: core.getInput("body"), file: core.getInput("file"), + fileEncoding: core.getInput("file-encoding") || 'utf8', editMode: core.getInput("edit-mode"), reactions: core.getInput("reactions") ? core.getInput("reactions") @@ -93,13 +94,20 @@ async function run() { return; } - const octokit = github.getOctokit(inputs.token); + if (inputs.file && inputs.body) { + core.setFailed("Only one of 'file' or 'body' can be set."); + return; + } - let bodyToUse = inputs.body; if (inputs.file) { - bodyToUse = readFileSync(inputs.file, "utf8"); + if (!existsSync(inputs.file)) { + core.setFailed(`File '${inputs.file}' does not exist.`); + return; + } } + const octokit = github.getOctokit(inputs.token); + if (inputs.commentId) { // Edit a comment if (!inputs.body && !inputs.reactions && !inputs.file) { @@ -107,7 +115,9 @@ async function run() { return; } - if (bodyToUse) { + const body = getBodyOrFile(inputs); + + if (body) { var commentBody = ""; if (editMode == "append") { // Get the comment body @@ -119,7 +129,7 @@ async function run() { commentBody = comment.body + "\n"; } - commentBody = commentBody + bodyToUse; + commentBody = commentBody + body; core.debug(`Comment body: ${commentBody}`); await octokit.rest.issues.updateComment({ owner: repo[0], @@ -137,15 +147,18 @@ async function run() { } } else if (inputs.issueNumber) { // Create a comment - if (!inputs.body && !inputs.file) { + const body = getBodyOrFile(inputs); + + if (!body) { core.setFailed("Missing comment 'body' or 'file'."); return; } + const { data: comment } = await octokit.rest.issues.createComment({ owner: repo[0], repo: repo[1], issue_number: inputs.issueNumber, - body: bodyToUse, + body, }); core.info( `Created comment id '${comment.id}' on issue '${inputs.issueNumber}'.` @@ -169,4 +182,12 @@ async function run() { } } +function getBodyOrFile (inputs) { + if (inputs.body) { + return inputs.body; + } else if (inputs.file) { + return readFileSync(inputs.file, inputs.fileEncoding); + } +} + run(); From 1fdf65a50f79c8290bea2d0b1f6854472f583072 Mon Sep 17 00:00:00 2001 From: Umang Galaiya Date: Wed, 1 Jun 2022 23:43:03 +0530 Subject: [PATCH 3/6] Update README --- README.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 584e1f29..405d090c 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ This action was created to help facilitate a GitHub Actions "ChatOps" solution i | `issue-number` | The number of the issue or pull request in which to create a comment. | | | `comment-id` | The id of the comment to update. | | | `body` | The comment body. | | +| `file` | The path to a file that can be read as `body`. Use either `file` or `body`, but not both. | | +| `fileEncoding` | The encoding of the file provided as `file`. | `utf8` | | `edit-mode` | The mode when updating a comment, `replace` or `append`. | `append` | | `reactions` | A comma separated list of reactions to add to the comment. (`+1`, `-1`, `laugh`, `confused`, `heart`, `hooray`, `rocket`, `eyes`) | | @@ -158,23 +160,12 @@ If required, the create and update steps can be separated for greater control. ### Setting the comment body from a file -This example shows how file content can be read into a variable and passed to the action. -The content must be [escaped to preserve newlines](https://github.community/t/set-output-truncates-multiline-strings/16852/3). - ```yml - - id: get-comment-body - run: | - body="$(cat comment-body.txt)" - body="${body//'%'/'%25'}" - body="${body//$'\n'/'%0A'}" - body="${body//$'\r'/'%0D'}" - echo "::set-output name=body::$body" - - name: Create comment uses: peter-evans/create-or-update-comment@v2 with: issue-number: 1 - body: ${{ steps.get-comment-body.outputs.body }} + file: 'comment-body.txt' ``` ### Using a markdown template From acea7ce9cea804615d6cb036b612b25040fc2dd1 Mon Sep 17 00:00:00 2001 From: Umang Galaiya Date: Fri, 3 Jun 2022 00:42:46 +0530 Subject: [PATCH 4/6] Update inputs --- action.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index a3b8799d..4e98fdb4 100644 --- a/action.yml +++ b/action.yml @@ -12,6 +12,8 @@ inputs: description: 'The id of the comment to update.' body: description: 'The comment body.' + file: + description: 'The path to a file that can be read as `body`. Use either `file` or `body`, but not both.' edit-mode: description: 'The mode when updating a comment, "replace" or "append".' reaction-type: @@ -25,5 +27,5 @@ runs: using: 'node16' main: 'dist/index.js' branding: - icon: 'message-square' + icon: 'message-square' color: 'gray-dark' From 40bf395e0ae447ac33928e8d9d1312c104175150 Mon Sep 17 00:00:00 2001 From: Peter Evans <18365890+peter-evans@users.noreply.github.com> Date: Mon, 24 Oct 2022 15:38:52 +0900 Subject: [PATCH 5/6] Minor refactor and tests for body-file input --- .github/comment-body-edited.md | 7 +++ .../{multiline-content.md => comment-body.md} | 0 .github/workflows/ci.yml | 15 +++++++ .github/workflows/test-command.yml | 10 +---- README.md | 7 ++- action.yml | 6 +-- dist/index.js | 43 +++++++++---------- index.js | 43 +++++++++---------- 8 files changed, 71 insertions(+), 60 deletions(-) create mode 100644 .github/comment-body-edited.md rename .github/{multiline-content.md => comment-body.md} (100%) diff --git a/.github/comment-body-edited.md b/.github/comment-body-edited.md new file mode 100644 index 00000000..8eb0936c --- /dev/null +++ b/.github/comment-body-edited.md @@ -0,0 +1,7 @@ +This is a multi-line test comment read from a file. +- With GitHub **Markdown** :sparkles: +- Created by [create-or-update-comment][1] + +[1]: https://github.com/peter-evans/create-or-update-comment + +*updated info* diff --git a/.github/multiline-content.md b/.github/comment-body.md similarity index 100% rename from .github/multiline-content.md rename to .github/comment-body.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a417a52..f201184f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,6 +92,21 @@ jobs: comment-id: ${{ steps.couc.outputs.comment-id }} reactions: heart, hooray, laugh + - name: Test create comment from file + uses: ./ + id: couc2 + with: + issue-number: ${{ needs.build.outputs.issue-number }} + body-file: .github/comment-body.md + reactions: '+1' + + - name: Test update comment from file + uses: ./ + with: + comment-id: ${{ steps.couc2.outputs.comment-id }} + body-file: .github/comment-body-edited.md + reactions: eyes + package: if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: [test] diff --git a/.github/workflows/test-command.yml b/.github/workflows/test-command.yml index ded4a9e3..eb5ec6cc 100644 --- a/.github/workflows/test-command.yml +++ b/.github/workflows/test-command.yml @@ -61,19 +61,11 @@ jobs: reactions: hooray # Test create with body from file - - id: get-comment-body - run: | - body="$(cat .github/multiline-content.md)" - delimiter="$(openssl rand -hex 8)" - echo "body<<$delimiter" >> $GITHUB_OUTPUT - echo "$body" >> $GITHUB_OUTPUT - echo "$delimiter" >> $GITHUB_OUTPUT - - name: Create comment uses: ./ with: issue-number: 1 - body: ${{ steps.get-comment-body.outputs.body }} + body-file: .github/comment-body.md # Test create from template - name: Render template diff --git a/README.md b/README.md index 405d090c..1e0d7519 100644 --- a/README.md +++ b/README.md @@ -54,9 +54,8 @@ This action was created to help facilitate a GitHub Actions "ChatOps" solution i | `repository` | The full name of the repository in which to create or update a comment. | Current repository | | `issue-number` | The number of the issue or pull request in which to create a comment. | | | `comment-id` | The id of the comment to update. | | -| `body` | The comment body. | | -| `file` | The path to a file that can be read as `body`. Use either `file` or `body`, but not both. | | -| `fileEncoding` | The encoding of the file provided as `file`. | `utf8` | +| `body` | The comment body. Cannot be used in conjunction with `body-file`. | | +| `body-file` | The path to a file containing the comment body. Cannot be used in conjunction with `body`. | | | `edit-mode` | The mode when updating a comment, `replace` or `append`. | `append` | | `reactions` | A comma separated list of reactions to add to the comment. (`+1`, `-1`, `laugh`, `confused`, `heart`, `hooray`, `rocket`, `eyes`) | | @@ -165,7 +164,7 @@ If required, the create and update steps can be separated for greater control. uses: peter-evans/create-or-update-comment@v2 with: issue-number: 1 - file: 'comment-body.txt' + body-file: 'comment-body.md' ``` ### Using a markdown template diff --git a/action.yml b/action.yml index 4e98fdb4..56c63298 100644 --- a/action.yml +++ b/action.yml @@ -11,9 +11,9 @@ inputs: comment-id: description: 'The id of the comment to update.' body: - description: 'The comment body.' - file: - description: 'The path to a file that can be read as `body`. Use either `file` or `body`, but not both.' + description: 'The comment body. Cannot be used in conjunction with `body-file`.' + body-file: + description: 'The path to a file containing the comment body. Cannot be used in conjunction with `body`.' edit-mode: description: 'The mode when updating a comment, "replace" or "append".' reaction-type: diff --git a/dist/index.js b/dist/index.js index aa5e2b7e..cbff30b5 100644 --- a/dist/index.js +++ b/dist/index.js @@ -9750,6 +9750,16 @@ async function addReactions(octokit, repo, comment_id, reactions) { results = undefined; } +function getBody(inputs) { + if (inputs.body) { + return inputs.body; + } else if (inputs.bodyFile) { + return readFileSync(inputs.bodyFile, 'utf-8'); + } else { + return ''; + } +} + async function run() { try { const inputs = { @@ -9758,8 +9768,7 @@ async function run() { issueNumber: core.getInput("issue-number"), commentId: core.getInput("comment-id"), body: core.getInput("body"), - file: core.getInput("file"), - fileEncoding: core.getInput("file-encoding") || 'utf8', + bodyFile: core.getInput("body-file"), editMode: core.getInput("edit-mode"), reactions: core.getInput("reactions") ? core.getInput("reactions") @@ -9780,29 +9789,29 @@ async function run() { return; } - if (inputs.file && inputs.body) { - core.setFailed("Only one of 'file' or 'body' can be set."); + if (inputs.bodyFile && inputs.body) { + core.setFailed("Only one of 'body' or 'body-file' can be set."); return; } - if (inputs.file) { - if (!existsSync(inputs.file)) { - core.setFailed(`File '${inputs.file}' does not exist.`); + if (inputs.bodyFile) { + if (!existsSync(inputs.bodyFile)) { + core.setFailed(`File '${inputs.bodyFile}' does not exist.`); return; } } + const body = getBody(inputs); + const octokit = github.getOctokit(inputs.token); if (inputs.commentId) { // Edit a comment - if (!inputs.body && !inputs.reactions && !inputs.file) { - core.setFailed("Missing either comment 'body', 'file', or 'reactions'."); + if (!body && !inputs.reactions) { + core.setFailed("Missing comment 'body', 'body-file', or 'reactions'."); return; } - const body = getBodyOrFile(inputs); - if (body) { var commentBody = ""; if (editMode == "append") { @@ -9833,10 +9842,8 @@ async function run() { } } else if (inputs.issueNumber) { // Create a comment - const body = getBodyOrFile(inputs); - if (!body) { - core.setFailed("Missing comment 'body' or 'file'."); + core.setFailed("Missing comment 'body' or 'body-file'."); return; } @@ -9868,14 +9875,6 @@ async function run() { } } -function getBodyOrFile (inputs) { - if (inputs.body) { - return inputs.body; - } else if (inputs.file) { - return readFileSync(inputs.file, inputs.fileEncoding); - } -} - run(); })(); diff --git a/index.js b/index.js index 1017e11f..98ebd7a6 100644 --- a/index.js +++ b/index.js @@ -64,6 +64,16 @@ async function addReactions(octokit, repo, comment_id, reactions) { results = undefined; } +function getBody(inputs) { + if (inputs.body) { + return inputs.body; + } else if (inputs.bodyFile) { + return readFileSync(inputs.bodyFile, 'utf-8'); + } else { + return ''; + } +} + async function run() { try { const inputs = { @@ -72,8 +82,7 @@ async function run() { issueNumber: core.getInput("issue-number"), commentId: core.getInput("comment-id"), body: core.getInput("body"), - file: core.getInput("file"), - fileEncoding: core.getInput("file-encoding") || 'utf8', + bodyFile: core.getInput("body-file"), editMode: core.getInput("edit-mode"), reactions: core.getInput("reactions") ? core.getInput("reactions") @@ -94,29 +103,29 @@ async function run() { return; } - if (inputs.file && inputs.body) { - core.setFailed("Only one of 'file' or 'body' can be set."); + if (inputs.bodyFile && inputs.body) { + core.setFailed("Only one of 'body' or 'body-file' can be set."); return; } - if (inputs.file) { - if (!existsSync(inputs.file)) { - core.setFailed(`File '${inputs.file}' does not exist.`); + if (inputs.bodyFile) { + if (!existsSync(inputs.bodyFile)) { + core.setFailed(`File '${inputs.bodyFile}' does not exist.`); return; } } + const body = getBody(inputs); + const octokit = github.getOctokit(inputs.token); if (inputs.commentId) { // Edit a comment - if (!inputs.body && !inputs.reactions && !inputs.file) { - core.setFailed("Missing either comment 'body', 'file', or 'reactions'."); + if (!body && !inputs.reactions) { + core.setFailed("Missing comment 'body', 'body-file', or 'reactions'."); return; } - const body = getBodyOrFile(inputs); - if (body) { var commentBody = ""; if (editMode == "append") { @@ -147,10 +156,8 @@ async function run() { } } else if (inputs.issueNumber) { // Create a comment - const body = getBodyOrFile(inputs); - if (!body) { - core.setFailed("Missing comment 'body' or 'file'."); + core.setFailed("Missing comment 'body' or 'body-file'."); return; } @@ -182,12 +189,4 @@ async function run() { } } -function getBodyOrFile (inputs) { - if (inputs.body) { - return inputs.body; - } else if (inputs.file) { - return readFileSync(inputs.file, inputs.fileEncoding); - } -} - run(); From deb2c8166c4383c7cdd4fbb5d14ae3c3221d1414 Mon Sep 17 00:00:00 2001 From: Peter Evans <18365890+peter-evans@users.noreply.github.com> Date: Mon, 24 Oct 2022 15:42:45 +0900 Subject: [PATCH 6/6] Test fix for consistency --- .github/comment-body-addition.md | 1 + .github/comment-body-edited.md | 7 ------- .github/workflows/ci.yml | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) create mode 100644 .github/comment-body-addition.md delete mode 100644 .github/comment-body-edited.md diff --git a/.github/comment-body-addition.md b/.github/comment-body-addition.md new file mode 100644 index 00000000..30f398d9 --- /dev/null +++ b/.github/comment-body-addition.md @@ -0,0 +1 @@ +**Edit:** Some additional info diff --git a/.github/comment-body-edited.md b/.github/comment-body-edited.md deleted file mode 100644 index 8eb0936c..00000000 --- a/.github/comment-body-edited.md +++ /dev/null @@ -1,7 +0,0 @@ -This is a multi-line test comment read from a file. -- With GitHub **Markdown** :sparkles: -- Created by [create-or-update-comment][1] - -[1]: https://github.com/peter-evans/create-or-update-comment - -*updated info* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f201184f..63102e58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -104,7 +104,7 @@ jobs: uses: ./ with: comment-id: ${{ steps.couc2.outputs.comment-id }} - body-file: .github/comment-body-edited.md + body-file: .github/comment-body-addition.md reactions: eyes package: