Skip to content
This repository was archived by the owner on Nov 23, 2024. It is now read-only.
Open
23 changes: 18 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,31 @@ node_js:
- "7"
sudo: false
dist: trusty
before_install:
- gem install zendesk_apps_tools
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- libstdc++-4.9-dev
env:
- TASK=yarn_test
- SECURITYSCAN=srcclr
- TASK=test
- TASK=srcclr
- TASK=test:integration
matrix:
fast_finish: true
allow_failures:
- TASK=test:integration
script:
- |
if [[ "$SECURITYSCAN" == "srcclr" ]]
if [[ "$TASK" == "srcclr" ]]
then
echo "Starting Source clear ..."
curl -sSL https://download.sourceclear.com/ci.sh | bash
else
echo "Running Yarn tests"
yarn test
echo "Running tests"
yarn run $TASK
fi
cache: yarn
branches:
Expand Down
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
},
"scripts": {
"build": "tsc -p .",
"build-watch": "nodemon --watch src --ext ts --exec yarn build",
"build:watch": "nodemon --watch src --ext ts --exec yarn build",
"pretest": "yarn run build",
"test": "mocha ./lib/test/**/*.test.js",
"test": "mocha ./lib/test/steps/*.test.js",
"preversion": "yarn run build",
"postversion": "git push --follow-tags && yarn publish",
"test-watch": "nodemon --watch src --ext ts --exec yarn test"
"test:watch": "nodemon --watch src --ext ts --exec yarn test",
"test:integration":
"yarn run build && mocha --timeout 60000 ./lib/test/integration/*.test.js"
},
"author": "Zendesk <support@zendesk.com>",
"license": "Apache-2.0",
Expand All @@ -41,11 +43,10 @@
"progress": "^2.0.0",
"recast": "^0.12.6",
"shelljs": "^0.7.8",
"tslib": "^1.7.1"
"tslib": "^1.7.1",
"winston": "^2.3.1"
},
"bundledDependencies": [
"app_scaffold"
],
"bundledDependencies": ["app_scaffold"],
"devDependencies": {
"@types/babel-generator": "^6.25.0",
"@types/babel-traverse": "^6.25.2",
Expand All @@ -65,6 +66,7 @@
"eslint-config-prettier": "^2.3.0",
"eslint-plugin-prettier": "^2.2.0",
"mocha": "^3.5.0",
"nodegit": "^0.20.2",
"nodemon": "^1.11.0",
"sinon": "^3.2.1",
"ts-node": "^3.3.0",
Expand Down
22 changes: 13 additions & 9 deletions src/migrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { emojify } from "node-emoji";
import * as ProgressBar from "progress";
import { List, Map } from "immutable";
import { prompt } from "inquirer";
import * as logger from "winston";

// This monkeypatch is necessary for for–await-of to work in Typescript v2.4+
(Symbol as any).asyncIterator =
Expand All @@ -15,6 +16,8 @@ export interface CliOptions {
path: string;
replaceV1?: boolean;
auto?: boolean;
force?: boolean;
quiet?: boolean;
}

class Migrator {
Expand Down Expand Up @@ -43,6 +46,7 @@ class Migrator {
]);

constructor() {
logger.cli();
this.progressBar = new ProgressBar(
` [:bar] ${chalk.bold(":current/:total")} steps complete`,
{
Expand All @@ -59,11 +63,7 @@ class Migrator {
// work out why there is a type incompatibility with the iterator
for (const stepName of <any>Migrator.steps) {
options = options.set("step", stepName);
// console.log(chalk.bold.gray.underline(`Starting step: ${stepName}`));
// FIXME: Work out why dynamic imports aren't working in the downlevel
// https://blogs.msdn.microsoft.com/typescript/2017/06/27/announcing-typescript-2-4/
const step = require(`./steps/${stepName}`).default;
// const step = await import(`./steps/${stepName}`);
const newOptions = await step(options);
options = options.merge(newOptions);
yield options;
Expand All @@ -81,8 +81,11 @@ class Migrator {
const options: Map<string, any> = Map({
editor
}).merge(cliOptions);

if (cliOptions.auto) {
// This is so that when we're running in CI mode, we can silence
// all of the noise and just report on pass/fail
if (cliOptions.quiet) logger.level = "error";
// Force may be used in CI mode so that confirmation is assumed
if (cliOptions.auto && !cliOptions.force) {
const { auto } = await prompt([
{
type: "confirm",
Expand All @@ -94,7 +97,7 @@ class Migrator {
}
]);
if (!auto) {
console.log(
logger.warn(
chalk.bold.red(`Migration cancelled ${emojify(":crying_cat_face:")}`)
);
return;
Expand All @@ -105,9 +108,10 @@ class Migrator {
// into the next step
try {
for await (const newOptions of migratr.perform(options)) {
if (!migratr.progressBar.complete) migratr.progressBar.tick();
if (!migratr.progressBar.complete && !cliOptions.quiet)
migratr.progressBar.tick();
}
console.log(chalk.bold.green(emojify("Finished all steps! :rocket:")));
logger.info(chalk.bold.green(emojify("Finished all steps! :rocket:")));
} catch (err) {
migratr.progressBar.interrupt(chalk.bold.red(err.message));
throw err;
Expand Down
14 changes: 8 additions & 6 deletions src/steps/run_scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { merge } from "lodash";
import * as chalk from "chalk";
import * as emoji from "node-emoji";
import { join, sep } from "path";
import * as logger from "winston";

const runShellScript = (cmd, cwd = __dirname, options = {}) => {
return new Promise((res, rej) => {
Expand All @@ -29,10 +30,11 @@ const runShellScript = (cmd, cwd = __dirname, options = {}) => {

export default async (options: Map<string, any>) => {
const dest = options.get("dest");
console.log(chalk.bold.green("Installing dependencies"));
await runShellScript("yarn install --force", dest);
console.log(chalk.bold.green("Building v2 app"));
await runShellScript("yarn run build", dest);
console.log(chalk.bold.green("Validating v2 app"));
await runShellScript(`zat validate --path ${join(dest, "dist", sep)}`);
const silent = options.get("quiet", false);
logger.info(chalk.bold.green("Installing dependencies"));
await runShellScript("yarn install --force", dest, { silent });
logger.info(chalk.bold.green("Building v2 app"));
await runShellScript("yarn run build", dest, { silent });
logger.info(chalk.bold.green("Validating v2 app"));
await runShellScript(`zat validate .`, join(dest, "dist", sep), { silent });
};
7 changes: 4 additions & 3 deletions src/steps/setup_paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { emojify } from "node-emoji";
import { existsSync } from "fs";
import { get } from "lodash";
import * as chalk from "chalk";
import * as logger from "winston";

export default async (options: Map<string, any>) => {
let src = options.get("path");
const dest = join(src, "v2", sep);
const replaceV1 = options.get("replaceV1", false);
// Log out the `src` and `dest` paths for developer reference
console.log(chalk.yellow(`App will be migrated from: ${src}`));
console.log(chalk.yellow(`App will be migrated to: ${dest}`));
logger.info(chalk.yellow(`App will be migrated from: ${src}`));
logger.info(chalk.yellow(`App will be migrated to: ${dest}`));
// If we're replacing the v1 app, we should copy everything to `v1`
if (replaceV1) {
let pkg;
Expand All @@ -39,7 +40,7 @@ export default async (options: Map<string, any>) => {
if (!replace) {
throw new Error(`Migration cancelled ${emojify(":crying_cat_face:")}`);
}
console.log(chalk.bold.yellow(`v1 App will be backed up to: ${src}/v1/`));
logger.info(chalk.bold.yellow(`v1 App will be backed up to: ${src}/v1/`));
}
return options.merge({
src,
Expand Down
53 changes: 53 additions & 0 deletions src/test/integration/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env node
import * as Git from "nodegit";
import { expect } from "chai";
import { rm } from "shelljs";
import { merge } from "lodash";
import { basename, join } from "path";
import { mkdtempSync } from "fs";
import Migrator from "../../migrator";

describe("integration tests", () => {
let path;

const options = {
auto: true,
force: true,
quiet: true
};
const apps: any[] = [
{ repo: "user_data_app" },
{ repo: "five_most_recent_app" },
{ repo: "timetracking_app" },
{ repo: "answer_suggestion_app" },
{ repo: "linked_ticket_app" },
{ repo: "notification_app" },
{ repo: "search_app" },
{ repo: "bookmarks_app" },
// { repo: "hangouts_app" },
{ repo: "text_app" },
{ repo: "highrise_app" },
// { repo: "box_app" },
{ repo: "infusionsoft_app" },
{ repo: "iframe_app" }
];

afterEach(() => {
rm("-rf", path);
});

async function prepareApp(app): Promise<string> {
const tmp = mkdtempSync(join(process.cwd(), "tmp"));
const repo = await Git.Clone(`https://github.com/zendesk/${app.repo}`, tmp);
return tmp;
}

apps.forEach(app => {
describe(`migrate: ${app.repo}`, () => {
it("should migrate without errors", async () => {
path = await prepareApp(app);
await Migrator.migrate(merge({ path }, options));
});
});
});
});
Loading