UNPKG

bitbucket-env-manager

Version:

Deploys Bitbucket Environment

198 lines (167 loc) 5.67 kB
#!/usr/bin/env node const { spinner, log, note } = require('@clack/prompts'); const color = require('picocolors'); const { guarded_create_env, guarded_create_var, guarded_delete_env, guarded_delete_var, guarded_get_envs, guarded_get_vars, guarded_get_repo_vars, guarded_create_repo_var, guarded_delete_repo_var, } = require('./guarded.api'); const { delay } = require('./helpers'); const { runConvert } = require('./convert'); const { apiSleepTime } = require('./config'); const run_repo_vars_setup = async (cfg) => { const s = spinner(); try { s.start(`Deploying repository variables for ${color.cyan(cfg.repo)}`); const mainParams = { repo_slug: cfg.repo, workspace: cfg.workspace, }; // Get existing repo variables const repoVarsString = await guarded_get_repo_vars({ ...mainParams }); const repoVars = JSON.parse(repoVarsString).values; const concurrency = 5; // Delete existing variables if (repoVars.length > 0) { s.message(`Removing ${repoVars.length} existing variable(s)...`); for (let i = 0; i < repoVars.length; i += concurrency) { const batch = repoVars.slice(i, i + concurrency); await Promise.all( batch.map((v) => guarded_delete_repo_var({ ...mainParams, variable_uuid: v.uuid })) ); await delay(apiSleepTime); } } const varLen = cfg.vars.length; // Upload new variables for (let i = 0; i < varLen; i += concurrency) { const batch = cfg.vars.slice(i, i + concurrency); const end = Math.min(i + concurrency, varLen); s.message(`Uploading ${color.dim(`(${i + 1}-${end}/${varLen})`)}`); await Promise.all( batch.map((v) => guarded_create_repo_var({ ...mainParams, var_key: v.key, var_value: v.value.toString(), var_secured: !!v.secured, }) ) ); await delay(apiSleepTime); } s.stop(color.green(`Repository variables deployed for ${cfg.repo}`)); } catch (e) { s.stop(color.red(`Failed to deploy repository variables for ${cfg.repo}`)); log.error(e.message); } }; const run_env_setup = async (cfg) => { const s = spinner(); const envLabel = `${cfg.repo} -> ${cfg.env_name}`; try { s.start(`Deploying ${color.cyan(envLabel)}`); const mainParams = { repo_slug: cfg.repo, workspace: cfg.workspace, env_config: cfg.env_config, }; const concurrency = 5; // Get existing env details const envsListString = await guarded_get_envs({ ...mainParams }); const envsList = JSON.parse(envsListString).values; const existingEnv = envsList.find((env) => env.slug === cfg.env_name.toLowerCase()); const desiredRank = Math.max(Math.min(cfg.rank, 2), 0); const rankMatches = existingEnv && existingEnv.environment_type && existingEnv.environment_type.rank === desiredRank; let targetEnv; if (existingEnv && rankMatches) { // Reuse existing env: clear its variables, keep the env itself const existingVarsString = await guarded_get_vars({ ...mainParams, environment_uuid: existingEnv.uuid, }); const existingVars = JSON.parse(existingVarsString).values || []; if (existingVars.length > 0) { s.message(`Clearing ${existingVars.length} existing variable(s)...`); for (let i = 0; i < existingVars.length; i += concurrency) { const batch = existingVars.slice(i, i + concurrency); await Promise.all( batch.map((v) => guarded_delete_var({ ...mainParams, environment_uuid: existingEnv.uuid, variable_uuid: v.uuid, }) ) ); await delay(apiSleepTime); } } targetEnv = existingEnv; } else { // Name/rank changed (or env missing) — delete (if any) and recreate if (existingEnv) { s.message('Removing existing environment...'); await guarded_delete_env({ ...mainParams, environment_uuid: existingEnv.uuid }); } s.message('Creating new environment...'); const newEnvString = await guarded_create_env({ ...mainParams, env_name: cfg.env_name, env_rank: cfg.rank, }); targetEnv = JSON.parse(newEnvString); } const varLen = cfg.vars.length; // Upload variables for (let i = 0; i < varLen; i += concurrency) { const batch = cfg.vars.slice(i, i + concurrency); const end = Math.min(i + concurrency, varLen); s.message(`Uploading ${color.dim(`(${i + 1}-${end}/${varLen})`)}`); await Promise.all( batch.map((v) => guarded_create_var({ ...mainParams, environment_uuid: targetEnv.uuid, var_key: v.key, var_value: v.value.toString(), var_secured: !!v.secured, }) ) ); await delay(apiSleepTime); } s.stop(color.green(`Deployed ${envLabel}`)); } catch (e) { s.stop(color.red(`Failed to deploy ${envLabel}`)); log.error(e.message); } }; const runDeploy = async () => { try { const cfgs = await runConvert({ multiple: true }); if (!cfgs || !cfgs.length) return; note(`Deploying ${cfgs.length} configuration(s)`, 'Deploy'); for (const cfg of cfgs) { if (cfg.is_repo) { await run_repo_vars_setup(cfg); } else { await run_env_setup(cfg); } } log.success('All deployments complete!'); } catch (e) { log.error(e.message); } }; module.exports = { runDeploy, run_env_setup, };