Skip to content

Commit

Permalink
v.2.5.0: Webhooks integration.
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelmhtr committed Sep 6, 2022
1 parent d1fb808 commit 59252e6
Show file tree
Hide file tree
Showing 26 changed files with 494 additions and 44 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog
All notable changes to this project will be documented in this file.

## [2.5.0] - 2022-09-05
### Added
- Webhooks integration.

## [2.4.6] - 2022-09-01
### Fixed
- [#48](https://github.com/flowwer-dev/pull-request-stats/issues/48) Prevent sponsorship query error on Github Enterprise environments.
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ The possible inputs for this action are:
| `sort-by` | The column used to sort the data. Possible values: `REVIEWS`, `TIME`, `COMMENTS`. | `REVIEWS` |
| `publish-as` | Where to publish the results. Possible values: as a `COMMENT`, on the pull request `DESCRIPTION`. | `COMMENT` |
| `telemetry` | Indicates if the action is allowed to send monitoring data to the developer. This data is [minimal](/src/services/telemetry/sendStart.js) and helps me improve this action. **This option is a premium feature reserved for [sponsors](#premium-features-).** |`true`|
| `slack-webhook` | A Slack webhook URL to post resulting stats. **This option is a premium feature reserved for [sponsors](#premium-features-).** |`null`|
| `slack-webhook` | **🔥 New.** A Slack webhook URL to post resulting stats. **This option is a premium feature reserved for [sponsors](#premium-features-).** |`null`|
| `slack-channel` | The Slack channel where stats will be posted. Include the `#` character (eg. `#mychannel`). Required when a `slack-webhook` is configured. |`null`|
| `webhook` | **🔥 New.** A webhook URL to send the resulting stats as JSON (integrate with Zapier, IFTTT...). See [full documentation here](/docs/webhook.md). |`null`|


## Examples
Expand Down Expand Up @@ -201,6 +202,7 @@ This action offers some premium features only for sponsors:

* Disabling telemetry.
* Slack integration.
* Comming soon: Microsoft teams and discord integrations.

No minimum amount is required for now. In the future, a minimum monthly sponsorship will be inforced to access premium features.

Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ inputs:
description: 'Prevents from adding any external links in the stats'
required: false
default: false
webhook:
description: 'A webhook URL to post resulting stats.'
required: false
telemetry:
description: 'Indicates if the action is allowed to send monitoring data to the developer.'
required: false
Expand Down
147 changes: 127 additions & 20 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,8 @@ const { sum, median, divide } = __webpack_require__(353);
const getProperty = (list, prop) => list.map((el) => el[prop]);

module.exports = (reviews) => {
const pullIds = getProperty(reviews, 'pullId');
const totalReviews = new Set(pullIds).size;
const pullRequestIds = getProperty(reviews, 'pullRequestId');
const totalReviews = new Set(pullRequestIds).size;
const totalComments = sum(getProperty(reviews, 'commentsCount'));

return {
Expand All @@ -647,7 +647,7 @@ module.exports = (reviews) => {
/***/ 61:
/***/ (function(module) {

module.exports = {"slack":{"logs":{"notConfigured":"Slack integration is disabled. No webhook or channel configured.","posting":"Post a Slack message with params: {{params}}","success":"Successfully posted to slack"},"errors":{"notSponsor":"Slack integration is a premium feature, available to sponsors.\n(If you are already an sponsor, please make sure it configured as public).","requestFailed":"Error posting Slack message: {{error}}"}}};
module.exports = {"slack":{"logs":{"notConfigured":"Slack integration is disabled. No webhook or channel configured.","posting":"Post a Slack message with params: {{params}}","success":"Successfully posted to slack"},"errors":{"notSponsor":"Slack integration is a premium feature, available to sponsors.\n(If you are already an sponsor, please make sure it configured as public).","requestFailed":"Error posting Slack message: {{error}}"}},"webhook":{"logs":{"notConfigured":"Webhook integration is disabled.","posting":"Post a Slack message with params: {{params}}","success":"Successfully posted to slack"},"errors":{"requestFailed":"Error posting Webhook: {{error}}"}}};

/***/ }),

Expand Down Expand Up @@ -1247,6 +1247,28 @@ module.exports = {
};


/***/ }),

/***/ 108:
/***/ (function(module) {

const parseReviewer = ({ contributions, ...other }) => other;

module.exports = ({
org,
repos,
reviewers,
periodLength,
}) => ({
reviewers: reviewers.map(parseReviewer),
options: {
periodLength,
organization: org || null,
repositories: org ? null : repos,
},
});


/***/ }),

/***/ 109:
Expand Down Expand Up @@ -2104,6 +2126,7 @@ const fetchPullRequestById = __webpack_require__(105);
const fetchPullRequests = __webpack_require__(593);
const fetchSponsorships = __webpack_require__(104);
const postToSlack = __webpack_require__(887);
const postToWebhook = __webpack_require__(205);
const updatePullRequest = __webpack_require__(664);

module.exports = {
Expand All @@ -2112,6 +2135,7 @@ module.exports = {
fetchPullRequests,
fetchSponsorships,
postToSlack,
postToWebhook,
updatePullRequest,
};

Expand Down Expand Up @@ -2417,6 +2441,23 @@ const calculateTotals = (allStats) => STATS.reduce((prev, statName) => ({
module.exports = calculateTotals;


/***/ }),

/***/ 205:
/***/ (function(module, __unusedexports, __webpack_require__) {

const axios = __webpack_require__(53);

module.exports = ({
payload,
webhook,
}) => axios({
method: 'post',
url: webhook,
data: payload,
});


/***/ }),

/***/ 211:
Expand Down Expand Up @@ -8354,6 +8395,26 @@ function createAgent(callback, opts) {
module.exports = createAgent;
//# sourceMappingURL=index.js.map

/***/ }),

/***/ 445:
/***/ (function(module, __unusedexports, __webpack_require__) {

const { STATS } = __webpack_require__(648);

const calculatePercentage = (value, total) => {
if (!total) return 0;
return Math.min(1, Math.max(0, value / total));
};

const getContributions = (reviewer, totals) => STATS.reduce((prev, statsName) => {
const percentage = calculatePercentage(reviewer.stats[statsName], totals[statsName]);
return { ...prev, [statsName]: percentage };
}, {});

module.exports = getContributions;


/***/ }),

/***/ 448:
Expand Down Expand Up @@ -10248,10 +10309,12 @@ exports.FetchError = FetchError;
/***/ 455:
/***/ (function(module, __unusedexports, __webpack_require__) {

const execution = __webpack_require__(861);
const integrations = __webpack_require__(61);
const table = __webpack_require__(680);

module.exports = {
execution,
integrations,
table,
};
Expand Down Expand Up @@ -13833,19 +13896,43 @@ exports.default = parseProxyResponse;
/***/ 660:
/***/ (function(module, __unusedexports, __webpack_require__) {

const { STATS } = __webpack_require__(648);
const { t } = __webpack_require__(781);
const { postToWebhook } = __webpack_require__(162);
const buildPayload = __webpack_require__(108);

const calculatePercentage = (value, total) => {
if (!total) return 0;
return Math.min(1, Math.max(0, value / total));
};
module.exports = async ({
org,
repos,
core,
webhook,
reviewers,
periodLength,
}) => {
if (!webhook) {
core.debug(t('integrations.webhook.logs.notConfigured'));
return;
}

const getContributions = (reviewer, totals) => STATS.reduce((prev, statsName) => {
const percentage = calculatePercentage(reviewer.stats[statsName], totals[statsName]);
return { ...prev, [statsName]: percentage };
}, {});
const payload = buildPayload({
org,
repos,
reviewers,
periodLength,
});

module.exports = getContributions;
const params = { payload, webhook };

core.debug(t('integrations.webhook.logs.posting', {
params: JSON.stringify(params, null, 2),
}));

await postToWebhook({ payload, webhook }).catch((error) => {
core.error(t('integrations.webhook.errors.requestFailed', { error }));
throw error;
});

core.debug(t('integrations.webhook.logs.success'));
};


/***/ }),
Expand All @@ -13868,6 +13955,7 @@ const {
checkSponsorship,
alreadyPublished,
postSlackMessage,
postWebhook,
} = __webpack_require__(942);

const run = async (params) => {
Expand Down Expand Up @@ -13920,6 +14008,7 @@ const run = async (params) => {
});
core.debug(`Commit content built successfully: ${content}`);

await postWebhook({ ...params, core, reviewers });
await postSlackMessage({
...params,
core,
Expand Down Expand Up @@ -14710,6 +14799,7 @@ const get = __webpack_require__(854);
const core = __webpack_require__(470);
const github = __webpack_require__(469);
const execute = __webpack_require__(662);
const { t } = __webpack_require__(781);

const parseArray = (value) => value.split(',');

Expand Down Expand Up @@ -14745,6 +14835,7 @@ const getParams = () => {
pullRequestId: getPrId(),
limit: parseInt(core.getInput('limit'), 10),
telemetry: core.getBooleanInput('telemetry'),
webhook: core.getInput('webhook'),
slack: {
webhook: core.getInput('slack-webhook'),
channel: core.getInput('slack-channel'),
Expand All @@ -14755,9 +14846,10 @@ const getParams = () => {
const run = async () => {
try {
await execute(getParams());
core.info('Action successfully executed');
core.info(t('execution.logs.success'));
core.info(t('execution.logs.news'));
} catch (error) {
core.debug(`Execution failed with error: ${error.message}`);
core.debug(t('execution.errors.main', error));
core.debug(error.stack);
core.setFailed(error.message);
}
Expand Down Expand Up @@ -14942,7 +15034,7 @@ module.exports = function bind(fn, thisArg) {
/***/ 731:
/***/ (function(module) {

module.exports = {"name":"pull-request-stats","version":"2.4.6","description":"Github action to print relevant stats about Pull Request reviewers","main":"dist/index.js","scripts":{"build":"ncc build src/index.js","test":"eslint src && yarn run build && jest"},"keywords":[],"author":"Manuel de la Torre","license":"MIT","jest":{"testEnvironment":"node","testMatch":["**/?(*.)+(spec|test).[jt]s?(x)"]},"dependencies":{"@actions/core":"^1.5.0","@actions/github":"^5.0.0","@sentry/react-native":"^3.4.2","axios":"^0.26.1","dotenv":"^16.0.1","graphql":"^16.5.0","graphql-anywhere":"^4.2.7","humanize-duration":"^3.27.0","i18n-js":"^3.9.2","jsurl":"^0.1.5","lodash":"^4.17.21","lodash.get":"^4.4.2","lottie-react-native":"^5.1.3","markdown-table":"^2.0.0","mixpanel":"^0.13.0"},"devDependencies":{"@zeit/ncc":"^0.22.3","eslint":"^7.32.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.24.1","eslint-plugin-jest":"^24.4.0","jest":"^27.0.6"},"funding":"https://github.com/sponsors/manuelmhtr"};
module.exports = {"name":"pull-request-stats","version":"2.5.0","description":"Github action to print relevant stats about Pull Request reviewers","main":"dist/index.js","scripts":{"build":"ncc build src/index.js","test":"eslint src && yarn run build && jest"},"keywords":[],"author":"Manuel de la Torre","license":"MIT","jest":{"testEnvironment":"node","testMatch":["**/?(*.)+(spec|test).[jt]s?(x)"]},"dependencies":{"@actions/core":"^1.5.0","@actions/github":"^5.0.0","@sentry/react-native":"^3.4.2","axios":"^0.26.1","dotenv":"^16.0.1","graphql":"^16.5.0","graphql-anywhere":"^4.2.7","humanize-duration":"^3.27.0","i18n-js":"^3.9.2","jsurl":"^0.1.5","lodash":"^4.17.21","lodash.get":"^4.4.2","lottie-react-native":"^5.1.3","markdown-table":"^2.0.0","mixpanel":"^0.13.0"},"devDependencies":{"@zeit/ncc":"^0.22.3","eslint":"^7.32.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.24.1","eslint-plugin-jest":"^24.4.0","jest":"^27.0.6"},"funding":"https://github.com/sponsors/manuelmhtr"};

/***/ }),

Expand Down Expand Up @@ -15247,7 +15339,7 @@ module.exports = (pulls) => {
const reviews = pull.reviews
.filter(removeOwnPulls)
.filter(removeWithEmptyId)
.map((r) => ({ ...r, pullId: pull.id }));
.map((r) => ({ ...r, pullRequestId: pull.id }));
return acc.concat(reviews);
}, []);

Expand Down Expand Up @@ -18213,6 +18305,13 @@ module.exports = ({
};


/***/ }),

/***/ 861:
/***/ (function(module) {

module.exports = {"logs":{"success":"Action successfully executed","news":"\n✨ New on v2.5:\n• Slack integration\n• Webhooks integration"},"errors":{"main":"Execution failed with error: {{message}}"}};

/***/ }),

/***/ 864:
Expand Down Expand Up @@ -18592,7 +18691,7 @@ module.exports = function () {
/***/ (function(module, __unusedexports, __webpack_require__) {

const buildReviewTimeLink = __webpack_require__(922);
const getContributions = __webpack_require__(660);
const getContributions = __webpack_require__(445);
const calculateTotals = __webpack_require__(202);
const sortByStats = __webpack_require__(914);

Expand Down Expand Up @@ -18637,10 +18736,14 @@ module.exports = ({
currentRepo,
limit,
tracker,
slack,
webhook,
}) => {
const owner = getRepoOwner(currentRepo);
const reposCount = (repos || []).length;
const orgsCount = org ? 1 : 0;
const usingSlack = !!(slack || {}).webhook;
const usingWebhook = !!webhook;

tracker.track('run', {
// Necessary to build the "Used by" section in Readme:
Expand All @@ -18655,6 +18758,8 @@ module.exports = ({
displayCharts,
disableLinks,
limit,
usingSlack,
usingWebhook,
});
};

Expand Down Expand Up @@ -20194,9 +20299,10 @@ const buildComment = __webpack_require__(641);
const checkSponsorship = __webpack_require__(402);
const getPulls = __webpack_require__(591);
const getReviewers = __webpack_require__(164);
const postComment = __webpack_require__(173);
const postSlackMessage = __webpack_require__(878);
const postWebhook = __webpack_require__(660);
const setUpReviewers = __webpack_require__(901);
const postComment = __webpack_require__(173);

module.exports = {
alreadyPublished,
Expand All @@ -20205,9 +20311,10 @@ module.exports = {
checkSponsorship,
getPulls,
getReviewers,
postComment,
postSlackMessage,
postWebhook,
setUpReviewers,
postComment,
};


Expand Down
Loading

0 comments on commit 59252e6

Please sign in to comment.