|
|
@@ -1,9 +1,9 @@ |
|
|
|
// const Queue = require('bull'); |
|
|
|
const secrets = require('../lib/secrets'); |
|
|
|
const secrets = require('../../lib/secrets'); |
|
|
|
const generator = require('./generator'); |
|
|
|
const build = require('../lib/builderator'); |
|
|
|
const { log } = require('../lib/logging'); |
|
|
|
const { transporter } = require('../lib/mail'); |
|
|
|
const build = require('../../lib/builderator'); |
|
|
|
const { log } = require('../../lib/logging'); |
|
|
|
const { transporter } = require('../../lib/mail'); |
|
|
|
const fs = require('fs').promises; |
|
|
|
const exists = require('fs').existsSync; |
|
|
|
const pm2 = require('pm2'); |
|
|
@@ -12,8 +12,25 @@ const assert = require('assert'); |
|
|
|
|
|
|
|
// const gitQ = new Queue('ci.git', secrets.redis); |
|
|
|
|
|
|
|
const dev_server_wait = {resources: ['http://localhost:3000'], delay: 1000, timeout: 30000}; |
|
|
|
const prod_server_wait = {resources: ['http://localhost:7778'], delay: 1000, timeout: 30000}; |
|
|
|
const config = { |
|
|
|
private: '../ljsthw-private/', |
|
|
|
testing_target: 'deployment/testing', |
|
|
|
prod_target: 'deployment/production', |
|
|
|
fixtures: '__tests__/fixtures', |
|
|
|
email: { |
|
|
|
to: 'zed@learnjsthehardway.com', |
|
|
|
from: '"CI from LJSTHW" ci@learnjsthehardway.com', |
|
|
|
subject: 'Build complete', |
|
|
|
text: `CI build completed.` |
|
|
|
}, |
|
|
|
state_file: 'deployment/cistate.json', |
|
|
|
dev_server_wait: { |
|
|
|
resources: ['http://localhost:3000'], delay: 1000, timeout: 30000 |
|
|
|
}, |
|
|
|
prod_server_wait: { |
|
|
|
resources: ['http://localhost:7778'], delay: 1000, timeout: 30000 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const pm2_restart = (name) => { |
|
|
|
log.debug(`Restarting the ${name} process.`); |
|
|
@@ -47,22 +64,22 @@ const needs_tests = build.rule('needs tests run', { |
|
|
|
then: async (f) => { |
|
|
|
log.info("Generating test fixtures"); |
|
|
|
// generate test fixtures |
|
|
|
await generator.run('tests/fixtures', 'deployment/testing'); |
|
|
|
await generator.run(config.fixtures, config.testing_target); |
|
|
|
|
|
|
|
log.debug('Linking in the new content'); |
|
|
|
if(exists('protected')) { |
|
|
|
await fs.unlink('protected'); // removes the symlink |
|
|
|
} |
|
|
|
|
|
|
|
log.debug('Creating symlink protected to deployment/testing'); |
|
|
|
await fs.symlink('./deployment/testing', 'protected'); |
|
|
|
log.debug(`Creating symlink protected to ${config.testing_target}`); |
|
|
|
await fs.symlink(config.testing_target, 'protected'); |
|
|
|
|
|
|
|
log.debug("Finished generating the tests now running them."); |
|
|
|
|
|
|
|
process.env.HEADLESS=1; |
|
|
|
|
|
|
|
pm2_restart('ljsthw-dev'); |
|
|
|
await waitOn(dev_server_wait); |
|
|
|
await waitOn(config.dev_server_wait); |
|
|
|
|
|
|
|
log.info("---- Running tests..."); |
|
|
|
let res = build.exec('npm run test'); |
|
|
@@ -81,7 +98,7 @@ const needs_git_pull = build.rule('needs git pull', { |
|
|
|
let git = build.exec(`git pull`, {}).toString(); |
|
|
|
log.debug("GIT code", git); |
|
|
|
f.code_updated = git != 'Already up to date.\n'; |
|
|
|
git = build.exec(`git pull`, {cwd: '../ljsthw-private'}).toString(); |
|
|
|
git = build.exec(`git pull`, {cwd: config.private}).toString(); |
|
|
|
f.media_updated = git != 'Already up to date.\n'; |
|
|
|
log.debug("GIT media", git); |
|
|
|
|
|
|
@@ -95,15 +112,7 @@ const needs_email_notify = build.rule('needs email notification', { |
|
|
|
then: f => { |
|
|
|
log.info("Sending notification email with results."); |
|
|
|
// email that it's done for visual testing |
|
|
|
|
|
|
|
let options = { |
|
|
|
to: 'zed@learnjsthehardway.com', |
|
|
|
from: '"CI from LJSTHW" ci@learnjsthehardway.com', |
|
|
|
subject: 'Build complete', |
|
|
|
text: `CI build completed.` |
|
|
|
} |
|
|
|
|
|
|
|
transporter.sendMail(options, (err, info) => { |
|
|
|
transporter.sendMail(config.email, (err, info) => { |
|
|
|
if(err) { |
|
|
|
log.error(err); |
|
|
|
} else { |
|
|
@@ -125,7 +134,8 @@ const needs_prod_media = build.rule('needs production media', { |
|
|
|
// need to get the videos into the web server somehow |
|
|
|
// and other media. Need a difference between generated media and source media |
|
|
|
// why can't source media be in the db? |
|
|
|
await generator.run('../ljsthw-private', 'deployment/production'); |
|
|
|
|
|
|
|
await generator.run(config.private, config.prod_target); |
|
|
|
|
|
|
|
f.prod_media_ready = true; |
|
|
|
} |
|
|
@@ -143,7 +153,7 @@ const needs_prod_code = build.rule('needs production code', { |
|
|
|
|
|
|
|
// tell pm2 reload |
|
|
|
pm2_restart('ljsthw'); |
|
|
|
await waitOn(prod_server_wait); |
|
|
|
await waitOn(config.prod_server_wait); |
|
|
|
|
|
|
|
f.build_complete = true; |
|
|
|
} |
|
|
@@ -155,13 +165,11 @@ const targets = [ |
|
|
|
needs_git_pull, needs_tests |
|
|
|
] |
|
|
|
|
|
|
|
const state_file = 'deployment/cistate.json'; |
|
|
|
|
|
|
|
const run = async () => { |
|
|
|
let facts; |
|
|
|
|
|
|
|
if(exists(state_file)) { |
|
|
|
facts = JSON.parse(await fs.readFile(state_file)); |
|
|
|
if(exists(config.state_file)) { |
|
|
|
facts = JSON.parse(await fs.readFile(config.state_file)); |
|
|
|
log.debug("FACTS", facts); |
|
|
|
} else { |
|
|
|
facts = {git_push_received: true}; |
|
|
@@ -172,7 +180,7 @@ const run = async () => { |
|
|
|
} catch(error) { |
|
|
|
log.error(error, "Running build."); |
|
|
|
} finally { |
|
|
|
await fs.writeFile(state_file, JSON.stringify(facts)); |
|
|
|
await fs.writeFile(config.state_file, JSON.stringify(facts)); |
|
|
|
} |
|
|
|
} |
|
|
|
|