UNPKG

strider

Version:

Brilliant continuous deployment platform

447 lines 13.1 kB
const models = require('../'); const Job = models.Job; const User = models.User; const Project = models.Project; const async = require('async'); const utils = require('../../utils'); module.exports = function (done) { upgradeUsers(function (err) { if (err) return done(err); upgradeJobs(done); }); }; function upgradeJobs(done) { Job.collection.find({}, function (err, cursor) { if (err) return done(err); cursor.toArray(function (err, jobs) { if (err) return done(err); console.log('converting', jobs.length, 'jobs'); const tasks = []; jobs.forEach(function (job) { tasks.push(function (next) { upgradeJob(job, next); }); }); async.series(tasks, done); }); }); } function upgradeJob(job, done) { Job.findById(job._id) .lean() .exec(function (err, mjob) { if (err) return done(err); mjob.user_id = job._owner; mjob.project = makeName(job.repo_url); mjob.ref = { branch: 'master', }; if (job.github_commit_info) { mjob.ref.id = job.github_commit_info.id; } mjob.std = { out: job.stdout || '', err: job.stderr || '', merged: job.stdmerged || '', }; mjob.created = job.created_timestamp; mjob.finished = job.finished_timestamp; mjob.queued = mjob.created; mjob.started = mjob.created; mjob.duration = mjob.finished ? mjob.finished.getTime() - mjob.created.getTime() : 0; mjob.archived = job.archived_timestamp; mjob.trigger = makeTrigger(job, job.github_commit_info); mjob.plugin_data = {}; if (job.tasks && job.tasks.length) { mjob.plugin_data.sauce = job.tasks; } killAttrs(mjob, [ 'created_timestamp', 'finished_timestamp', 'archived_timestamp', '_owner', 'repo_url', 'stdout', 'stderr', 'stdmerged', 'tasks', ]); mjob.phases = { environment: { commands: [], }, prepare: { commands: [], }, test: { finished: mjob.finished, duration: mjob.duration, exitCode: mjob.test_exitcode, commands: [ { started: mjob.started, duration: mjob.duration, command: 'Legacy job output', out: mjob.std.out, err: mjob.std.err, merged: mjob.std.merged, }, ], }, deploy: { commands: [], }, cleanup: { commands: [], }, }; Job.collection.updateOne({ _id: job._id }, mjob, done); console.log('done job', job._id); }); } function makeTrigger(job, commit) { if (!commit) { return { type: 'manual', author: { id: job._owner, }, message: job.type === 'TEST_AND_DEPLOY' ? 'Redeploy' : 'Retest', timestamp: job.created_timestamp, source: { type: 'UI', page: 'Unknown' }, }; } commit.author.image = utils.gravatar(commit.author.email); return { type: 'commit', author: commit.author, message: commit.message, timestamp: commit.timestamp, url: `${job.repo_url}/commit/${commit.id}`, source: { type: 'plugin', plugin: 'github' }, }; } function upgradeUsers(done) { User.collection.find({}, function (err, cursor) { if (err) return done(err); cursor.toArray(function (err, users) { if (err) return done(err); console.log('converting users', users.length); const tasks = []; users.forEach(function (user) { tasks.push(function (next) { upgradeUser(user, next); }); }); async.series(tasks, done); }); }); } function makeGithubRepos(user) { if (!user.github) return []; const github = user.github_metadata[user.github.id].repos; const repos = []; for (let i = 0; i < github.length; i++) { repos.push({ id: `${github[i].id}`, name: github[i].full_name && github[i].full_name.toLowerCase(), display_name: github[i].full_name, group: github[i].owner.login, display_url: github[i].html_url, config: { url: `git://${github[i].clone_url.split('//')[1]}`, owner: github[i].owner.login, repo: github[i].name, auth: { type: 'https', }, }, }); } return repos; } // remove attributes from a model function killAttrs(model, attrs) { for (let i = 0; i < attrs.length; i++) { delete model[attrs[i]]; } } function makeHerokuAccounts(user) { if (!user.heroku || !user.heroku.length) return { accounts: [], apps: {} }; const keys = {}; const accounts = []; const caches = {}; const apps = {}; user.heroku.forEach(function (account) { let aid = account.account_id.split('@')[0]; if (keys[account.api_key]) { aid = keys[account.api_key]; } else { caches[account.api_key] = []; } apps[account.account_id] = { id: account.account_id.split('@')[0].split('-')[1], name: account.app, account: aid, git_url: `git@heroku.com:${account.app}.git`, web_url: `http://${account.app}.herokuapp.com/`, }; caches[account.api_key].push(apps[account.account_id]); if (keys[account.api_key]) { return; } keys[account.api_key] = aid; accounts.push({ id: aid, api_key: account.api_key, email: aid, privkey: account.privkey, pubkey: account.pubkey, cache: caches[account.api_key], }); }); return { accounts: accounts, apps: apps, }; } function upgradeUser(user, done) { User.findById(user._id) .lean() .exec(function (err, mongUser) { const heroku = makeHerokuAccounts(user); mongUser.accounts = []; if (user.github && user.github.id) { mongUser.accounts.push({ provider: 'github', id: user.github.id, display_url: `https://github.com/${user.github.login}`, title: user.github.login, config: convertGithub(user), cache: makeGithubRepos(user), }); } mongUser.jobplugins = { heroku: { accounts: heroku.accounts, }, }; mongUser.projects = []; killAttrs(mongUser, [ 'github', 'github_config', 'github_metadata', 'dotcloud_config', 'heroku', ]); const projects = []; if (user.github_config && user.github_config.length > 0) { for (let i = 0; i < user.github_config.length; i++) { const repo_config = user.github_config[i]; const name = makeName(repo_config.display_url); mongUser.projects.push({ name: name.toLowerCase(), display_name: name, access_level: 2, }); projects.push(makeProject(name, repo_config, user, heroku)); } } Project.create(projects, function (err) { if (err) return done(err); User.collection.updateOne({ _id: mongUser._id }, mongUser, done); }); console.log('projects', projects.length, user._id); }); } function makeName(url) { return url.split('/').slice(-2).join('/').split('.')[0]; } function makeProvider(name, repo, user) { // TODO: how do I know if it's not github? const parts = name.split('/'); const repos = user.github_metadata[user.github.id].repos; let url = `git://${repo.display_url.split('//')[1]}.git`; let id = null; for (let i = 0; i < repos.length; i++) { if (repos[i].html_url === repo.display_url) { id = repos[i].id; url = `git://${repos[i].git_url.split('//')[1]}`; break; } } return { id: 'github', repo_id: id, account: user.github.id, config: { url: url, owner: parts[0], repo: parts[1], auth: { type: 'https', }, }, }; } // plugins that we need: // node // // Optional: // browserstack // webhooks // heroku // custom // env // jelly // qunit // sauce const checkPlugins = { sauce: function (repo) { if (!repo.sauce_access_key) return; return { access_key: repo.sauce_access_key, username: repo.sauce_username, browsers: repo.sauce_browsers, }; }, qunit: function (repo) { if (!repo.qunit_file) return; return { file: repo.qunit_file, path: repo.qunit_path, }; }, jelly: function (repo) { if (!repo.jelly_payload) return; return { url: repo.jelly_url, port: repo.jelly_port, payload: repo.jelly_payload, static: repo.jelly_static, static_dir: repo.jelly_static_dir, }; }, env: function (repo) { return repo.env; }, custom: function (repo) { return repo.custom; }, heroku: function (repo, user, heroku) { if (!repo.prod_deploy_target || repo.prod_deploy_target.provider !== 'heroku') return; const account_id = repo.prod_deploy_target.account_id; return { app: heroku.apps[account_id] }; }, webhooks: function (repo) { if (!repo.webhooks || !repo.webhooks.length) return; const hooks = []; let hook; for (let i = 0; i < repo.webhooks.length; i++) { hook = repo.webhooks[i]; hooks.push({ id: hook._id, url: hook.url, secret: hook.secret, format: '', trigger: 'job.done', }); } return hooks; }, browserstack: function (repo) { if (!repo.browserstack_api_key) return; return { apiKey: repo.browserstack_api_key, username: repo.browserstack_username, password: repo.browserstack_password, browsers: repo.browserstack_browsers, }; }, }; function makePlugins(repo, user, heroku) { const plugins = [ { id: 'node', enabled: true, config: { test: 'npm install', runtime: 'whatever', }, }, ]; Object.keys(checkPlugins).forEach(function (name) { const config = checkPlugins[name](repo, user, heroku); if (!config) return; plugins.push({ id: name, enabled: true, config: config, }); }); return plugins; } function makeBranch(repo, user, heroku) { return { active: repo.active, name: 'master', mirror_master: false, deploy_on_green: repo.prod_deploy_target && repo.prod_deploy_target.deploy_on_green, deploy_on_pull_request: false, pubkey: repo.pubkey, privkey: repo.privkey, plugins: makePlugins(repo, user, heroku), plugin_data: {}, runner: { id: 'simple-runner', config: { pty: false, }, }, }; } function makeProject(name, repo, user, heroku) { return { name: name.toLowerCase(), secret: repo.secret, public: repo.public, display_name: name, display_url: repo.display_url, creator: user._id, branches: [makeBranch(repo, user, heroku)], provider: makeProvider(name, repo, user), }; } function convertGithub(user) { if (!user.github) return {}; const g = user.github; return { accessToken: g.accessToken, login: g.login, email: g.email, gravatarId: g.gravatarId, name: g.name, }; } //# sourceMappingURL=from0to1.js.map