diff --git a/README.md b/README.md index a0e7242..18024bc 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,10 @@ If the workflow succeeds, the bot comments the details of the preview environmen # If a comment with the given id is not found, a new comment is created append: true + # Replaces the message of a comment that already exits with the given id. + # If a comment with the given id is not found, a new comment is created + replace: true + # Deletes all the existing comments matching the given id and # creates a new comment with the given message recreate: true @@ -63,9 +67,7 @@ If the workflow succeeds, the bot comments the details of the preview environmen delete: true ``` -**Note:** The `number` and `commit-sha` fields are mutually exclusive. Only one of them should be set in a job. If both or none are present, an error will be thrown and the job will fail. - -**Note**: The `append` and `recreate` fields are also mutually exclusive. If none of them are set, the job will continue in normal mode but if both are present an error will be thrown and the job will fail. +**Note**: `append`, `recreate`, `replace`, and `delete` fields are mutually exclusive. If more than one of them are set, an error will be thrown and the job will fail. ## Scenarios @@ -165,6 +167,45 @@ jobs: append: true ``` +### Create a comment and replace an identical comment + +This uses the `replace` flag to replace any existing comment created with the same id. + +```yml +on: + pull_request: + types: [opened] + +jobs: + deploy-preview: + runs-on: ubuntu-20.04 + name: Deploy preview + steps: + - name: Notify about starting this deployment + uses: hasura/comment-progress@v2.3.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + repository: "my-org/my-repo" + number: ${{ github.event.number }} + id: deploy-preview + message: "Starting deployment of this pull request." + + - name: Deploy preview + run: | + echo "deploy preview" + # long running step + + - name: Notify about the result of this deployment + uses: hasura/comment-progress@v2.3.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + repository: "my-org/my-repo" + number: ${{ github.event.number }} + id: deploy-preview + message: "Deployment of a preview for this pull request was successful." + replace: true +``` + ### Delete older/stale comment and add a new comment Take a case where you need to re-deploy a preview for your pull request and report the status of the redeployment as a new comment and at the same time delete the old comment containing stale information. `recreate` flag will help in achieving this scenario. diff --git a/action.yml b/action.yml index 9010712..a38c1ec 100644 --- a/action.yml +++ b/action.yml @@ -28,6 +28,10 @@ inputs: description: 'If true, message will be appended to existing comment' required: false default: false + replace: + description: 'If true, message will replace existing comment' + required: false + default: false recreate: description: 'If true, message will be commented after deleting existing comment' required: false diff --git a/dist/index.js b/dist/index.js index 395834c..015f3f5 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,311 +1,6 @@ -module.exports = /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ -/***/ 752: -/***/ ((__unused_webpack_module, __webpack_exports__, __nccwpck_require__) => { - -"use strict"; -// ESM COMPAT FLAG -__nccwpck_require__.r(__webpack_exports__); - -// EXTERNAL MODULE: ./node_modules/@actions/core/lib/core.js -var core = __nccwpck_require__(186); -// EXTERNAL MODULE: ./node_modules/@actions/github/lib/github.js -var github = __nccwpck_require__(438); -// CONCATENATED MODULE: ./identifier.js -function getCommentPrefix(identifier) { - return ``; -} - -// CONCATENATED MODULE: ./comment/issue_commenter.js -class IssueCommenter { - constructor(octokit, { owner, repo, number }) { - this.octokit = octokit; - this.owner = owner; - this.repo = repo; - this.number = number; - } - - createComment(comment) { - return this.octokit.issues.createComment({ - owner: this.owner, - repo: this.repo, - issue_number: this.number, - body: comment, - }); - } - - deleteComment(commentID) { - return this.octokit.issues.deleteComment({ - owner: this.owner, - repo: this.repo, - comment_id: commentID, - }); - } - - listComments(opts) { - return this.octokit.issues.listComments({ - owner: this.owner, - repo: this.repo, - issue_number: this.number, - page: opts.page, - per_page: opts.perPage, - }); - } - - updateComment(commentID, comment) { - return this.octokit.issues.updateComment({ - owner: this.owner, - repo: this.repo, - comment_id: commentID, - body: comment, - }); - } -} - -// CONCATENATED MODULE: ./comment/commit_commenter.js -class CommitCommenter { - constructor(octokit, { owner, repo, commitSHA }) { - this.octokit = octokit; - this.owner = owner; - this.repo = repo; - this.commitSHA = commitSHA; - } - - createComment(comment) { - return this.octokit.repos.createCommitComment({ - owner: this.owner, - repo: this.repo, - commit_sha: this.commitSHA, - body: comment, - }); - } - - deleteComment(commentID) { - return this.octokit.repos.deleteCommitComment({ - owner: this.owner, - repo: this.repo, - comment_id: commentID, - }); - } - - listComments(opts) { - return this.octokit.repos.listCommentsForCommit({ - owner: this.owner, - repo: this.repo, - commit_sha: this.commitSHA, - page: opts.page, - per_page: opts.perPage, - }); - } - - updateComment(commentID, comment) { - return this.octokit.repos.updateCommitComment({ - owner: this.owner, - repo: this.repo, - comment_id: commentID, - body: comment, - }); - } -} - -// CONCATENATED MODULE: ./comment/commenter.js - - - - -function getCommenter(octokit, { - owner, repo, number, commitSHA, -}) { - if ((number && commitSHA) || (!number && !commitSHA)) { - throw new Error('Either set the `number` or the `commit-sha` field.'); - } - if (number) { - return new IssueCommenter(octokit, { owner, repo, number }); - } - if (commitSHA) { - return new CommitCommenter(octokit, { owner, repo, commitSHA }); - } - return null; -} - -async function findMatchingComments(commenter, identifier) { - let fetchMoreComments = true; - let page = 0; - const matchingComments = []; - const commentPrefix = getCommentPrefix(identifier); - - while (fetchMoreComments) { - page += 1; - const comments = await commenter.listComments({ - page, - perPage: 100, - }); - fetchMoreComments = comments.data.length !== 0; - for (const comment of comments.data) { - if (comment.body.startsWith(commentPrefix)) { - matchingComments.push(comment); - } - } - } - return matchingComments; -} - -async function findMatchingComment(commenter, identifier) { - const matchingComments = await findMatchingComments(commenter, identifier); - let matchingComment; - if (matchingComments && matchingComments.length > 0) { - matchingComment = matchingComments[matchingComments.length - 1]; - } - return matchingComment; -} - -// CONCATENATED MODULE: ./modes.js - - - -// normal mode creates a comment when there is no existing comment that match identifier -// and updates the matching comment if found -async function normalMode(commenter, identifier, message) { - console.log(`Checking if a comment already exists for ${identifier}.`); - const matchingComment = await findMatchingComment(commenter, identifier); - - const comment = `${getCommentPrefix(identifier)}\n${message}`; - - if (matchingComment) { - console.log(`Updating an existing comment for ${identifier}.`); - const resp = await commenter.updateComment(matchingComment.id, comment); - console.log(`Updated comment: ${resp.data.html_url}`); - return; - } - - console.log(`Creating a new comment for ${identifier}.`); - const resp = await commenter.createComment(comment); - console.log(`Created comment: ${resp.data.html_url}`); -} - -// recreate mode deletes existing comments that match the identifier -// and creates a new comment -async function recreateMode(commenter, identifier, message) { - console.log(`Finding matching comments for ${identifier}.`); - const matchingComments = await findMatchingComments(commenter, identifier); - - for (const comment of matchingComments) { - console.log(`Deleting github comment ${comment.id}`); - await commenter.deleteComment(comment.id); - } - - console.log(`Creating a new comment for ${identifier}.`); - const comment = `${getCommentPrefix(identifier)}\n${message}`; - const resp = await commenter.createComment(comment); - console.log(`Created comment: ${resp.data.html_url}`); -} - -// append mode creates a comment when there is no existing comment that match identifier -// and appends message to a matching comment if found. -async function appendMode(commenter, identifier, message) { - console.log(`Checking if a comment already exists for ${identifier}.`); - const matchingComment = await findMatchingComment(commenter, identifier); - - if (matchingComment) { - console.log(`Updating an existing comment for ${identifier}.`); - const comment = `${matchingComment.body}\n${message}`; - const resp = await commenter.updateComment(matchingComment.id, comment); - console.log(`Updated comment: ${resp.data.html_url}`); - return; - } - - console.log(`Creating a new comment for ${identifier}.`); - const comment = `${getCommentPrefix(identifier)}\n${message}`; - const resp = await commenter.createComment(comment); - console.log(`Created comment: ${resp.data.html_url}`); -} - -// delete mode deletes an existing comment that matches the identifier -async function deleteMode(commenter, identifier) { - console.log(`Finding matching comment for ${identifier}.`); - const matchingComment = await findMatchingComment(commenter, identifier); - - if (matchingComment) { - console.log(`Deleting github comment ${matchingComment.id}`); - await commenter.deleteComment(matchingComment.id); - } -} - -// CONCATENATED MODULE: ./index.js - - - - - -(async () => { - try { - const repository = core.getInput("repository"); - const [owner, repo] = repository.split("/"); - if (!owner || !repo) { - throw new Error(`Invalid repository: ${repository}`); - } - - const number = core.getInput("number"); - const commitSHA = core.getInput("commit-sha"); - const identifier = core.getInput("id"); - const appendComment = core.getInput("append"); - const recreateComment = core.getInput("recreate"); - const deleteComment = core.getInput("delete"); - const fail = core.getInput("fail"); - const githubToken = core.getInput("github-token"); - const message = core.getInput("message"); - - const octokit = github.getOctokit(githubToken); - - let commenter; - try { - commenter = getCommenter(octokit, { - owner, - repo, - number, - commitSHA, - }); - } catch (err) { - core.setFailed(err); - return; - } - - let mode = normalMode; - - if (appendComment === "true" && recreateComment === "true") { - core.setFailed("Not allowed to set both `append` and `recreate` to true."); - return; - } - - if (deleteComment === "true" && (appendComment === "true" || recreateComment === "true")) { - core.setFailed("Not allowed to set `delete` to true with `append` or `recreate`."); - return; - } - - if (recreateComment === "true") { - mode = recreateMode; - } else if (appendComment === "true") { - mode = appendMode; - } else if (deleteComment === "true") { - mode = deleteMode; - } - - await mode(commenter, identifier, message); - - if (fail === "true") { - core.setFailed(message); - } - } catch (error) { - console.error(error); - core.setFailed(error.message); - } -})(); - - -/***/ }), - /***/ 351: /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { @@ -319,7 +14,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -const os = __importStar(__nccwpck_require__(87)); +const os = __importStar(__nccwpck_require__(37)); const utils_1 = __nccwpck_require__(278); /** * Commands @@ -417,8 +112,8 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); const command_1 = __nccwpck_require__(351); const file_command_1 = __nccwpck_require__(717); const utils_1 = __nccwpck_require__(278); -const os = __importStar(__nccwpck_require__(87)); -const path = __importStar(__nccwpck_require__(622)); +const os = __importStar(__nccwpck_require__(37)); +const path = __importStar(__nccwpck_require__(17)); /** * The code to exit an action */ @@ -653,8 +348,8 @@ var __importStar = (this && this.__importStar) || function (mod) { Object.defineProperty(exports, "__esModule", ({ value: true })); // We use any as a valid input type /* eslint-disable @typescript-eslint/no-explicit-any */ -const fs = __importStar(__nccwpck_require__(747)); -const os = __importStar(__nccwpck_require__(87)); +const fs = __importStar(__nccwpck_require__(147)); +const os = __importStar(__nccwpck_require__(37)); const utils_1 = __nccwpck_require__(278); function issueCommand(command, message) { const filePath = process.env[`GITHUB_${command}`]; @@ -699,15 +394,15 @@ exports.toCommandValue = toCommandValue; /***/ }), -/***/ 53: +/***/ 87: /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.Context = void 0; -const fs_1 = __nccwpck_require__(747); -const os_1 = __nccwpck_require__(87); +const fs_1 = __nccwpck_require__(147); +const os_1 = __nccwpck_require__(37); class Context { /** * Hydrate the context from the environment @@ -782,7 +477,7 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getOctokit = exports.context = void 0; -const Context = __importStar(__nccwpck_require__(53)); +const Context = __importStar(__nccwpck_require__(87)); const utils_1 = __nccwpck_require__(30); exports.context = new Context.Context(); /** @@ -875,7 +570,7 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.getOctokitOptions = exports.GitHub = exports.context = void 0; -const Context = __importStar(__nccwpck_require__(53)); +const Context = __importStar(__nccwpck_require__(87)); const Utils = __importStar(__nccwpck_require__(914)); // octokit + plugins const core_1 = __nccwpck_require__(762); @@ -916,8 +611,8 @@ exports.getOctokitOptions = getOctokitOptions; "use strict"; Object.defineProperty(exports, "__esModule", ({ value: true })); -const http = __nccwpck_require__(605); -const https = __nccwpck_require__(211); +const http = __nccwpck_require__(685); +const https = __nccwpck_require__(687); const pm = __nccwpck_require__(443); let tunnel; var HttpCodes; @@ -4045,11 +3740,11 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -var Stream = _interopDefault(__nccwpck_require__(413)); -var http = _interopDefault(__nccwpck_require__(605)); -var Url = _interopDefault(__nccwpck_require__(835)); -var https = _interopDefault(__nccwpck_require__(211)); -var zlib = _interopDefault(__nccwpck_require__(761)); +var Stream = _interopDefault(__nccwpck_require__(781)); +var http = _interopDefault(__nccwpck_require__(685)); +var Url = _interopDefault(__nccwpck_require__(310)); +var https = _interopDefault(__nccwpck_require__(687)); +var zlib = _interopDefault(__nccwpck_require__(796)); // Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js @@ -4200,7 +3895,7 @@ FetchError.prototype.name = 'FetchError'; let convert; try { - convert = __nccwpck_require__(877).convert; + convert = (__nccwpck_require__(877).convert); } catch (e) {} const INTERNALS = Symbol('Body internals'); @@ -5683,7 +5378,7 @@ fetch.Promise = global.Promise; module.exports = exports = fetch; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.default = exports; +exports["default"] = exports; exports.Headers = Headers; exports.Request = Request; exports.Response = Response; @@ -5755,13 +5450,13 @@ module.exports = __nccwpck_require__(219); "use strict"; -var net = __nccwpck_require__(631); -var tls = __nccwpck_require__(16); -var http = __nccwpck_require__(605); -var https = __nccwpck_require__(211); -var events = __nccwpck_require__(614); -var assert = __nccwpck_require__(357); -var util = __nccwpck_require__(669); +var net = __nccwpck_require__(808); +var tls = __nccwpck_require__(404); +var http = __nccwpck_require__(685); +var https = __nccwpck_require__(687); +var events = __nccwpck_require__(361); +var assert = __nccwpck_require__(491); +var util = __nccwpck_require__(837); exports.httpOverHttp = httpOverHttp; @@ -6082,172 +5777,510 @@ function wrappy (fn, cb) { } return ret } -} +} + + +/***/ }), + +/***/ 877: +/***/ ((module) => { + +module.exports = eval("require")("encoding"); + + +/***/ }), + +/***/ 491: +/***/ ((module) => { + +"use strict"; +module.exports = require("assert"); + +/***/ }), + +/***/ 361: +/***/ ((module) => { + +"use strict"; +module.exports = require("events"); + +/***/ }), + +/***/ 147: +/***/ ((module) => { + +"use strict"; +module.exports = require("fs"); + +/***/ }), + +/***/ 685: +/***/ ((module) => { + +"use strict"; +module.exports = require("http"); + +/***/ }), + +/***/ 687: +/***/ ((module) => { + +"use strict"; +module.exports = require("https"); + +/***/ }), + +/***/ 808: +/***/ ((module) => { + +"use strict"; +module.exports = require("net"); + +/***/ }), + +/***/ 37: +/***/ ((module) => { + +"use strict"; +module.exports = require("os"); + +/***/ }), + +/***/ 17: +/***/ ((module) => { + +"use strict"; +module.exports = require("path"); + +/***/ }), + +/***/ 781: +/***/ ((module) => { + +"use strict"; +module.exports = require("stream"); + +/***/ }), + +/***/ 404: +/***/ ((module) => { + +"use strict"; +module.exports = require("tls"); + +/***/ }), + +/***/ 310: +/***/ ((module) => { + +"use strict"; +module.exports = require("url"); + +/***/ }), + +/***/ 837: +/***/ ((module) => { + +"use strict"; +module.exports = require("util"); + +/***/ }), + +/***/ 796: +/***/ ((module) => { + +"use strict"; +module.exports = require("zlib"); + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __nccwpck_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ var threw = true; +/******/ try { +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __nccwpck_require__); +/******/ threw = false; +/******/ } finally { +/******/ if(threw) delete __webpack_module_cache__[moduleId]; +/******/ } +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __nccwpck_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/compat */ +/******/ +/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/"; +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be in strict mode. +(() => { +"use strict"; +// ESM COMPAT FLAG +__nccwpck_require__.r(__webpack_exports__); + +// EXTERNAL MODULE: ./node_modules/@actions/core/lib/core.js +var core = __nccwpck_require__(186); +// EXTERNAL MODULE: ./node_modules/@actions/github/lib/github.js +var github = __nccwpck_require__(438); +;// CONCATENATED MODULE: ./identifier.js +function getCommentPrefix(identifier) { + return ``; +} + +;// CONCATENATED MODULE: ./comment/issue_commenter.js +class IssueCommenter { + constructor(octokit, { owner, repo, number }) { + this.octokit = octokit; + this.owner = owner; + this.repo = repo; + this.number = number; + } + + createComment(comment) { + return this.octokit.issues.createComment({ + owner: this.owner, + repo: this.repo, + issue_number: this.number, + body: comment, + }); + } + + deleteComment(commentID) { + return this.octokit.issues.deleteComment({ + owner: this.owner, + repo: this.repo, + comment_id: commentID, + }); + } + + listComments(opts) { + return this.octokit.issues.listComments({ + owner: this.owner, + repo: this.repo, + issue_number: this.number, + page: opts.page, + per_page: opts.perPage, + }); + } + + updateComment(commentID, comment) { + return this.octokit.issues.updateComment({ + owner: this.owner, + repo: this.repo, + comment_id: commentID, + body: comment, + }); + } +} + +;// CONCATENATED MODULE: ./comment/commit_commenter.js +class CommitCommenter { + constructor(octokit, { owner, repo, commitSHA }) { + this.octokit = octokit; + this.owner = owner; + this.repo = repo; + this.commitSHA = commitSHA; + } + + createComment(comment) { + return this.octokit.repos.createCommitComment({ + owner: this.owner, + repo: this.repo, + commit_sha: this.commitSHA, + body: comment, + }); + } + deleteComment(commentID) { + return this.octokit.repos.deleteCommitComment({ + owner: this.owner, + repo: this.repo, + comment_id: commentID, + }); + } -/***/ }), + listComments(opts) { + return this.octokit.repos.listCommentsForCommit({ + owner: this.owner, + repo: this.repo, + commit_sha: this.commitSHA, + page: opts.page, + per_page: opts.perPage, + }); + } -/***/ 877: -/***/ ((module) => { + updateComment(commentID, comment) { + return this.octokit.repos.updateCommitComment({ + owner: this.owner, + repo: this.repo, + comment_id: commentID, + body: comment, + }); + } +} -module.exports = eval("require")("encoding"); +;// CONCATENATED MODULE: ./comment/commenter.js -/***/ }), -/***/ 357: -/***/ ((module) => { -"use strict"; -module.exports = require("assert");; +function getCommenter(octokit, { + owner, repo, number, commitSHA, +}) { + if ((number && commitSHA) || (!number && !commitSHA)) { + throw new Error('Either set the `number` or the `commit-sha` field.'); + } + if (number) { + return new IssueCommenter(octokit, { owner, repo, number }); + } + if (commitSHA) { + return new CommitCommenter(octokit, { owner, repo, commitSHA }); + } + return null; +} -/***/ }), +async function findMatchingComments(commenter, identifier) { + let fetchMoreComments = true; + let page = 0; + const matchingComments = []; + const commentPrefix = getCommentPrefix(identifier); -/***/ 614: -/***/ ((module) => { + while (fetchMoreComments) { + page += 1; + const comments = await commenter.listComments({ + page, + perPage: 100, + }); + fetchMoreComments = comments.data.length !== 0; + for (const comment of comments.data) { + if (comment.body.startsWith(commentPrefix)) { + matchingComments.push(comment); + } + } + } + return matchingComments; +} -"use strict"; -module.exports = require("events");; +async function findMatchingComment(commenter, identifier) { + const matchingComments = await findMatchingComments(commenter, identifier); + let matchingComment; + if (matchingComments && matchingComments.length > 0) { + matchingComment = matchingComments[matchingComments.length - 1]; + } + return matchingComment; +} -/***/ }), +;// CONCATENATED MODULE: ./modes.js -/***/ 747: -/***/ ((module) => { -"use strict"; -module.exports = require("fs");; -/***/ }), +// normal mode creates a comment when there is no existing comment that match identifier +// and updates the matching comment if found +async function normalMode(commenter, identifier, message) { + console.log(`Checking if a comment already exists for ${identifier}.`); + const matchingComment = await findMatchingComment(commenter, identifier); -/***/ 605: -/***/ ((module) => { + const comment = `${getCommentPrefix(identifier)}\n${message}`; -"use strict"; -module.exports = require("http");; + if (matchingComment) { + console.log(`Updating an existing comment for ${identifier}.`); + const resp = await commenter.updateComment(matchingComment.id, comment); + console.log(`Updated comment: ${resp.data.html_url}`); + return; + } -/***/ }), + console.log(`Creating a new comment for ${identifier}.`); + const resp = await commenter.createComment(comment); + console.log(`Created comment: ${resp.data.html_url}`); +} -/***/ 211: -/***/ ((module) => { +// recreate mode deletes existing comments that match the identifier +// and creates a new comment +async function recreateMode(commenter, identifier, message) { + console.log(`Finding matching comments for ${identifier}.`); + const matchingComments = await findMatchingComments(commenter, identifier); -"use strict"; -module.exports = require("https");; + for (const comment of matchingComments) { + console.log(`Deleting github comment ${comment.id}`); + await commenter.deleteComment(comment.id); + } -/***/ }), + console.log(`Creating a new comment for ${identifier}.`); + const comment = `${getCommentPrefix(identifier)}\n${message}`; + const resp = await commenter.createComment(comment); + console.log(`Created comment: ${resp.data.html_url}`); +} -/***/ 631: -/***/ ((module) => { +// append mode creates a comment when there is no existing comment that match identifier +// and appends message to a matching comment if found. +async function appendMode(commenter, identifier, message) { + console.log(`Checking if a comment already exists for ${identifier}.`); + const matchingComment = await findMatchingComment(commenter, identifier); -"use strict"; -module.exports = require("net");; + if (matchingComment) { + console.log(`Updating an existing comment for ${identifier}.`); + const comment = `${matchingComment.body}\n${message}`; + const resp = await commenter.updateComment(matchingComment.id, comment); + console.log(`Updated comment: ${resp.data.html_url}`); + return; + } -/***/ }), + console.log(`Creating a new comment for ${identifier}.`); + const comment = `${getCommentPrefix(identifier)}\n${message}`; + const resp = await commenter.createComment(comment); + console.log(`Created comment: ${resp.data.html_url}`); +} -/***/ 87: -/***/ ((module) => { +// replace mode replaces the content of an existing comment that matches the identifier +// with the message. +async function replaceMode(commenter, identifier, message) { + console.log(`Checking if a comment already exists for ${identifier}.`); + const matchingComment = await findMatchingComment(commenter, identifier); -"use strict"; -module.exports = require("os");; + const comment = `${getCommentPrefix(identifier)}\n${message}`; -/***/ }), + if (matchingComment) { + console.log(`Updating an existing comment for ${identifier}.`); + const resp = await commenter.updateComment(matchingComment.id, comment); + console.log(`Updated comment: ${resp.data.html_url}`); + return; + } -/***/ 622: -/***/ ((module) => { + console.log(`Creating a new comment for ${identifier}.`); + const resp = await commenter.createComment(comment); + console.log(`Created comment: ${resp.data.html_url}`); +} -"use strict"; -module.exports = require("path");; +// delete mode deletes an existing comment that matches the identifier +async function deleteMode(commenter, identifier) { + console.log(`Finding matching comment for ${identifier}.`); + const matchingComment = await findMatchingComment(commenter, identifier); -/***/ }), + if (matchingComment) { + console.log(`Deleting github comment ${matchingComment.id}`); + await commenter.deleteComment(matchingComment.id); + } +} -/***/ 413: -/***/ ((module) => { +;// CONCATENATED MODULE: ./index.js -"use strict"; -module.exports = require("stream");; -/***/ }), -/***/ 16: -/***/ ((module) => { -"use strict"; -module.exports = require("tls");; -/***/ }), +(async () => { + try { + const repository = core.getInput('repository'); + const [owner, repo] = repository.split('/'); + if (!owner || !repo) { + throw new Error(`Invalid repository: ${repository}`); + } -/***/ 835: -/***/ ((module) => { + const number = core.getInput('number'); + const commitSHA = core.getInput('commit-sha'); + const identifier = core.getInput('id'); + const fail = core.getInput('fail'); + const githubToken = core.getInput('github-token'); + const message = core.getInput('message'); -"use strict"; -module.exports = require("url");; + const appendComment = core.getInput('append'); + const replaceComment = core.getInput('replace'); + const recreateComment = core.getInput('recreate'); + const deleteComment = core.getInput('delete'); -/***/ }), + const octokit = github.getOctokit(githubToken); -/***/ 669: -/***/ ((module) => { + let commenter; + try { + commenter = getCommenter(octokit, { + owner, + repo, + number, + commitSHA, + }); + } catch (err) { + core.setFailed(err); + return; + } -"use strict"; -module.exports = require("util");; + const effectiveModes = [ + { name: 'recreate', flag: recreateComment }, + { name: 'append', flag: appendComment }, + { name: 'replace', flag: replaceComment }, + { name: 'delete', flag: deleteComment }, + ].filter((m) => m.flag === 'true'); -/***/ }), + if (effectiveModes.length > 1) { + const effectiveModeNames = effectiveModes.map((m) => m.name).join(', '); + core.setFailed(`Only one of ${effectiveModeNames} can be set to true.`); + return; + } -/***/ 761: -/***/ ((module) => { + let mode; + + switch (effectiveModes[0].name) { + case 'recreate': + mode = recreateMode; + break; + case 'append': + mode = appendMode; + break; + case 'replace': + mode = replaceMode; + break; + case 'delete': + mode = deleteMode; + break; + default: + mode = normalMode; + break; + } -"use strict"; -module.exports = require("zlib");; + await mode(commenter, identifier, message); -/***/ }) + if (fail === 'true') { + core.setFailed(message); + } + } catch (error) { + console.error(error); + core.setFailed(error.message); + } +})(); -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __nccwpck_require__(moduleId) { -/******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ var threw = true; -/******/ try { -/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __nccwpck_require__); -/******/ threw = false; -/******/ } finally { -/******/ if(threw) delete __webpack_module_cache__[moduleId]; -/******/ } -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __nccwpck_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/compat */ -/******/ -/******/ __nccwpck_require__.ab = __dirname + "/";/************************************************************************/ -/******/ // module exports must be returned from runtime so entry inlining is disabled -/******/ // startup -/******/ // Load entry module and return exports -/******/ return __nccwpck_require__(752); +})(); + +module.exports = __webpack_exports__; /******/ })() ; \ No newline at end of file diff --git a/index.js b/index.js index ab08b82..fe4d840 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,8 @@ import * as core from '@actions/core'; import * as github from '@actions/github'; -import { normalMode, recreateMode, appendMode, deleteMode } from './modes'; +import { + normalMode, recreateMode, appendMode, deleteMode, replaceMode, +} from './modes'; import { getCommenter } from './comment/commenter'; (async () => { @@ -14,13 +16,15 @@ import { getCommenter } from './comment/commenter'; const number = core.getInput('number'); const commitSHA = core.getInput('commit-sha'); const identifier = core.getInput('id'); - const appendComment = core.getInput('append'); - const recreateComment = core.getInput('recreate'); - const deleteComment = core.getInput('delete'); const fail = core.getInput('fail'); const githubToken = core.getInput('github-token'); const message = core.getInput('message'); + const appendComment = core.getInput('append'); + const replaceComment = core.getInput('replace'); + const recreateComment = core.getInput('recreate'); + const deleteComment = core.getInput('delete'); + const octokit = github.getOctokit(githubToken); let commenter; @@ -36,24 +40,37 @@ import { getCommenter } from './comment/commenter'; return; } - let mode = normalMode; + const effectiveModes = [ + { name: 'recreate', flag: recreateComment }, + { name: 'append', flag: appendComment }, + { name: 'replace', flag: replaceComment }, + { name: 'delete', flag: deleteComment }, + ].filter((m) => m.flag === 'true'); - if (appendComment === 'true' && recreateComment === 'true') { - core.setFailed('Not allowed to set both `append` and `recreate` to true.'); + if (effectiveModes.length > 1) { + const effectiveModeNames = effectiveModes.map((m) => m.name).join(', '); + core.setFailed(`Only one of ${effectiveModeNames} can be set to true.`); return; } - if (deleteComment === 'true' && (appendComment === 'true' || recreateComment === 'true')) { - core.setFailed('Not allowed to set `delete` to true with `append` or `recreate`.'); - return; - } + let mode; - if (recreateComment === 'true') { - mode = recreateMode; - } else if (appendComment === 'true') { - mode = appendMode; - } else if (deleteComment === 'true') { - mode = deleteMode; + switch (effectiveModes[0].name) { + case 'recreate': + mode = recreateMode; + break; + case 'append': + mode = appendMode; + break; + case 'replace': + mode = replaceMode; + break; + case 'delete': + mode = deleteMode; + break; + default: + mode = normalMode; + break; } await mode(commenter, identifier, message); diff --git a/modes.js b/modes.js index 677278b..1c60ccf 100644 --- a/modes.js +++ b/modes.js @@ -58,6 +58,26 @@ export async function appendMode(commenter, identifier, message) { console.log(`Created comment: ${resp.data.html_url}`); } +// replace mode replaces the content of an existing comment that matches the identifier +// with the message. +export async function replaceMode(commenter, identifier, message) { + console.log(`Checking if a comment already exists for ${identifier}.`); + const matchingComment = await findMatchingComment(commenter, identifier); + + const comment = `${getCommentPrefix(identifier)}\n${message}`; + + if (matchingComment) { + console.log(`Updating an existing comment for ${identifier}.`); + const resp = await commenter.updateComment(matchingComment.id, comment); + console.log(`Updated comment: ${resp.data.html_url}`); + return; + } + + console.log(`Creating a new comment for ${identifier}.`); + const resp = await commenter.createComment(comment); + console.log(`Created comment: ${resp.data.html_url}`); +} + // delete mode deletes an existing comment that matches the identifier export async function deleteMode(commenter, identifier) { console.log(`Finding matching comment for ${identifier}.`); diff --git a/package-lock.json b/package-lock.json index 146985d..d6b3a4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "comment-progress", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "comment-progress", - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "dependencies": { "@actions/core": "^1.2.6", "@actions/github": "^4.0.0" }, "devDependencies": { - "@vercel/ncc": "^0.27.0", + "@vercel/ncc": "^0.38.1", "eslint": "^7.29.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-plugin-import": "^2.23.4" @@ -233,9 +233,9 @@ "integrity": "sha512-Ecfmo4YDQPwuqTCl1yBxLV5ihKfRlkBmzUEDcfIRvDxOTGQEeikr317Ln7Gcv0tjA8dVgKI3rniqW2G1OyKDng==" }, "node_modules/@vercel/ncc": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.27.0.tgz", - "integrity": "sha512-DllIJQapnU2YwewIhh/4dYesmMQw3h2cFtabECc/zSJHqUbNa0eJuEkRa6DXbZvh1YPWBtYQoPV17NlDpBw1Vw==", + "version": "0.38.1", + "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.1.tgz", + "integrity": "sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw==", "dev": true, "bin": { "ncc": "dist/ncc/cli.js" diff --git a/package.json b/package.json index 9c9013d..574319e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "comment-progress", - "version": "1.0.0", + "version": "1.0.1", "description": "", "main": "index.js", "scripts": { @@ -20,7 +20,7 @@ "@actions/github": "^4.0.0" }, "devDependencies": { - "@vercel/ncc": "^0.27.0", + "@vercel/ncc": "^0.38.1", "eslint": "^7.29.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-plugin-import": "^2.23.4"