Verified Commit ae5fe7d1 authored by Adam Zerella's avatar Adam Zerella
Browse files

Tweaking linting config and running on main script

parent 3a0d5aa9
{
"extends": [
"eslint:recommended",
"prettier"
],
"env": {
"commonjs": true
}
}
\ No newline at end of file
"extends": ["eslint:recommended", "prettier"],
"parserOptions": {
"ecmaVersion": "latest"
},
"env": {
"node": true,
"commonjs": true,
"es6": true
},
"rules": {
"prefer-const": "warn"
}
}
{
"trailingComma": "es5",
"tabWidth": 2,
"singleQuote": true
}
\ No newline at end of file
"trailingComma": "es5",
"tabWidth": 2,
"singleQuote": true,
"semi": true,
"bracketSpacing": true
}
......@@ -4,11 +4,11 @@
*/
module.exports = (app) => {
// Your code here
app.log.info("Tip bot was loaded!");
app.log.info('Tip bot was loaded!');
app.on("issue_comment", async (context) => {
app.on('issue_comment', async (context) => {
// Get all the relevant contextual information.
let commentText = context.payload.comment.body
let commentText = context.payload.comment.body;
let pullRequestBody = context.payload.issue.body;
let pullRequestUrl = context.payload.issue.html_url;
let tipper = context.payload.comment.user.login;
......@@ -18,11 +18,14 @@ module.exports = (app) => {
// The bot only triggers on creation of a new comment on a pull request.
if (
!context.payload.issue.hasOwnProperty("pull_request") ||
context.payload.action !== "created" ||
!commentText.startsWith("/tip")
!Object.prototype.hasOwnProperty.call(
context.payload.issue,
'pull_request'
) ||
context.payload.action !== 'created' ||
!commentText.startsWith('/tip')
) {
return
return;
}
// Any problems along the way will be stored here, and used to return an error if needed.
......@@ -40,7 +43,9 @@ module.exports = (app) => {
// TODO temporarily, only allow whitelisted users access to the bot.
if (!process.env.ALLOWED_USERS.includes(tipper)) {
problemsText.push(`You are not allowed to access the tip bot. Only ${process.env.ALLOWED_USERS} are allowed.`)
problemsText.push(
`You are not allowed to access the tip bot. Only ${process.env.ALLOWED_USERS} are allowed.`
);
}
// We will populate this information by processing the pull request and tip comment.
......@@ -50,50 +55,74 @@ module.exports = (app) => {
let addressRegex = /(polkadot|kusama|localtest) address:\s?([a-z0-9]+)/i;
let maybeMatch = pullRequestBody.match(addressRegex);
if (!maybeMatch || maybeMatch.length != 3) {
problemsText.push(`Contributor did not properly post their Polkadot or Kusama address. Make sure the pull request has: "{network} address: {address}".`);
problemsText.push(
`Contributor did not properly post their Polkadot or Kusama address. Make sure the pull request has: "{network} address: {address}".`
);
} else {
network = maybeMatch[1].toLowerCase();
if (!["polkadot", "kusama", "localtest"].includes(network)) {
problemsText.push(`Invalid network: ${maybeMatch[1]}. Please select "polkadot" or "kusama".`);
if (!['polkadot', 'kusama', 'localtest'].includes(network)) {
problemsText.push(
`Invalid network: ${maybeMatch[1]}. Please select "polkadot" or "kusama".`
);
}
address = maybeMatch[2];
}
// Tip initiation comment should be: "/tip { small / medium / large }"
let textParts = commentText.split(" ");
let textParts = commentText.split(' ');
if (textParts.length !== 2) {
problemsText.push(`Invalid command! Payload should be: "/tip { small / medium / large }".`);
problemsText.push(
`Invalid command! Payload should be: "/tip { small / medium / large }".`
);
} else {
// We already match `/tip` at the top of this program, so just check size.
size = textParts[1].toLowerCase();
if (size == "s") {
size = "small";
} else if (size == "m") {
size = "medium";
} else if (size == "l") {
size = "large";
if (size == 's') {
size = 'small';
} else if (size == 'm') {
size = 'medium';
} else if (size == 'l') {
size = 'large';
}
if (!["small", "medium", "large"].includes(size)) {
problemsText.push(`Invalid tip size. Please specify one of small, medium, or large.`)
if (!['small', 'medium', 'large'].includes(size)) {
problemsText.push(
`Invalid tip size. Please specify one of small, medium, or large.`
);
}
}
if (problemsText.length > 0) {
// there was some error to get to this point, lets list them.
let comment = "Please fix the following problems before calling the tip bot again:";
for (problem of problemsText) {
comment += `\n * ${problem}`
let comment =
'Please fix the following problems before calling the tip bot again:';
for (const problem of problemsText) {
comment += `\n * ${problem}`;
}
postComment(context, comment);
} else {
console.log(`Valid command! \n ${tipper} wants to tip ${contributor} (${address} on ${network}) a ${size} tip for pull request ${pullRequestUrl}.`);
console.log(
`Valid command! \n ${tipper} wants to tip ${contributor} (${address} on ${network}) a ${size} tip for pull request ${pullRequestUrl}.`
);
// Send the transaction to the network.
let result = await tipUser(address, contributor, network, pullRequestNumber, pullRequestRepo, size);
let result = await tipUser(
address,
contributor,
network,
pullRequestNumber,
pullRequestRepo,
size
);
// TODO actually check for problems with submitting the tip. Maybe even query storage to ensure the tip is there.
if (result) {
postComment(context, `A ${size} tip was successfully submitted for ${contributor} (${address} on ${network}). \n\n https://polkadot.js.org/apps/#/treasury/tips`);
postComment(
context,
`A ${size} tip was successfully submitted for ${contributor} (${address} on ${network}). \n\n https://polkadot.js.org/apps/#/treasury/tips`
);
} else {
postComment(context, `Could not submit tip :( Notify someone at Parity.`);
postComment(
context,
`Could not submit tip :( Notify someone at Parity.`
);
}
}
return;
......@@ -112,19 +141,26 @@ var { ApiPromise, WsProvider, Keyring } = require('@polkadot/api');
var { cryptoWaitReady } = require('@polkadot/util-crypto');
// TODO add some kind of timeout then return an error
async function tipUser(address, contributor, network, pullRequestNumber, pullRequestRepo, size) {
async function tipUser(
address,
contributor,
network,
pullRequestNumber,
pullRequestRepo,
size
) {
await cryptoWaitReady();
const keyring = new Keyring({ type: 'sr25519' });
// Connect to the appropriate network.
let provider, account;
if (network == "localtest") {
if (network == 'localtest') {
provider = new WsProvider('ws://localhost:9944');
account = keyring.addFromUri('//Alice', { name: 'Alice default' });
} else if (network == "polkadot") {
} else if (network == 'polkadot') {
provider = new WsProvider('wss://rpc.polkadot.io/');
account = keyring.addFromUri(process.env.ACCOUNT_SEED);
} else if (network == "kusama") {
} else if (network == 'kusama') {
provider = new WsProvider('wss://kusama-rpc.polkadot.io/');
account = keyring.addFromUri(process.env.ACCOUNT_SEED);
} else {
......@@ -137,7 +173,7 @@ async function tipUser(address, contributor, network, pullRequestNumber, pullReq
const [chain, nodeName, nodeVersion] = await Promise.all([
api.rpc.system.chain(),
api.rpc.system.name(),
api.rpc.system.version()
api.rpc.system.version(),
]);
console.log(
`You are connected to chain ${chain} using ${nodeName} v${nodeVersion}`
......@@ -146,7 +182,8 @@ async function tipUser(address, contributor, network, pullRequestNumber, pullReq
let reason = `TO: ${contributor} FOR: ${pullRequestRepo}#${pullRequestNumber} (${size})`;
// TODO before submitting, check tip does not already exist via a storage query.
// TODO potentially prevent duplicates by also checking for reasons with the other sizes.
const unsub = await api.tx.tips.reportAwesome(reason, address)
const unsub = await api.tx.tips
.reportAwesome(reason, address)
.signAndSend(account, (result) => {
console.log(`Current status is ${result.status}`);
if (result.status.isInBlock) {
......@@ -155,7 +192,7 @@ async function tipUser(address, contributor, network, pullRequestNumber, pullReq
console.log(`Tip finalized at blockHash ${result.status.asFinalized}`);
unsub();
}
});;
});
return true;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment