From 49717e4205f73c6a1d834d2306df761585aa625b Mon Sep 17 00:00:00 2001 From: Garret Alfert Date: Tue, 29 Dec 2020 18:24:42 +0100 Subject: [PATCH] Collect Gitea review contributions --- .env.example | 1 + .gitignore | 2 + index.js | 104 ++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 26 ++++++++++++ package.json | 15 +++++++ repos.json | 16 +++++++ 6 files changed, 164 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 index.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 repos.json diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..8e324f3 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +GITEA_TOKEN=your-token-here diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f0fc62a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/node_modules/ +.env diff --git a/index.js b/index.js new file mode 100644 index 0000000..ebbd2b8 --- /dev/null +++ b/index.js @@ -0,0 +1,104 @@ +require('dotenv').config() + +const axios = require('axios'); + +const pageLimit = 50; +const kreditsAmounts = { + 'kredits-1': 100, + 'kredits-2': 300, + 'kredits-3': 1000 +}; + +const repos = require('./repos.json'); + +const gitea = axios.create({ + baseURL: 'https://gitea.kosmos.org/api/v1', + headers: { + 'accepts': 'application/json', + 'Authorization': `token ${process.env.GITEA_TOKEN}` + } +}); + +// TODO get the dates from params or user input +const startDate = new Date('2020-11-01T00:00:00Z'); +const endDate = new Date('2020-12-30T23:59:59Z'); + +async function getGiteaReviewContributions (repos) { + let pulls = []; + let reviewContributions = {} + + await Promise.all(repos.map(async (repo) => { + let page = 1; + let result; + + do { + try { + result = await gitea.get(`/repos/${repo}/pulls?state=closed&limit=${pageLimit}&page=${page}`); + } catch(error) { + console.log(`failed to fetch PRs for repo ${repo}:`, error); + continue; + } + + if (!result || !result.data || result.data.length === 0) { + continue; + } + + let pullRequests = result.data.filter(pr => { + if (!pr.merged) return false; // only interested in merged PRs + + // check if the PR has been merged in the given timeframe + const mergeDate = new Date(pr.merged_at); + if (mergeDate < startDate || mergeDate > endDate) return false; + + // check if the PR has a kredits label + return pr.labels + .map(label => label.name) + .some(labelname => labelname.match(/kredits-[123]/)); + }); + + await Promise.all(pullRequests.map(async (pr) => { + let reviews; + try { + reviews = await gitea.get(`/repos/${repo}/pulls/${pr.number}/reviews`); + } catch(error) { + console.log(`failed to fetch reviews for repo ${repo}, PR ${pr.number}:`, error); + return; + } + + if (!reviews || !reviews.data || reviews.data.length === 0) { + return; + } + + reviews = reviews.data.filter(review => { + return ['APPROVED', 'REJECTED'].includes(review.state); + }); + + reviews.forEach(review => { + if (typeof reviewContributions[review.user.login] === 'undefined') { + reviewContributions[review.user.login] = []; + } + + let kreditsLabel = pr.labels.find(label => label.name.match(/kredits-[123]/)); + + reviewContributions[review.user.login].push({ + pr, + prNumber: pr.number, + review, + reviewState: review.state, + kredits: kreditsAmounts[kreditsLabel.name] + }); + + }); + })); + + page++; + } while (result.data && result.data.length > 0); + })); + + return reviewContributions; +} + +getGiteaReviewContributions(repos.gitea).then(reviewContributions => { + console.log('REVIEW CONTRIBUTIONS', reviewContributions); +}); + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8e019ab --- /dev/null +++ b/package-lock.json @@ -0,0 +1,26 @@ +{ + "name": "kredits-reviews", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" + }, + "follow-redirects": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d6af49e --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "kredits-reviews", + "version": "1.0.0", + "description": "Create Kosmos Kredits contributions for code reviews", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Garret Alfert", + "license": "ISC", + "dependencies": { + "axios": "^0.21.1", + "dotenv": "^8.2.0" + } +} diff --git a/repos.json b/repos.json new file mode 100644 index 0000000..688ba92 --- /dev/null +++ b/repos.json @@ -0,0 +1,16 @@ +{ + "github": [ + "67P/kredits-contracts", + "67P/kredits-web", + "sockethub/sockethub" + ], + "gitea": [ + "kosmos/akkounts", + "kosmos/chef", + "kosmos/wormhole", + "kosmos/ipfs-cookbook", + "kosmos/kredits-ipfs-pinner", + "kosmos/website", + "kosmos/gitea.kosmos.org" + ] +}