From a933dd8bc4b8003e2e3f74a5da628874a4c608d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arwid=20Thornstro=CC=88m?= Date: Fri, 3 Feb 2023 14:37:28 +0100 Subject: [PATCH] track a pipeline --- src/commands/aws/pipeline/pipeline.ts | 15 +++ src/commands/aws/pipeline/status/status.ts | 108 +++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 src/commands/aws/pipeline/pipeline.ts create mode 100644 src/commands/aws/pipeline/status/status.ts diff --git a/src/commands/aws/pipeline/pipeline.ts b/src/commands/aws/pipeline/pipeline.ts new file mode 100644 index 0000000..33cf2ff --- /dev/null +++ b/src/commands/aws/pipeline/pipeline.ts @@ -0,0 +1,15 @@ +import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu'; +import { defaultMenuSettings } from '../../../globals'; + +/** + * Section1 menu + */ +module.exports = { + name: 'pipeline', + alias: ['pl'], + description: 'Pipeline (pl)', + hidden: false, + run: async (toolbox: GluegunMenuToolbox) => { + await toolbox.menu.showMenu('aws pipeline', defaultMenuSettings); + } +}; diff --git a/src/commands/aws/pipeline/status/status.ts b/src/commands/aws/pipeline/status/status.ts new file mode 100644 index 0000000..a3212b4 --- /dev/null +++ b/src/commands/aws/pipeline/status/status.ts @@ -0,0 +1,108 @@ +import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu'; +import chalk = require('chalk'); +import { exit } from 'process'; +import { defaultMenuSettings, sleep } from '../../../../globals'; +const { AutoComplete } = require('enquirer'); + +type Pipeline = { + name: string; + version: number; + created: string; + updated: string; +}; + +type StageState = { + stageName: string; + latestExecution: { + status: string; + }; +}; + +module.exports = { + name: 'status', + alias: ['s'], + description: 'Pipeline Status (s)', + hidden: false, + run: async (toolbox: GluegunMenuToolbox) => { + const { system, strings, print } = toolbox; + + const pipelines = JSON.parse( + strings.trim(await system.run(`aws codepipeline list-pipelines`)) + ); + + const testPipelines = pipelines.pipelines.filter(item => { + return item.name.indexOf('photowall-test-') > -1; + }); + + const curratedPipes: Pipeline[] = testPipelines.filter(Boolean); + const options = curratedPipes.map(item => { + return item.name; + }); + + const prompt = new AutoComplete({ + name: 'pipelines', + message: 'Choose a pipeline', + limit: options.length - 1, + initial: options.length - 1, + choices: options + }); + + try { + const pipelineName = await prompt.run(); + + const spinner = print.spin(`Tracking pipeline status`); + const getArrow = (pos: number) => { + const o = '---------------'.split(''); // 0-14 + return o.map((char, index) => { + if (index === pos) { + return chalk.bold.magenta('>'); + } + return chalk.cyan(char); + }); + }; + + while (true) { + const pipelineState = JSON.parse( + await system.run( + `aws codepipeline get-pipeline-state --name ${pipelineName}`, + { trim: true } + ) + ); + const states = {}; + for (const state of pipelineState.stageStates) { + const s = state.latestExecution.status; + switch (s) { + case 'InProgress': + states[state.stageName] = chalk.blue('IN PROGRESS'); + break; + case 'Succeeded': + states[state.stageName] = chalk.green('DONE'); + break; + case 'Failed': + states[state.stageName] = chalk.red('FAILED'); + break; + } + } + + let pos = 0; + while (pos < 15) { + const arrow = getArrow(pos); + arrow.splice(15, 0, ` Deploy: [${states['Deploy']}] `); + arrow.splice(10, 0, ` Build: [${states['Build']}] `); + arrow.splice(5, 0, ` Source: [${states['Source']}] `); + spinner.text = arrow.join(''); + pos += 1; + await sleep(500); + } + } + } catch (e) { + console.log(`e`, e); + } + + if (toolbox.fromMenu()) { + await toolbox.menu.showMenu('aws pipeline', defaultMenuSettings); + } else { + exit(); + } + } +};