Swapped tslint to eslint and fixed files

This commit is contained in:
Arwid Thornström
2023-02-03 12:48:29 +01:00
committed by GitHub
parent 258e0b2dde
commit a7da247cf4
15 changed files with 1136 additions and 386 deletions
+16
View File
@@ -0,0 +1,16 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2017
},
"env": {
"es6": true
},
"extends": ["prettier"],
"plugins": ["@typescript-eslint", "prettier"],
"rules": {
"prettier/prettier": ["error"],
"no-return-await": "error"
}
}
+6 -5
View File
@@ -9,11 +9,10 @@
}, },
"scripts": { "scripts": {
"format": "prettier --write **/*.{js,ts,tsx,json}", "format": "prettier --write **/*.{js,ts,tsx,json}",
"lint": "tslint -p .",
"clean-build": "rm -rf ./build", "clean-build": "rm -rf ./build",
"compile": "tsc -p .", "compile": "tsc -p .",
"copy-templates": "if [ -e ./src/templates ]; then cp -a ./src/templates ./build/; fi", "copy-templates": "if [ -e ./src/templates ]; then cp -a ./src/templates ./build/; fi",
"build": "yarn format && yarn lint && yarn clean-build && yarn compile && yarn copy-templates", "build": "yarn format && yarn clean-build && yarn compile && yarn copy-templates",
"prepublishOnly": "yarn build", "prepublishOnly": "yarn build",
"test": "jest", "test": "jest",
"watch": "jest --watch", "watch": "jest --watch",
@@ -48,9 +47,11 @@
"prettier": "^1.12.1", "prettier": "^1.12.1",
"ts-jest": "^24.1.0", "ts-jest": "^24.1.0",
"ts-node": "^8.4.1", "ts-node": "^8.4.1",
"tslint": "^5.12.0", "@typescript-eslint/eslint-plugin": "^5.44.0",
"tslint-config-prettier": "^1.17.0", "@typescript-eslint/parser": "^5.44.0",
"tslint-config-standard": "^8.0.1", "eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"typescript": "^3.6.3" "typescript": "^3.6.3"
}, },
"jest": { "jest": {
+18 -10
View File
@@ -1,4 +1,4 @@
import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu' import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu';
import chalk = require('chalk'); import chalk = require('chalk');
import { confirmMessage, defaultMenuSettings } from '../../../globals'; import { confirmMessage, defaultMenuSettings } from '../../../globals';
const { AutoComplete } = require('enquirer'); const { AutoComplete } = require('enquirer');
@@ -10,10 +10,11 @@ module.exports = {
description: 'Tail a log in cloudwatch (l) (WIP)', description: 'Tail a log in cloudwatch (l) (WIP)',
hidden: false, hidden: false,
run: async (toolbox: GluegunMenuToolbox) => { run: async (toolbox: GluegunMenuToolbox) => {
const { system, strings } = toolbox;
const { system, strings } = toolbox const groups = JSON.parse(
strings.trim(await system.run(`aws logs describe-log-groups`))
const groups = JSON.parse(strings.trim(await system.run(`aws logs describe-log-groups`))); );
const options = groups.logGroups.map(item => { const options = groups.logGroups.map(item => {
return item.logGroupName; return item.logGroupName;
@@ -29,16 +30,23 @@ module.exports = {
const logGroup = await prompt.run(); const logGroup = await prompt.run();
if (await confirmMessage(`Tail logs from ${chalk.yellow(logGroup)}?`)) { if (await confirmMessage(`Tail logs from ${chalk.yellow(logGroup)}?`)) {
const child = spawn('aws', ['logs', 'tail', `${logGroup}`, '--follow', '--format', 'short']); const child = spawn('aws', [
'logs',
'tail',
`${logGroup}`,
'--follow',
'--format',
'short'
]);
child.stdout.setEncoding('utf8'); child.stdout.setEncoding('utf8');
child.stdout.on('data', function(data) { child.stdout.on('data', function(data) {
// Here is where the output goes // Here is where the output goes
console.log(data); console.log(data);
}); });
child.stderr.on('data', (data) => { child.stderr.on('data', data => {
console.error(`stderr: ${data}`); console.error(`stderr: ${data}`);
}); });
child.on('close', (code) => { child.on('close', code => {
console.log(`child process exited with code ${code}`); console.log(`child process exited with code ${code}`);
}); });
} }
@@ -47,4 +55,4 @@ module.exports = {
await toolbox.menu.showMenu('aws', defaultMenuSettings); await toolbox.menu.showMenu('aws', defaultMenuSettings);
} }
} }
} };
@@ -1,4 +1,4 @@
import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu' import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu';
import chalk = require('chalk'); import chalk = require('chalk');
import { defaultMenuSettings, sleep } from '../../../globals'; import { defaultMenuSettings, sleep } from '../../../globals';
const { AutoComplete } = require('enquirer'); const { AutoComplete } = require('enquirer');
@@ -9,7 +9,6 @@ module.exports = {
description: 'Parameter store functions (ps)', description: 'Parameter store functions (ps)',
hidden: false, hidden: false,
run: async (toolbox: GluegunMenuToolbox) => { run: async (toolbox: GluegunMenuToolbox) => {
const { system, strings, print, filesystem } = toolbox; const { system, strings, print, filesystem } = toolbox;
// Check for cache in /tmp folder // Check for cache in /tmp folder
@@ -19,21 +18,38 @@ module.exports = {
let nextToken = ''; let nextToken = '';
if (valueNames.length === 0) { if (valueNames.length === 0) {
const spinner = print.spin(`Downloading parameter names (${chalk.red('0')})`); const spinner = print.spin(
`Downloading parameter names (${chalk.red('0')})`
);
while (nextToken !== null) { while (nextToken !== null) {
const values = JSON.parse( const values = JSON.parse(
strings.trim( strings.trim(
await system.run(`aws ssm describe-parameters --output json --max-items 50 ${(nextToken !== '') ? `--starting-token ${nextToken}` : ''}`))); await system.run(
`aws ssm describe-parameters --output json --max-items 50 ${
nextToken !== '' ? `--starting-token ${nextToken}` : ''
}`
)
)
);
await sleep(500); await sleep(500);
valueNames.push(...values.Parameters.map(({Name}) => { return Name; })); valueNames.push(
...values.Parameters.map(({ Name }) => {
return Name;
})
);
nextToken = values.NextToken || null; nextToken = values.NextToken || null;
spinner.text = `Downloading parameter names (${chalk.red(valueNames.length)})` spinner.text = `Downloading parameter names (${chalk.red(
valueNames.length
)})`;
} }
spinner.text = 'Saving parameter names to /tmp/.pwcli_parametercache'; spinner.text = 'Saving parameter names to /tmp/.pwcli_parametercache';
filesystem.file('/tmp/.pwcli_parametercache', {mode: '600', content: JSON.stringify(valueNames)}); filesystem.file('/tmp/.pwcli_parametercache', {
mode: '600',
content: JSON.stringify(valueNames)
});
await sleep(2000); await sleep(2000);
spinner.stop(); spinner.stop();
@@ -51,8 +67,18 @@ module.exports = {
try { try {
const parameterName = await prompt.run(); const parameterName = await prompt.run();
const parameterValue = JSON.parse(strings.trim(await system.run(`aws ssm get-parameter --name ${parameterName} --with-decryption`))); const parameterValue = JSON.parse(
print.success(`${chalk.green(parameterName)} value is [${chalk.yellow(parameterValue.Parameter.Value)}]`); strings.trim(
await system.run(
`aws ssm get-parameter --name ${parameterName} --with-decryption`
)
)
);
print.success(
`${chalk.green(parameterName)} value is [${chalk.yellow(
parameterValue.Parameter.Value
)}]`
);
} catch (e) { } catch (e) {
parameterName = 'exit'; parameterName = 'exit';
} }
@@ -62,4 +88,4 @@ module.exports = {
await toolbox.menu.showMenu('aws', defaultMenuSettings); await toolbox.menu.showMenu('aws', defaultMenuSettings);
} }
} }
} };
@@ -1,4 +1,4 @@
import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu' import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu';
import { exit } from 'process'; import { exit } from 'process';
const chalk = require('chalk'); const chalk = require('chalk');
const { AutoComplete, Input, Confirm } = require('enquirer'); const { AutoComplete, Input, Confirm } = require('enquirer');
@@ -6,18 +6,20 @@ import { defaultMenuSettings, getSettings } from '../../../../globals';
import { getRepoBranches } from '../../../../services/github_rest'; import { getRepoBranches } from '../../../../services/github_rest';
type Stack = { type Stack = {
name: string name: string;
status: string status: string;
drift_status: string drift_status: string;
branch: string branch: string;
updated: string updated: string;
} };
const getConfirmation = async (branchName: string, stackName: string) => { const getConfirmation = async (branchName: string, stackName: string) => {
const url = stackName.replace('photowall-', ''); const url = stackName.replace('photowall-', '');
const confirm = new Confirm({ const confirm = new Confirm({
name: 'confirm', name: 'confirm',
message: `Will create ${chalk.yellow(url + '.photowall-test.xx')} and publish ${chalk.green(branchName)} to it, continue?` message: `Will create ${chalk.yellow(
url + '.photowall-test.xx'
)} and publish ${chalk.green(branchName)} to it, continue?`
}); });
try { try {
@@ -26,7 +28,7 @@ const getConfirmation = async (branchName: string, stackName: string) => {
console.error(e); console.error(e);
return false; return false;
} }
} };
module.exports = { module.exports = {
name: 'create', name: 'create',
@@ -38,7 +40,7 @@ module.exports = {
// Load settings // Load settings
const config = await getSettings(toolbox); const config = await getSettings(toolbox);
if (!config || (!config.photowall_repo || config.photowall_repo === "")) { if (!config || !config.photowall_repo || config.photowall_repo === '') {
print.error(` print.error(`
The create command requires that you set an absolute path to your local photowall repository. The create command requires that you set an absolute path to your local photowall repository.
@@ -48,7 +50,12 @@ module.exports = {
return; return;
} }
const branches = await getRepoBranches(toolbox, config.gh_token, 'Photowall', 'photowall'); const branches = await getRepoBranches(
toolbox,
config.gh_token,
'Photowall',
'photowall'
);
const branchOptions = branches.map(item => item.name); const branchOptions = branches.map(item => item.name);
const promptBranch = new AutoComplete({ const promptBranch = new AutoComplete({
@@ -62,7 +69,7 @@ module.exports = {
const stacks = JSON.parse( const stacks = JSON.parse(
strings.trim(await system.run(`aws cloudformation list-stacks`)) strings.trim(await system.run(`aws cloudformation list-stacks`))
) );
const teststacks: Stack[] = await Promise.all( const teststacks: Stack[] = await Promise.all(
stacks.StackSummaries.map(async item => { stacks.StackSummaries.map(async item => {
if ( if (
@@ -82,24 +89,24 @@ module.exports = {
`aws codepipeline get-pipeline --name ${item.StackName}Pipeline` `aws codepipeline get-pipeline --name ${item.StackName}Pipeline`
) )
) )
) );
const branch = pipeline.pipeline.stages.filter(stage => { const branch = pipeline.pipeline.stages.filter(stage => {
return stage.name === 'Source' return stage.name === 'Source';
})[0].actions[0].configuration.Branch })[0].actions[0].configuration.Branch;
const lastUpdated = pipeline.metadata.updated const lastUpdated = pipeline.metadata.updated;
return { return {
name: item.StackName, name: item.StackName,
status: item.StackStatus, status: item.StackStatus,
drift_status: item.DriftInformation.StackDriftStatus, drift_status: item.DriftInformation.StackDriftStatus,
branch: branch, branch: branch,
updated: lastUpdated updated: lastUpdated
} };
} }
return Promise.resolve(null) return Promise.resolve(null);
}) })
) );
const curratedStacks: Stack[] = teststacks.filter(Boolean) const curratedStacks: Stack[] = teststacks.filter(Boolean);
const options = curratedStacks.map(item => { const options = curratedStacks.map(item => {
return item.name; return item.name;
}); });
@@ -110,12 +117,14 @@ module.exports = {
message: `Subdomain of new server (${chalk.yellow('test-xxx')})` message: `Subdomain of new server (${chalk.yellow('test-xxx')})`
}); });
const stacksuffix = await input.run(); const stacksuffix = await input.run();
const stackName = `photowall-${stacksuffix}` const stackName = `photowall-${stacksuffix}`;
if (options.includes(stackName)) { if (options.includes(stackName)) {
print.error(` print.error(`
The stack ${chalk.yellow(stackName)} is already taken, try the update command instead. The stack ${chalk.yellow(
stackName
)} is already taken, try the update command instead.
`); `);
if (toolbox.fromMenu()) { if (toolbox.fromMenu()) {
@@ -126,11 +135,16 @@ module.exports = {
} else if (stackName.indexOf('photowall-test-') !== 0) { } else if (stackName.indexOf('photowall-test-') !== 0) {
print.error(` print.error(`
The stack must begin with ${chalk.yellow('test-')} and then something after like ${chalk.yellow('test-yourname-1')}. The stack must begin with ${chalk.yellow(
'test-'
)} and then something after like ${chalk.yellow('test-yourname-1')}.
`); `);
if (toolbox.fromMenu()) { if (toolbox.fromMenu()) {
await toolbox.menu.showMenu('deployment testservers', defaultMenuSettings); await toolbox.menu.showMenu(
'deployment testservers',
defaultMenuSettings
);
} else { } else {
exit(); exit();
} }
@@ -141,8 +155,15 @@ module.exports = {
if (shouldRun) { if (shouldRun) {
const cmd = `make create-stack STACK_ENVIRONMENT_NAME=${stacksuffix} GITHUB_BRANCH=${branchName}`; const cmd = `make create-stack STACK_ENVIRONMENT_NAME=${stacksuffix} GITHUB_BRANCH=${branchName}`;
print.fancy(`Running [${chalk.yellow(cmd)}] in folder [${`${config.photowall_repo}/cloudformation/`}]`); print.fancy(
const output = await system.run(cmd, {cwd: `${config.photowall_repo}/cloudformation/`, trim: true}); `Running [${chalk.yellow(
cmd
)}] in folder [${`${config.photowall_repo}/cloudformation/`}]`
);
const output = await system.run(cmd, {
cwd: `${config.photowall_repo}/cloudformation/`,
trim: true
});
print.fancy(output); print.fancy(output);
} }
} catch (e) { } catch (e) {
@@ -150,7 +171,10 @@ module.exports = {
} }
if (toolbox.fromMenu()) { if (toolbox.fromMenu()) {
await toolbox.menu.showMenu('deployment testservers', defaultMenuSettings); await toolbox.menu.showMenu(
'deployment testservers',
defaultMenuSettings
);
} }
} }
} };
@@ -1,21 +1,23 @@
import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu' import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu';
import { GluegunSystem } from 'gluegun'; import { GluegunSystem } from 'gluegun';
import { defaultMenuSettings } from '../../../../globals'; import { defaultMenuSettings } from '../../../../globals';
const chalk = require('chalk'); const chalk = require('chalk');
const { AutoComplete, Input, Confirm } = require('enquirer'); const { AutoComplete, Input, Confirm } = require('enquirer');
type Stack = { type Stack = {
name: string, name: string;
status: string, status: string;
drift_status: string, drift_status: string;
branch: string, branch: string;
updated: string, updated: string;
}; };
const getConfirmation = async (stackName: string) => { const getConfirmation = async (stackName: string) => {
const confirm = new Confirm({ const confirm = new Confirm({
name: 'confirm', name: 'confirm',
message: `The stack ${chalk.yellow(stackName)} will be ${chalk.red.bold('deleted')}` message: `The stack ${chalk.yellow(stackName)} will be ${chalk.red.bold(
'deleted'
)}`
}); });
try { try {
@@ -23,12 +25,12 @@ const getConfirmation = async (stackName: string) => {
} catch (e) { } catch (e) {
return false; return false;
} }
} };
const confirmCommand = async (cmd: string) => { const confirmCommand = async (cmd: string) => {
const confirm = new Confirm({ const confirm = new Confirm({
name: 'confirm', name: 'confirm',
message: `RUN COMMAND > [${chalk.yellow(cmd)}] ?`, message: `RUN COMMAND > [${chalk.yellow(cmd)}] ?`
}); });
try { try {
@@ -40,9 +42,9 @@ const confirmCommand = async (cmd: string) => {
} catch (e) { } catch (e) {
return null; return null;
} }
} };
const runCommand = async (system: GluegunSystem, cmd : string | null) => { const runCommand = async (system: GluegunSystem, cmd: string | null) => {
if (cmd) { if (cmd) {
return system.run(cmd); return system.run(cmd);
} }
@@ -55,12 +57,11 @@ module.exports = {
description: 'Choose a testserver to delete (d)', description: 'Choose a testserver to delete (d)',
hidden: false, hidden: false,
run: async (toolbox: GluegunMenuToolbox) => { run: async (toolbox: GluegunMenuToolbox) => {
const { system, strings, print } = toolbox; const { system, strings, print } = toolbox;
const stacks = JSON.parse( const stacks = JSON.parse(
strings.trim(await system.run(`aws cloudformation list-stacks`)) strings.trim(await system.run(`aws cloudformation list-stacks`))
) );
const teststacks: Stack[] = await Promise.all( const teststacks: Stack[] = await Promise.all(
stacks.StackSummaries.map(async item => { stacks.StackSummaries.map(async item => {
if ( if (
@@ -80,27 +81,27 @@ module.exports = {
`aws codepipeline get-pipeline --name ${item.StackName}Pipeline` `aws codepipeline get-pipeline --name ${item.StackName}Pipeline`
) )
) )
) );
const branch = pipeline.pipeline.stages.filter(stage => { const branch = pipeline.pipeline.stages.filter(stage => {
return stage.name === 'Source' return stage.name === 'Source';
})[0].actions[0].configuration.Branch })[0].actions[0].configuration.Branch;
const lastUpdated = pipeline.metadata.updated const lastUpdated = pipeline.metadata.updated;
return { return {
name: item.StackName, name: item.StackName,
status: item.StackStatus, status: item.StackStatus,
drift_status: item.DriftInformation.StackDriftStatus, drift_status: item.DriftInformation.StackDriftStatus,
branch: branch, branch: branch,
updated: lastUpdated updated: lastUpdated
} };
} }
return Promise.resolve(null) return Promise.resolve(null);
}) })
) );
const curratedStacks: Stack[] = teststacks.filter(Boolean) const curratedStacks: Stack[] = teststacks.filter(Boolean);
const options = curratedStacks.map(item => { const options = curratedStacks.map(item => {
return item.name return item.name;
}) });
const prompt = new AutoComplete({ const prompt = new AutoComplete({
name: 'testserver', name: 'testserver',
@@ -115,20 +116,50 @@ module.exports = {
const shouldRun = await getConfirmation(stackName); const shouldRun = await getConfirmation(stackName);
if (shouldRun) { if (shouldRun) {
await runCommand(system, await confirmCommand(`aws cloudformation delete-stack --stack-name ${stackName}`)); await runCommand(
await runCommand(system, await confirmCommand(`aws ecr delete-repository --force --repository-name ${stackName}`)); system,
await runCommand(system, await confirmCommand(`aws logs delete-log-group --log-group-name /aws/codebuild/${stackName}`)); await confirmCommand(
await runCommand(system, await confirmCommand(`aws logs delete-log-group --log-group-name ${stackName}`)); `aws cloudformation delete-stack --stack-name ${stackName}`
const artifacts = strings.trim( )
await system.run(`aws s3 ls | grep ${stackName}-artifactbucket | awk '{print $3}'`) );
).split('\n'); await runCommand(
system,
await confirmCommand(
`aws ecr delete-repository --force --repository-name ${stackName}`
)
);
await runCommand(
system,
await confirmCommand(
`aws logs delete-log-group --log-group-name /aws/codebuild/${stackName}`
)
);
await runCommand(
system,
await confirmCommand(
`aws logs delete-log-group --log-group-name ${stackName}`
)
);
const artifacts = strings
.trim(
await system.run(
`aws s3 ls | grep ${stackName}-artifactbucket | awk '{print $3}'`
)
)
.split('\n');
for (const artifact of artifacts) { for (const artifact of artifacts) {
await runCommand(system, await confirmCommand(`aws s3 rb --force s3://${artifact}`)); await runCommand(
system,
await confirmCommand(`aws s3 rb --force s3://${artifact}`)
);
} }
} }
if (toolbox.fromMenu()) { if (toolbox.fromMenu()) {
await toolbox.menu.showMenu('deployment testservers', defaultMenuSettings); await toolbox.menu.showMenu(
'deployment testservers',
defaultMenuSettings
);
} }
} }
} };
@@ -1,14 +1,14 @@
import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu' import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu';
import chalk = require('chalk'); import chalk = require('chalk');
import { defaultMenuSettings } from '../../../../globals'; import { defaultMenuSettings } from '../../../../globals';
const tto = require('terminal-table-output').create(); const tto = require('terminal-table-output').create();
type Stack = { type Stack = {
name: string, name: string;
status: string, status: string;
drift_status: string, drift_status: string;
branch: string, branch: string;
updated: string, updated: string;
}; };
module.exports = { module.exports = {
@@ -17,44 +17,64 @@ module.exports = {
description: 'Show status for available testservers (s)', description: 'Show status for available testservers (s)',
hidden: false, hidden: false,
run: async (toolbox: GluegunMenuToolbox) => { run: async (toolbox: GluegunMenuToolbox) => {
const { system, strings } = toolbox;
const { system, strings } = toolbox const stacks = JSON.parse(
strings.trim(await system.run(`aws cloudformation list-stacks`))
const stacks = JSON.parse(strings.trim(await system.run(`aws cloudformation list-stacks`))); );
const teststacks: Stack[] = await Promise.all(stacks.StackSummaries.map(async (item) => { const teststacks: Stack[] = await Promise.all(
if (item.StackName.indexOf('photowall-test-') > -1 && ['CREATE_COMPLETE', 'UPDATE_COMPLETE', 'UPDATE_IN_PROGRESS', 'UPDATE_FAILED', 'CREATE_FAILED', 'CREATE_IN_PROGRESS'].includes(item.StackStatus)) { stacks.StackSummaries.map(async item => {
try { if (
const pipeline = JSON.parse(strings.trim(await system.run(`aws codepipeline get-pipeline --name ${item.StackName}Pipeline`))); item.StackName.indexOf('photowall-test-') > -1 &&
const sourceStage = pipeline.pipeline.stages.filter(stage => { [
return stage.name === 'Source'; 'CREATE_COMPLETE',
}); 'UPDATE_COMPLETE',
const branch = sourceStage[0].actions[0].configuration.Branch ?? sourceStage[0].actions[0].configuration.BranchName; 'UPDATE_IN_PROGRESS',
const lastUpdated = pipeline.metadata.updated; 'UPDATE_FAILED',
return { 'CREATE_FAILED',
name: item.StackName, 'CREATE_IN_PROGRESS'
status: item.StackStatus, ].includes(item.StackStatus)
drift_status: item.DriftInformation.StackDriftStatus, ) {
branch: branch, try {
updated: lastUpdated, const pipeline = JSON.parse(
} strings.trim(
} catch (e) { await system.run(
return { `aws codepipeline get-pipeline --name ${item.StackName}Pipeline`
name: item.StackName, )
status: 'NO_STATUS', )
drift_status: '', );
branch: '', const sourceStage = pipeline.pipeline.stages.filter(stage => {
updated: '', return stage.name === 'Source';
});
const branch =
sourceStage[0].actions[0].configuration.Branch ??
sourceStage[0].actions[0].configuration.BranchName;
const lastUpdated = pipeline.metadata.updated;
return {
name: item.StackName,
status: item.StackStatus,
drift_status: item.DriftInformation.StackDriftStatus,
branch: branch,
updated: lastUpdated
};
} catch (e) {
return {
name: item.StackName,
status: 'NO_STATUS',
drift_status: '',
branch: '',
updated: ''
};
} }
} }
return Promise.resolve(null);
} })
return Promise.resolve(null); );
}));
const curratedStacks: Stack[] = teststacks.filter(Boolean); const curratedStacks: Stack[] = teststacks.filter(Boolean);
const status = (status: string) => { const status = (status: string) => {
switch(status) { switch (status) {
case 'NO_STATUS': case 'NO_STATUS':
return `(${chalk.red.bold('?')})`; return `(${chalk.red.bold('?')})`;
case 'UPDATE_FAILED': case 'UPDATE_FAILED':
@@ -67,10 +87,12 @@ module.exports = {
case 'CREATE_COMPLETE': case 'CREATE_COMPLETE':
return `(${chalk.greenBright('OK')})`; return `(${chalk.greenBright('OK')})`;
} }
} };
const stackUrl = (stackname: string) => { const stackUrl = (stackname: string) => {
return `https://test-${stackname.split('photowall-test-')[1]}.photowall-test.com/us`; return `https://test-${
stackname.split('photowall-test-')[1]
}.photowall-test.com/us`;
}; };
const ellipsis = (a: string, max: number) => { const ellipsis = (a: string, max: number) => {
@@ -88,30 +110,31 @@ module.exports = {
let interval = seconds / 31536000; let interval = seconds / 31536000;
if (interval > 1) { if (interval > 1) {
return Math.floor(interval) + " years"; return Math.floor(interval) + ' years';
} }
interval = seconds / 2592000; interval = seconds / 2592000;
if (interval > 1) { if (interval > 1) {
return `${chalk.red(Math.floor(interval) + " months")}`; return `${chalk.red(Math.floor(interval) + ' months')}`;
} }
interval = seconds / 86400; interval = seconds / 86400;
if (interval > 1) { if (interval > 1) {
const days = Math.floor(interval); const days = Math.floor(interval);
return `${chalk[days >= 14 ? 'yellow' : 'green'](days + " days")}`; return `${chalk[days >= 14 ? 'yellow' : 'green'](days + ' days')}`;
} }
interval = seconds / 3600; interval = seconds / 3600;
if (interval > 1) { if (interval > 1) {
return `${chalk.green(Math.floor(interval) + " hours")}`; return `${chalk.green(Math.floor(interval) + ' hours')}`;
} }
interval = seconds / 60; interval = seconds / 60;
if (interval > 1) { if (interval > 1) {
return `${chalk.green(Math.floor(interval) + " minutes")}`; return `${chalk.green(Math.floor(interval) + ' minutes')}`;
} }
return Math.floor(seconds) + " seconds"; return Math.floor(seconds) + ' seconds';
} };
tto.line('-'); tto.line('-');
tto.pushrow(['| status', 'stack', 'branch', 'time since update', 'url']) tto
.pushrow(['| status', 'stack', 'branch', 'time since update', 'url'])
.line('-'); .line('-');
// Sort on stackname // Sort on stackname
curratedStacks.sort((a, b) => { curratedStacks.sort((a, b) => {
@@ -121,12 +144,21 @@ module.exports = {
}); });
for (const stack of curratedStacks) { for (const stack of curratedStacks) {
const t = new Date(stack.updated); const t = new Date(stack.updated);
tto.pushrow([status(stack.status), stack.name, ellipsis(stack.branch, 24), timeSince(t.getTime()), stackUrl(stack.name)]); tto.pushrow([
status(stack.status),
stack.name,
ellipsis(stack.branch, 24),
timeSince(t.getTime()),
stackUrl(stack.name)
]);
} }
tto.print(true); tto.print(true);
if (toolbox.fromMenu()) { if (toolbox.fromMenu()) {
await toolbox.menu.showMenu('deployment testservers', defaultMenuSettings); await toolbox.menu.showMenu(
'deployment testservers',
defaultMenuSettings
);
} }
} }
} };
@@ -1,26 +1,35 @@
import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu' import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu';
const chalk = require('chalk'); const chalk = require('chalk');
const { AutoComplete, Input, Confirm } = require('enquirer'); const { AutoComplete, Input, Confirm } = require('enquirer');
import { Octokit } from "@octokit/core"; import { Octokit } from '@octokit/core';
import { exit } from 'process'; import { exit } from 'process';
import { defaultMenuSettings, getCurrentBranch, getSettings, sleep } from '../../../../globals'; import {
defaultMenuSettings,
getCurrentBranch,
getSettings,
sleep
} from '../../../../globals';
type Stack = { type Stack = {
name: string name: string;
status: string status: string;
drift_status: string drift_status: string;
branch: string branch: string;
updated: string updated: string;
} };
const getBranchName = async (toolbox: GluegunMenuToolbox, token: string, repoPath: string) => { const getBranchName = async (
const {print} = toolbox; toolbox: GluegunMenuToolbox,
token: string,
repoPath: string
) => {
const { print } = toolbox;
const currentBranch = await getCurrentBranch(repoPath, toolbox); const currentBranch = await getCurrentBranch(repoPath, toolbox);
const input = new Input({ const input = new Input({
type: 'input', type: 'input',
name: 'branch', name: 'branch',
message: 'What github branch should be deployed?', message: 'What github branch should be deployed?',
initial: currentBranch, initial: currentBranch
}); });
const responseBranch = await input.run(); const responseBranch = await input.run();
@@ -28,11 +37,14 @@ const getBranchName = async (toolbox: GluegunMenuToolbox, token: string, repoPat
const octokit = new Octokit({ auth: token }); const octokit = new Octokit({ auth: token });
try { try {
const response = await octokit.request("GET /repos/{owner}/{repo}/branches/{branch}", { const response = await octokit.request(
owner: "photowall", 'GET /repos/{owner}/{repo}/branches/{branch}',
repo: "photowall", {
branch: responseBranch owner: 'photowall',
}); repo: 'photowall',
branch: responseBranch
}
);
if (response.status === 200) { if (response.status === 200) {
return responseBranch; return responseBranch;
} }
@@ -45,7 +57,9 @@ const getBranchName = async (toolbox: GluegunMenuToolbox, token: string, repoPat
const getConfirmation = async (branchName: string, stackName: string) => { const getConfirmation = async (branchName: string, stackName: string) => {
const confirm = new Confirm({ const confirm = new Confirm({
name: 'confirm', name: 'confirm',
message: `The branch ${chalk.green(branchName)} will deploy to ${chalk.yellow(stackName)}` message: `The branch ${chalk.green(
branchName
)} will deploy to ${chalk.yellow(stackName)}`
}); });
try { try {
@@ -54,7 +68,7 @@ const getConfirmation = async (branchName: string, stackName: string) => {
console.error(e); console.error(e);
return false; return false;
} }
} };
module.exports = { module.exports = {
name: 'update', name: 'update',
@@ -66,7 +80,7 @@ module.exports = {
// Load settings // Load settings
const config = await getSettings(toolbox); const config = await getSettings(toolbox);
if (!config || (!config.photowall_repo || config.photowall_repo === "")) { if (!config || !config.photowall_repo || config.photowall_repo === '') {
print.error(` print.error(`
The create command requires that you set an absolute path to your local photowall repository. The create command requires that you set an absolute path to your local photowall repository.
@@ -78,12 +92,16 @@ module.exports = {
let branchName = null; let branchName = null;
while (!branchName) { while (!branchName) {
branchName = await getBranchName(toolbox, config.gh_token, config.photowall_repo); branchName = await getBranchName(
toolbox,
config.gh_token,
config.photowall_repo
);
} }
const stacks = JSON.parse( const stacks = JSON.parse(
strings.trim(await system.run(`aws cloudformation list-stacks`)) strings.trim(await system.run(`aws cloudformation list-stacks`))
) );
const teststacks: Stack[] = await Promise.all( const teststacks: Stack[] = await Promise.all(
stacks.StackSummaries.map(async item => { stacks.StackSummaries.map(async item => {
if ( if (
@@ -103,24 +121,24 @@ module.exports = {
`aws codepipeline get-pipeline --name ${item.StackName}Pipeline` `aws codepipeline get-pipeline --name ${item.StackName}Pipeline`
) )
) )
) );
const branch = pipeline.pipeline.stages.filter(stage => { const branch = pipeline.pipeline.stages.filter(stage => {
return stage.name === 'Source' return stage.name === 'Source';
})[0].actions[0].configuration.Branch })[0].actions[0].configuration.Branch;
const lastUpdated = pipeline.metadata.updated const lastUpdated = pipeline.metadata.updated;
return { return {
name: item.StackName, name: item.StackName,
status: item.StackStatus, status: item.StackStatus,
drift_status: item.DriftInformation.StackDriftStatus, drift_status: item.DriftInformation.StackDriftStatus,
branch: branch, branch: branch,
updated: lastUpdated updated: lastUpdated
} };
} }
return Promise.resolve(null) return Promise.resolve(null);
}) })
) );
const curratedStacks: Stack[] = teststacks.filter(Boolean) const curratedStacks: Stack[] = teststacks.filter(Boolean);
const options = curratedStacks.map(item => { const options = curratedStacks.map(item => {
return item.name; return item.name;
}); });
@@ -141,48 +159,69 @@ module.exports = {
if (shouldRun) { if (shouldRun) {
const cmd = `make update-stack STACK_ENVIRONMENT_NAME=${stacksuffix} GITHUB_BRANCH=${branchName}`; const cmd = `make update-stack STACK_ENVIRONMENT_NAME=${stacksuffix} GITHUB_BRANCH=${branchName}`;
print.fancy(`Running [${chalk.yellow(cmd)}] in folder [${`${config.photowall_repo}/cloudformation/`}]`); print.fancy(
const output = await system.run(cmd, {cwd: `${config.photowall_repo}/cloudformation/`, trim: true}); `Running [${chalk.yellow(
cmd
)}] in folder [${`${config.photowall_repo}/cloudformation/`}]`
);
const output = await system.run(cmd, {
cwd: `${config.photowall_repo}/cloudformation/`,
trim: true
});
print.fancy(output); print.fancy(output);
// Check the status // Check the status
const spinner = print.spin(`Waiting for stack to update`); const spinner = print.spin(`Waiting for stack to update`);
let currentStackStatus = ""; let currentStackStatus = '';
while (currentStackStatus !== "UPDATE_COMPLETE") { while (currentStackStatus !== 'UPDATE_COMPLETE') {
const stackCmd = `aws cloudformation describe-stacks --stack-name photowall-${stacksuffix}`; const stackCmd = `aws cloudformation describe-stacks --stack-name photowall-${stacksuffix}`;
const response = await system.run(stackCmd, {trim: true}); const response = await system.run(stackCmd, { trim: true });
const stackData = JSON.parse(response); const stackData = JSON.parse(response);
currentStackStatus = stackData.Stacks[0].StackStatus; currentStackStatus = stackData.Stacks[0].StackStatus;
let statusOutput = '';
switch (currentStackStatus) { switch (currentStackStatus) {
case "UPDATE_IN_PROGRESS": case 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS':
spinner.text = `[${chalk.red(currentStackStatus)}]: Updating the stack`; statusOutput = `[${chalk.yellow(
case "UPDATE_COMPLETE_CLEANUP_IN_PROGRESS": currentStackStatus
spinner.text = `[${chalk.yellow(currentStackStatus)}]: Almost done, cleanup in progress`; )}]: Almost done, cleanup in progress`;
case "UPDATE_COMPLETE": break;
spinner.text = `[${chalk.green(currentStackStatus)}]: Update complete`; case 'UPDATE_COMPLETE':
statusOutput = `[${chalk.green(
currentStackStatus
)}]: Update complete`;
break;
default:
statusOutput = `[${chalk.red(
currentStackStatus
)}]: Updating the stack`;
break; break;
} }
spinner.text = statusOutput;
if (currentStackStatus !== 'UPDATE_COMPLETE') { if (currentStackStatus !== 'UPDATE_COMPLETE') {
await sleep(1000); await sleep(1000);
} }
} }
spinner.text = `Will start the pipeline now [${chalk.yellow(`photowall-${stacksuffix}Pipeline`)}]`; spinner.text = `Will start the pipeline now [${chalk.yellow(
`photowall-${stacksuffix}Pipeline`
)}]`;
const runPipelineCmd = `aws codepipeline start-pipeline-execution --name photowall-${stacksuffix}Pipeline`; const runPipelineCmd = `aws codepipeline start-pipeline-execution --name photowall-${stacksuffix}Pipeline`;
await system.run(runPipelineCmd); await system.run(runPipelineCmd);
await sleep(2000); await sleep(2000);
spinner.stop(); spinner.stop();
print.fancy('Pipeline started, bye! 🚀'); print.fancy('Pipeline started, bye! 🚀');
} }
} catch (e) { } catch (e) {
console.log(`e`, e) console.log(`e`, e);
} }
if (toolbox.fromMenu()) { if (toolbox.fromMenu()) {
await toolbox.menu.showMenu('deployment testservers', defaultMenuSettings) await toolbox.menu.showMenu(
'deployment testservers',
defaultMenuSettings
);
} else { } else {
exit(); exit();
} }
} }
} };
+32 -21
View File
@@ -5,14 +5,14 @@ import { defaultMenuSettings, getSettings } from '../../../globals';
const { Confirm, Input } = require('enquirer'); const { Confirm, Input } = require('enquirer');
const checkCLIProgram = async (toolbox: GluegunMenuToolbox, cmd: string) => { const checkCLIProgram = async (toolbox: GluegunMenuToolbox, cmd: string) => {
const {print, system, strings} = toolbox; const { print, system, strings } = toolbox;
try { try {
const result = strings.trim(await system.run(`command -v ${cmd}`)); const result = strings.trim(await system.run(`command -v ${cmd}`));
return true; return true;
} catch(e) { } catch (e) {
return false; return false;
} }
} };
module.exports = { module.exports = {
name: 'settings', name: 'settings',
@@ -20,10 +20,10 @@ module.exports = {
description: 'Setup settings for pwcli (se)', description: 'Setup settings for pwcli (se)',
hidden: false, hidden: false,
run: async (toolbox: GluegunMenuToolbox) => { run: async (toolbox: GluegunMenuToolbox) => {
const { print, system, strings } = toolbox;
const {print, system, strings} = toolbox; print.info(
chalk.yellow(`
print.info(chalk.yellow(`
This will help you setup everything needed to run pwcli on a mac (maby linux). This will help you setup everything needed to run pwcli on a mac (maby linux).
All settings will be saved to ${chalk.cyan('~/.pwcli_settings')} All settings will be saved to ${chalk.cyan('~/.pwcli_settings')}
@@ -31,7 +31,8 @@ module.exports = {
First step is to install aws cli [https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html] First step is to install aws cli [https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html]
and configuring it. Install it either with brew or do as specified in the link. and configuring it. Install it either with brew or do as specified in the link.
`)); `)
);
let config = await getSettings(toolbox); let config = await getSettings(toolbox);
@@ -101,38 +102,48 @@ module.exports = {
// } // }
await system.run('touch ~/.pwcli_settings'); await system.run('touch ~/.pwcli_settings');
print.info(`Created configuration file ${chalk.yellow(`~/.pwcli_settings`)}`); print.info(
`Created configuration file ${chalk.yellow(`~/.pwcli_settings`)}`
);
if (!config) { if (!config) {
config = { config = {
gh_token: '', gh_token: '',
photowall_repo: '', photowall_repo: ''
}; };
} }
config.gh_token = await (new Input({ config.gh_token = await new Input({
message: `A github accesstoken is required with ${chalk.yellow('Full control of private repositories')}, please insert the key >`, message: `A github accesstoken is required with ${chalk.yellow(
initial: config.gh_token, 'Full control of private repositories'
})).run(); )}, please insert the key >`,
initial: config.gh_token
}).run();
config.photowall_repo = await (new Input({ config.photowall_repo = await new Input({
message: `If you want to be able to use current branch in your photowall repository\nor the create and update commands for testservers, please insert\nthe absolute path to the project or leave blank >`, message: `If you want to be able to use current branch in your photowall repository\nor the create and update commands for testservers, please insert\nthe absolute path to the project or leave blank >`,
initial: config.photowall_repo, initial: config.photowall_repo
})).run(); }).run();
print.info(` print.info(`
${JSON.stringify(config)} ${JSON.stringify(config)}
`); `);
if (await (new Confirm({ if (
message: `Ok to save the these settings to ${chalk.yellow(`~/.pwcli_settings`)}?` await new Confirm({
})).run()) { message: `Ok to save the these settings to ${chalk.yellow(
`~/.pwcli_settings`
)}?`
}).run()
) {
await system.run(`echo '${JSON.stringify(config)}' > ~/.pwcli_settings`); await system.run(`echo '${JSON.stringify(config)}' > ~/.pwcli_settings`);
} else { } else {
print.info('Ok then.'); print.info('Ok then.');
if (toolbox.fromMenu()) await toolbox.menu.showMenu(null, defaultMenuSettings); if (toolbox.fromMenu())
await toolbox.menu.showMenu(null, defaultMenuSettings);
} }
if (toolbox.fromMenu()) await toolbox.menu.showMenu(null, defaultMenuSettings); if (toolbox.fromMenu())
await toolbox.menu.showMenu(null, defaultMenuSettings);
} }
}; };
+34 -12
View File
@@ -2,9 +2,14 @@ import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu';
import { Octokit } from '@octokit/core'; import { Octokit } from '@octokit/core';
import chalk = require('chalk'); import chalk = require('chalk');
import { system } from 'gluegun'; import { system } from 'gluegun';
import { confirmMessage, defaultMenuSettings, getSettings, issueToBranchName } from '../../../globals'; import {
import { createPullRequest, getIssueFromRepo, getOpenIssuesFromRepo, getOrgIssues, getOrgRepos } from '../../../services/github_rest'; confirmMessage,
const { AutoComplete, Confirm, Input } = require('enquirer'); defaultMenuSettings,
getSettings,
issueToBranchName
} from '../../../globals';
import { getIssueFromRepo, getOrgIssues } from '../../../services/github_rest';
const { AutoComplete } = require('enquirer');
module.exports = { module.exports = {
name: 'SetupIssue', name: 'SetupIssue',
@@ -12,8 +17,7 @@ module.exports = {
description: 'Setup everything for a issue (si)', description: 'Setup everything for a issue (si)',
hidden: false, hidden: false,
run: async (toolbox: GluegunMenuToolbox) => { run: async (toolbox: GluegunMenuToolbox) => {
const { print, system, strings } = toolbox;
const {print, system, strings} = toolbox;
// Load settings // Load settings
const config = await getSettings(toolbox); const config = await getSettings(toolbox);
@@ -24,8 +28,10 @@ module.exports = {
const repos = await getOrgIssues(toolbox, config.gh_token); const repos = await getOrgIssues(toolbox, config.gh_token);
const issueOptions = repos.flatMap(repo => { const issueOptions = repos.flatMap(repo => {
return repo.issues.map(issue => `${issue.number}-${repo.repo}-${issue.title}`); return repo.issues.map(
}) issue => `${issue.number}-${repo.repo}-${issue.title}`
);
});
const promptIssues = new AutoComplete({ const promptIssues = new AutoComplete({
name: 'issues', name: 'issues',
@@ -38,14 +44,30 @@ module.exports = {
const issueNumber = issueResponse.split('-')[0]; const issueNumber = issueResponse.split('-')[0];
const repo = issueResponse.split('-')[1]; const repo = issueResponse.split('-')[1];
const issueData = await getIssueFromRepo(toolbox, config.gh_token, repo, issueNumber); const issueData = await getIssueFromRepo(
toolbox,
config.gh_token,
repo,
issueNumber
);
const branchName = issueToBranchName(issueData); const branchName = issueToBranchName(issueData);
if (await confirmMessage(`Create new branch ${chalk.yellow(branchName)} from origin/master?`)) { if (
await system.run(`git checkout -b ${branchName} origin/master`, {cwd: config.photowall_repo, trim: true}); await confirmMessage(
await system.run(`git push -u origin ${branchName}`, {cwd: config.photowall_repo, trim: true}); `Create new branch ${chalk.yellow(branchName)} from origin/master?`
)
) {
await system.run(`git checkout -b ${branchName} origin/master`, {
cwd: config.photowall_repo,
trim: true
});
await system.run(`git push -u origin ${branchName}`, {
cwd: config.photowall_repo,
trim: true
});
} }
if (toolbox.fromMenu()) await toolbox.menu.showMenu('workflow', defaultMenuSettings); if (toolbox.fromMenu())
await toolbox.menu.showMenu('workflow', defaultMenuSettings);
} }
}; };
+4 -6
View File
@@ -1,13 +1,11 @@
import { GluegunToolbox } from 'gluegun';
import { GluegunToolbox } from 'gluegun'
// add your CLI-specific functionality here, which will then be accessible // add your CLI-specific functionality here, which will then be accessible
// to your commands // to your commands
module.exports = (toolbox: GluegunToolbox) => { module.exports = (toolbox: GluegunToolbox) => {
toolbox.foo = () => { toolbox.foo = () => {
toolbox.print.info('called foo extension') toolbox.print.info('called foo extension');
} };
// enable this if you want to read configuration in from // enable this if you want to read configuration in from
// the current folder's package.json (in a "pwcli" property), // the current folder's package.json (in a "pwcli" property),
@@ -16,4 +14,4 @@ module.exports = (toolbox: GluegunToolbox) => {
// ...toolbox.config, // ...toolbox.config,
// ...toolbox.config.loadConfig("pwcli", process.cwd()) // ...toolbox.config.loadConfig("pwcli", process.cwd())
// } // }
} };
+3 -3
View File
@@ -66,6 +66,6 @@ export const confirmMessage = async (message: string) => {
} }
}; };
export const sleep = (milliseconds) => { export const sleep = milliseconds => {
return new Promise(resolve => setTimeout(resolve, milliseconds)) return new Promise(resolve => setTimeout(resolve, milliseconds));
} };
+45 -34
View File
@@ -1,12 +1,12 @@
import { Octokit } from "@octokit/core"; import { Octokit } from '@octokit/core';
export const getOrgRepos = async (toolbox, token, org) => { export const getOrgRepos = async (toolbox, token, org) => {
const { print } = toolbox; const { print } = toolbox;
const octokit = new Octokit({ auth: token }); const octokit = new Octokit({ auth: token });
try { try {
const response = await octokit.request("GET /orgs/{org}/repos", { const response = await octokit.request('GET /orgs/{org}/repos', {
org: org, org: org,
per_page: 100, per_page: 100
}); });
if (response.status === 200) { if (response.status === 200) {
return response.data; return response.data;
@@ -21,9 +21,9 @@ export const getRepo = async (toolbox, token, owner, repo) => {
const { print } = toolbox; const { print } = toolbox;
const octokit = new Octokit({ auth: token }); const octokit = new Octokit({ auth: token });
try { try {
const response = await octokit.request("GET /repos/{owner}/{repo}", { const response = await octokit.request('GET /repos/{owner}/{repo}', {
owner: owner, owner: owner,
repo: repo, repo: repo
}); });
if (response.status === 200) { if (response.status === 200) {
return response.data; return response.data;
@@ -32,19 +32,22 @@ export const getRepo = async (toolbox, token, owner, repo) => {
print.error('Not a valid organisation for your token access'); print.error('Not a valid organisation for your token access');
return null; return null;
} }
} };
export const getRepoBranches = async (toolbox, token, owner, repo) => { export const getRepoBranches = async (toolbox, token, owner, repo) => {
const { print } = toolbox; const { print } = toolbox;
const octokit = new Octokit({ auth: token }); const octokit = new Octokit({ auth: token });
const getBranches = async (toolbox, token, owner, repo, page) => { const getBranches = async (toolbox, token, owner, repo, page) => {
const response = await octokit.request("GET /repos/{owner}/{repo}/branches", { const response = await octokit.request(
owner: owner, 'GET /repos/{owner}/{repo}/branches',
repo: repo, {
page: page, owner: owner,
per_page: 100, repo: repo,
}); page: page,
per_page: 100
}
);
return response; return response;
}; };
@@ -62,29 +65,31 @@ export const getRepoBranches = async (toolbox, token, owner, repo) => {
} }
return allBranches; return allBranches;
} };
export const getOrgIssues = async (toolbox, token) => { export const getOrgIssues = async (toolbox, token) => {
// const { print } = toolbox; // const { print } = toolbox;
const repos = await getOrgRepos(toolbox, token, 'Photowall'); const repos = await getOrgRepos(toolbox, token, 'Photowall');
const repoNames = repos.map(item => item.name); const repoNames = repos.map(item => item.name);
const allIssues = await Promise.all(repoNames.map(async (repoName) => { const allIssues = await Promise.all(
const issues = await getOpenIssuesFromRepo(toolbox, token, repoName); repoNames.map(async repoName => {
// console.log(`${repoName} - issues`, issues.length); const issues = await getOpenIssuesFromRepo(toolbox, token, repoName);
// return issues.map(item => `${item.number}-${item.title.substring(0, 10)}`); // console.log(`${repoName} - issues`, issues.length);
return {repo: repoName, issues: issues}; // return issues.map(item => `${item.number}-${item.title.substring(0, 10)}`);
})); return { repo: repoName, issues: issues };
})
);
return allIssues.flat(); return allIssues.flat();
} };
export const getOpenIssuesFromRepo = async (toolbox, token, repo) => { export const getOpenIssuesFromRepo = async (toolbox, token, repo) => {
const { print } = toolbox; const { print } = toolbox;
const octokit = new Octokit({ auth: token }); const octokit = new Octokit({ auth: token });
try { try {
const response = await octokit.request("GET /repos/{owner}/{repo}/issues", { const response = await octokit.request('GET /repos/{owner}/{repo}/issues', {
owner: "Photowall", owner: 'Photowall',
repo: repo, repo: repo,
per_page: 100, per_page: 100
}); });
if (response.status === 200) { if (response.status === 200) {
return response.data; return response.data;
@@ -93,17 +98,20 @@ export const getOpenIssuesFromRepo = async (toolbox, token, repo) => {
print.error('Not a valid issuenumber for this repository'); print.error('Not a valid issuenumber for this repository');
return null; return null;
} }
} };
export const getIssueFromRepo = async (toolbox, token, repo, issueNumber) => { export const getIssueFromRepo = async (toolbox, token, repo, issueNumber) => {
const { print } = toolbox; const { print } = toolbox;
const octokit = new Octokit({ auth: token }); const octokit = new Octokit({ auth: token });
try { try {
const response = await octokit.request("GET /repos/{owner}/{repo}/issues/{issue_number}", { const response = await octokit.request(
owner: "Photowall", 'GET /repos/{owner}/{repo}/issues/{issue_number}',
repo: repo, {
issue_number: issueNumber, owner: 'Photowall',
}); repo: repo,
issue_number: issueNumber
}
);
if (response.status === 200) { if (response.status === 200) {
return response.data; return response.data;
} }
@@ -111,9 +119,14 @@ export const getIssueFromRepo = async (toolbox, token, repo, issueNumber) => {
print.error('Not a valid issuenumber for this repository'); print.error('Not a valid issuenumber for this repository');
return null; return null;
} }
} };
export const createPullRequest = async (toolbox, token: string, repo: string, branch: string) => { export const createPullRequest = async (
toolbox,
token: string,
repo: string,
branch: string
) => {
const { print } = toolbox; const { print } = toolbox;
const octokit = new Octokit({ auth: token }); const octokit = new Octokit({ auth: token });
try { try {
@@ -131,6 +144,4 @@ export const createPullRequest = async (toolbox, token: string, repo: string, br
print.error('Not a valid branch'); print.error('Not a valid branch');
return null; return null;
} }
};
}
+4 -1
View File
@@ -1,5 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"esModuleInterop": true,
"emitDecoratorMetadata": true,
"strictPropertyInitialization": false,
"allowSyntheticDefaultImports": false, "allowSyntheticDefaultImports": false,
"experimentalDecorators": true, "experimentalDecorators": true,
"lib": [ "lib": [
@@ -19,7 +22,7 @@
"inlineSourceMap": true, "inlineSourceMap": true,
"outDir": "build", "outDir": "build",
"strict": false, "strict": false,
"target": "es5", "target": "es2020",
"declaration": true, "declaration": true,
"declarationDir": "build/types" "declarationDir": "build/types"
}, },
+638 -110
View File
File diff suppressed because it is too large Load Diff