diff --git a/.eslintrc b/.eslintrc index b855931..a2b3e11 100644 --- a/.eslintrc +++ b/.eslintrc @@ -11,6 +11,9 @@ "ecmaVersion": "latest", "sourceType": "module" }, + "ignorePatterns": [ + "dist/**" + ], "globals": { "Promise": "readonly" }, diff --git a/.github/workflows/recap.yml b/.github/workflows/recap.yml new file mode 100644 index 0000000..1ec1fbe --- /dev/null +++ b/.github/workflows/recap.yml @@ -0,0 +1,14 @@ +name: Pull Request Recap + +on: + pull_request: + types: [opened] + +jobs: + stats: + runs-on: ubuntu-latest + steps: + - name: Recap changes + uses: flowwer-dev/recap@dev + with: + openai-apikey: ${{ secrets.OPENAI_APIKEY }} diff --git a/README.md b/README.md index 22c2723..27ebb03 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,22 @@ [![CI](https://github.com/flowwer-dev/recap/workflows/Tests/badge.svg)](https://github.com/flowwer-dev/recap/actions?query=workflow%3ATests) -Tired of writing long pull request descriptions? or worst, not writing them at all? +Tired of writing long pull request descriptions? or worse, not writing them at all? -This Github action will summarize the most important changes in a pull request using [GPT](https://openai.com/blog/chatgpt). +This Github action will summarize the most critical changes in a pull request using [GPT](https://openai.com/blog/chatgpt). The objective of this action is to: * Reduce the time spent writing the pull request description. * Help developers understand the changes before reviewing them. -Running this action will add a comment to the pull request with a summary of the changes. +Running this action will add a comment to the pull request summarizing the changes. [For example](https://github.com/flowwer-dev/recap/pull/1#issuecomment-1476682437): -![](/assets/exmaple.png) +![](/assets/example.png) ## Privacy * **No repository data is collected**, stored, or distributed by this GitHub action. This action is **state-less**. -* [Minimal data](/src/services/telemetry/sendStart.js) is sent to Mixpanel in order to improve this action. However, you can opt-out using the `telemetry` option. +* [Minimal data](/src/services/telemetry/sendStart.js) is sent to Mixpanel to improve this action. However, you can opt out using the `telemetry` option. ## Usage @@ -70,7 +70,7 @@ This config will: 1. Create an account on [OpenAI's developers site](https://platform.openai.com/docs/api-reference). 2. Go to Config > [View API Keys](https://platform.openai.com/account/api-keys). -3. Press the button `Create new secret key` and copy the value. +3. Press the `Create new secret key` button and copy the value. 4. Voilà! ## Troubleshooting @@ -96,8 +96,8 @@ This config will:
I'm a sponsor but still getting the error "...is a premium feature, available to sponsors". - 1. Check the sponsorship comes from the account that owns the configured repos (usually an organization). - 2. Make sure the sponsorship is configured as `public`, otherwise, the action cannot access the sponsorship information. If you prefer to keep it `private`, please reach me out to make it work for you that way 😉. + 1. Check the sponsorship comes from the account that owns the configured repository (usually an organization). + 2. Ensure the sponsorship is configured as `public`; otherwise, the action cannot access the sponsorship information. If you prefer to keep it `private`, please reach out to make it work for you that way 😉.
## Premium features ✨ @@ -105,16 +105,16 @@ This config will: This action offers some premium features only for sponsors: * Disabling telemetry. -* More comming soon. +* More coming soon. The **suggested sponsorship is $20 USD / month**. However, if it's not possible for you or your organization, please consider supporting it with any amount you can. Even a one-time sponsorship will enable the Premium features and encourage the progress of this project. -Beign a sponsor will also give you access to the premium features in all my [other projects](#related-projects). +Being a sponsor will also give you access to the premium features in all my [other projects](#related-projects). Thanks for your support! 💙 -## Related projects +## Related projects 🔥 * **[Pull Request Stats](https://github.com/flowwer-dev/pull-request-stats)**: Github action to print relevant stats about Pull Request **reviewers**. diff --git a/assets/example.png b/assets/example.png new file mode 100644 index 0000000..602fbd4 Binary files /dev/null and b/assets/example.png differ diff --git a/dist/index.js b/dist/index.js index e06746b..c17e985 100644 --- a/dist/index.js +++ b/dist/index.js @@ -55,6 +55,7 @@ module.exports = const core = __webpack_require__(470); const axios = __webpack_require__(53); const parser = __webpack_require__(202); +const { t } = __webpack_require__(781); const { getGptConfig } = __webpack_require__(508); const { logRequestError } = __webpack_require__(353); @@ -92,9 +93,12 @@ module.exports = ({ return axios(options) .then(parser(prompt)) .catch((error) => { - const msg = `Error getting GPT Recap with "${JSON.stringify(options)}"`; - core.debug(msg); + core.debug(t('execution.errors.gptRequest', { + options: JSON.stringify(options, null, 2), + })); + const response = error.response || {}; logRequestError(core, error); + if (response.status === 401) core.setFailed(t('execution.errors.badOpenaiApiKey')); throw error; }); }; @@ -5071,7 +5075,7 @@ const getParams = () => ({ pullRequestId: getPrId(), currentRepo: getCurrentRepo(), githubToken: core.getInput('github-token'), - openaiApiKey: core.getInput('openai-api-key'), + openaiApiKey: core.getInput('openai-apikey'), publishAs: core.getInput('publish-as'), useTelemetry: core.getBooleanInput('telemetry'), }); @@ -15997,7 +16001,7 @@ module.exports = get; /***/ 861: /***/ (function(module) { -module.exports = {"skip":"Skipping execution because recap was published already","logs":{"params":"Parameters:\n{{params}}","pullRequest":"Pull request fetched successfully:\n{{pullRequest}}","prPatch":"Pull request patch fetched successfully:\n{{prPatch}}","recap":"Recap calculated successfully:\n{{recap}}","postedComment":"Comment was successfully posted","success":"Action successfully executed"},"sponsors":{"thankYou":"Thanks for sponsoring this project! 💙","external":{"fetch":{"success":"External sponsors fetched successfully. {{data}}","error":"Failed to fetch external sponsors. {{error}}"}}},"errors":{"main":"Execution failed with error: {{message}}"}}; +module.exports = {"skip":"Skipping execution because recap was published already","logs":{"params":"Parameters:\n{{params}}","pullRequest":"Pull request fetched successfully:\n{{pullRequest}}","prPatch":"Pull request patch fetched successfully:\n{{prPatch}}","recap":"Recap calculated successfully:\n{{recap}}","postedComment":"Comment was successfully posted","success":"Action successfully executed"},"sponsors":{"thankYou":"Thanks for sponsoring this project! 💙","external":{"fetch":{"success":"External sponsors fetched successfully. {{data}}","error":"Failed to fetch external sponsors. {{error}}"}}},"errors":{"badOpenaiApiKey":"OpenAI API Key is invalid. Please check your configuration.","gptRequest":"Error getting GPT Recap with options:\n{{options}}","main":"Execution failed with error: {{message}}"}}; /***/ }), diff --git a/src/entrypoint.js b/src/entrypoint.js index 38ec489..263a084 100644 --- a/src/entrypoint.js +++ b/src/entrypoint.js @@ -12,7 +12,7 @@ const getParams = () => ({ pullRequestId: getPrId(), currentRepo: getCurrentRepo(), githubToken: core.getInput('github-token'), - openaiApiKey: core.getInput('openai-api-key'), + openaiApiKey: core.getInput('openai-apikey'), publishAs: core.getInput('publish-as'), useTelemetry: core.getBooleanInput('telemetry'), }); diff --git a/src/fetchers/getGptRecap/index.js b/src/fetchers/getGptRecap/index.js index 4667465..f07cd0b 100644 --- a/src/fetchers/getGptRecap/index.js +++ b/src/fetchers/getGptRecap/index.js @@ -1,6 +1,7 @@ const core = require('@actions/core'); const axios = require('axios'); const parser = require('./parser'); +const { t } = require('../../i18n'); const { getGptConfig } = require('../../config'); const { logRequestError } = require('../../utils'); @@ -38,9 +39,12 @@ module.exports = ({ return axios(options) .then(parser(prompt)) .catch((error) => { - const msg = `Error getting GPT Recap with "${JSON.stringify(options)}"`; - core.debug(msg); + core.debug(t('execution.errors.gptRequest', { + options: JSON.stringify(options, null, 2), + })); + const response = error.response || {}; logRequestError(core, error); + if (response.status === 401) core.setFailed(t('execution.errors.badOpenaiApiKey')); throw error; }); }; diff --git a/src/i18n/locales/en-US/execution.json b/src/i18n/locales/en-US/execution.json index 71307f8..da48fcf 100644 --- a/src/i18n/locales/en-US/execution.json +++ b/src/i18n/locales/en-US/execution.json @@ -18,6 +18,8 @@ } }, "errors": { + "badOpenaiApiKey": "OpenAI API Key is invalid. Please check your configuration.", + "gptRequest": "Error getting GPT Recap with options:\n{{options}}", "main": "Execution failed with error: {{message}}" } }