UNPKG

@purinton/knit

Version:

GitHub webhook handler and deployment automation tool. Listens for GitHub webhook events, validates signatures, updates repositories, runs deployment commands, and sends notifications.

152 lines (145 loc) 4.95 kB
import { fs as defaultFs, path as defaultPath, log as logger } from '@purinton/common'; import inquirer from 'inquirer'; /** * Interactive setup wizard for repository configuration. */ export async function runWizard({ log = logger, getCommands: getCommandsFn = getCommands, fs = defaultFs, path = defaultPath } = {}) { try { log.info('Starting interactive setup wizard'); const { repoName } = await inquirer.prompt([ { type: 'input', name: 'repoName', message: 'Repository Name (owner/repo):', validate: input => /^.+\/.+$/.test(input) || 'Invalid repository name format. Use owner/repo.' } ]); const [owner, repo] = repoName.split('/'); const { installPath } = await inquirer.prompt([ { type: 'input', name: 'installPath', message: 'Install Path:', validate: input => Boolean(input) || 'Install path cannot be empty.' } ]); const preCommands = await getCommandsFn('pre-deployment'); let postCommands = []; // npm install (default yes) const { runNpm } = await inquirer.prompt([ { type: 'confirm', name: 'runNpm', message: 'Do you want to run npm install?', default: true } ]); if (runNpm) { postCommands.push('npm install --silent'); // npm test (default yes) const { runNpmTest } = await inquirer.prompt([ { type: 'confirm', name: 'runNpmTest', message: 'Do you want to run npm test?', default: true } ]); if (runNpmTest) { postCommands.push('npm test > .jest.result 2>&1'); } } postCommands = postCommands.concat(await getCommandsFn('post-deployment')); const { user } = await inquirer.prompt([ { type: 'input', name: 'user', message: 'User:', default: 'root' } ]); const { group } = await inquirer.prompt([ { type: 'input', name: 'group', message: 'Group:', default: 'root' } ]); // Remove default webhook URL const { notify } = await inquirer.prompt([ { type: 'input', name: 'notify', message: 'Notification URL:' } ]); const config = buildConfig(installPath, preCommands, user, group, postCommands, notify); const jsonConfig = JSON.stringify(config, null, 2); const filePath = await saveConfigurationFile(owner, repo, jsonConfig, fs, path); printRepositoryInfo(filePath); log.info('Repository configuration complete'); } catch (err) { log.error('Wizard error:', err); } } export async function getCommands(type) { const commands = []; const { hasCommand } = await inquirer.prompt([ { type: 'confirm', name: 'hasCommand', message: `Do you have any ${type} commands?`, default: false } ]); if (!hasCommand) return commands; let addMore = true; while (addMore) { const { cmd } = await inquirer.prompt([ { type: 'input', name: 'cmd', message: `Enter a ${type} command:`, validate: input => !!input || 'Command cannot be empty.' } ]); commands.push(cmd); const { more } = await inquirer.prompt([ { type: 'confirm', name: 'more', message: `Do you have another ${type} command?`, default: false } ]); addMore = more; } return commands; } function buildConfig(installPath, pre, user, group, post, notify) { return { pwd: installPath, pre, user, group, post, notify }; } async function saveConfigurationFile(owner, repo, jsonConfig, fs = defaultFs, path = defaultPath) { const dirPath = path(import.meta, '..', 'repos', owner); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } const filePath = path(dirPath, `${repo}.json`); fs.writeFileSync(filePath, jsonConfig); return filePath; } function printRepositoryInfo(filePath) { console.log(`Repository configuration saved to ${filePath}`); console.log('\nReminder: Set the GitHub webhook!\nURL to https://knit.purinton.us\nPOST: application/json\n'); } if (process.env.NODE_ENV !== 'test') { runWizard(); }