浏览代码

Publisher Upgrade

sebavan 6 年之前
父节点
当前提交
7f73dd709b

+ 1 - 1
Tools/Config/config.js

@@ -16,7 +16,7 @@ const distES6Folder = path.join(tempFolder, config.build.distES6FolderName);
 const packageES6Folder = path.join(tempFolder, config.build.packageES6FolderName);
 const packageES6DevFolder = path.join(tempFolder, config.build.packageES6DevFolderName);
 
-const tempTypingsAMDFileName = config.tempTypingsAMDFileName;
+const tempTypingsAMDFileName = config.build.tempTypingsAMDFileName;
 const tempTypingsFileName = tempTypingsAMDFileName.replace(".js", ".d.ts");
 const tempTypingsAMDFilePath = path.join(tempFolder, tempTypingsAMDFileName);
 const tempTypingsFilePath = path.join(tempFolder, tempTypingsFileName);

+ 2 - 2
Tools/Config/config.json

@@ -625,7 +625,7 @@
                     ]
                 }
             ],
-            "legacyPackageOutputDirectory": "../../Viewer/build/src/",
+            "legacyPackageOutputDirectory": "../../../Viewer/build/src/",
             "requiredFiles": [
                 "dist/preview release/viewer/readme.md",
                 "dist/preview release/viewer/package.json",
@@ -667,7 +667,7 @@
                     "minified": true
                 }
             ],
-            "legacyPackageOutputDirectory": "../../Viewer/build/assets/",
+            "legacyPackageOutputDirectory": "../../../Viewer/build/assets/",
             "requiredFiles": [
                 "Viewer/assets/readme.md",
                 "Viewer/assets/package.json"

+ 24 - 0
Tools/Publisher/helpers/getFiles.js

@@ -0,0 +1,24 @@
+// Dependecies.
+const fs = require('fs-extra');
+
+/**
+ * Get Files from folder.
+ */
+const getFiles = function(dir, files_) {
+    files_ = files_ || [];
+    var files = fs.readdirSync(dir);
+    for (var i in files) {
+        var name = dir + '/' + files[i];
+        if (fs.statSync(name).isDirectory()) {
+            getFiles(name, files_);
+        } else {
+            files_.push(name);
+        }
+    }
+    return files_;
+}
+
+/**
+ * Get Files from folder.
+ */
+module.exports = getFiles;

+ 37 - 0
Tools/Publisher/helpers/publish.js

@@ -0,0 +1,37 @@
+// Dependecies.
+const shelljs = require('shelljs');
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+/**
+ * Publish a package to npm.
+ */
+function publish(version, packageName, publishPath, public) {
+    colorConsole.log('    Publishing ' + packageName.blue.bold + " from " + publishPath.cyan);
+
+    let tag = "";
+    // check for alpha or beta
+    if (version.indexOf('alpha') !== -1 || version.indexOf('beta') !== -1) {
+        tag = ' --tag preview';
+    }
+
+    //publish the respected package
+    var cmd = 'npm publish "' + publishPath + '"' + tag;
+    if (public) {
+       cmd += " --access public";
+    }
+
+    if (process.env.BABYLONJSREALPUBLISH === "true") {
+        colorConsole.log("    Executing: " + cmd.yellow);
+        shelljs.exec(cmd);
+    }
+    else {
+        colorConsole.log("    If publishing enabled: " + cmd.yellow);
+    }
+
+    colorConsole.success('    Publishing ' + "OK".green);
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = publish;

+ 2 - 16
Tools/Publisher/index.js

@@ -1,18 +1,4 @@
 // Dependecies.
-const publisher = require('./publisher');
+const publisher = require('./tasks/main');
 
-// CMD Arguments Management.
-const doNotBuild = process.argv.indexOf('--no-build') === -1;
-const doNotPublish = process.argv.indexOf('--no-publish') === -1;
-
-// Gets the current npm user.
-console.log("Using npm user:");
-let loginCheck = shelljs.exec('npm whoami');
-// If logged in process.
-if (loginCheck.code === 0) {
-    publisher(doNotBuild, doNotPublish, true);
-}
-// If not logged in error.
-else {
-    console.log('Not logged in, please log in to npm.');
-}
+publisher(false);

+ 15 - 0
Tools/Publisher/production.js

@@ -0,0 +1,15 @@
+// Dependecies.
+const shelljs = require('shelljs');
+const publisher = require('./tasks/main');
+
+// Gets the current npm user.
+console.log("Using npm user:");
+let loginCheck = shelljs.exec('npm whoami');
+// If logged in process.
+if (loginCheck.code === 0) {
+    publisher(true);
+}
+// If not logged in error.
+else {
+    console.log('Not logged in, please log in to npm.');
+}

+ 0 - 479
Tools/Publisher/publisher.js

@@ -1,479 +0,0 @@
-// Dependecies.
-const prompt = require('prompt');
-const shelljs = require('shelljs');
-const fs = require('fs-extra');
-const path = require('path');
-const rmDir = require("../NodeHelpers/rmDir");
-const colorConsole = require("../NodeHelpers/colorConsole");
-
-// CMD Arguments Management.
-let doNotBuild = false;
-let doNotPublish = false;
-
-// Path management.
-process.env.PATH += (path.delimiter + path.join(__dirname, 'node_modules', '.bin'));
-
-// Global Variables.
-const config = require("../Config/config.js");
-const modules = config.modules.concat(config.viewerModules);
-const enginePath = path.join(config.core.computed.srcDirectory, "Engines/engine.ts");
-
-/**
- * Get Files from folder.
- */
-const getFiles = function(dir, files_) {
-    files_ = files_ || [];
-    var files = fs.readdirSync(dir);
-    for (var i in files) {
-        var name = dir + '/' + files[i];
-        if (fs.statSync(name).isDirectory()) {
-            getFiles(name, files_);
-        } else {
-            files_.push(name);
-        }
-    }
-    return files_;
-}
-
-/**
- * Update the version in the engine class for Babylon
- */
-function updateEngineVersion(newVersion) {
-    colorConsole.log("Updating version in engine.ts to: " + newVersion.green);
-    let engineContent = fs.readFileSync(enginePath).toString();
-    let replaced = engineContent.replace(/(public static get Version\(\): string {\s*return ")(.*)(";\s*})/g, "$1" + newVersion + "$3");
-    fs.writeFileSync(enginePath, replaced);    
-    colorConsole.emptyLine();
-}
-
-/**
- * Update the root package.json version
- */
-function updateRootPackageVersion(newVersion) {
-    colorConsole.log("Updating version in /package.json to: " + newVersion.green);
-    const packageJSONPath = config.core.computed.packageJSONPath;
-    const packageJson = require(packageJSONPath);
-    packageJson.version = newVersion;
-    fs.writeFileSync(packageJSONPath, JSON.stringify(packageJson, null, 4));
-    colorConsole.emptyLine();
-}
-
-/**
- * Get the version from the engine class for Babylon
- */
-function getEngineVersion() {
-    colorConsole.log("Get version from engine.ts");
-    const engineContent = fs.readFileSync(enginePath).toString();
-
-    const versionRegex = new RegExp(`public static get Version\\(\\): string {[\\s\\S]*return "([\\s\\S]*?)";[\\s\\S]*}`, "gm");
-    const match = versionRegex.exec(engineContent);
-    if (match && match.length) {
-        const version = match[1];
-        colorConsole.log("Version found: " + version.green);
-        colorConsole.emptyLine();
-        return version;
-    }
-
-    colorConsole.error("Version not found in engine.ts");
-    process.exit(1);
-}
-
-/**
- * Publish a package to npm.
- */
-function publish(version, packageName, publishPath, public) {
-    colorConsole.log('    Publishing ' + packageName.blue.bold + " from " + publishPath.cyan);
-
-    let tag = "";
-    // check for alpha or beta
-    if (version.indexOf('alpha') !== -1 || version.indexOf('beta') !== -1) {
-        tag = ' --tag preview';
-    }
-
-    //publish the respected package
-    var cmd = 'npm publish "' + publishPath + '"' + tag;
-    if (public) {
-       cmd += " --access public";
-    }
-
-    if (doNotPublish) {
-        colorConsole.log("    If publishing enabled: " + cmd.yellow);
-    }
-    else {
-        colorConsole.log("    Executing: " + cmd.yellow);
-        shelljs.exec(cmd);
-    }
-
-    colorConsole.success('    Publishing ' + "OK".green);
-}
-
-/**
- * Build the folder with Gulp.
- */
-function buildBabylonJSAndDependencies() {
-    colorConsole.log("Running gulp compilation");
-    let exec = shelljs.exec("gulp typescript-libraries --gulpfile ../Gulp/gulpfile.js");
-    if (exec.code) {
-        colorConsole.error("Error during compilation, aborting");
-        process.exit(1);
-    }
-}
-
-/**
- * Process ES6 Packages.
- */
-function processEs6Packages(version) {
-    config.modules.forEach(moduleName => {
-        let module = config[moduleName];
-        let es6Config = module.build.es6;
-
-        colorConsole.log("Process " + "ES6".magenta + " Package: " + moduleName.blue.bold);
-
-        let distPath = module.computed.distES6Directory;
-        let packagePath = module.computed.packageES6Directory;
-        let legacyPackageJson = require(module.computed.packageJSONPath);
-
-        colorConsole.log("    Cleanup " + packagePath.cyan);
-        rmDir(packagePath);
-
-        colorConsole.log("    Copy Dist folder " + distPath.cyan + " to " + packagePath.cyan);
-        fs.copySync(distPath, packagePath);
-
-        if (module.build.requiredFiles) {
-            module.build.requiredFiles.forEach(file => {
-                let source = path.join(config.computed.rootFolder, file);
-                let destination = path.join(packagePath, path.basename(file));
-                colorConsole.log("    Copy required file: ", source.cyan, destination.cyan);
-                fs.copySync(source, destination);
-            });
-        }
-        if (es6Config.requiredFiles) {
-            es6Config.requiredFiles.forEach(file => {
-                let source = path.join(config.computed.rootFolder, file);
-                let destination = path.join(packagePath, path.basename(file));
-                colorConsole.log("    Copy es6 required file: ", source.cyan, destination.cyan);
-                fs.copySync(source, destination);
-            });
-        }
-
-        legacyPackageJson.name = es6Config.packageName;
-        legacyPackageJson.version = version;
-        legacyPackageJson.main = es6Config.index || "index.js";
-        legacyPackageJson.module = es6Config.index || "index.js";
-        legacyPackageJson.esnext = es6Config.index || "index.js";
-        legacyPackageJson.typings = es6Config.typings || "index.d.ts";
-
-        if (es6Config.pacakagesFiles) {
-            legacyPackageJson.files = es6Config.pacakagesFiles;
-        }
-        else {
-            let files = getFiles(packagePath)
-                .map(f => f.replace(packagePath + "/", ""))
-                .filter(f => f.indexOf("assets/") === -1);
-            legacyPackageJson.files = files;
-        }
-
-        ["dependencies", "peerDependencies", "devDependencies"].forEach(key => {
-            if (legacyPackageJson[key]) {
-                let dependencies = legacyPackageJson[key];
-                legacyPackageJson[key] = {};
-                Object.keys(dependencies).forEach(packageName => {
-                    if (packageName.indexOf("babylonjs") !== -1) {
-                        colorConsole.log("    Checking Internal Dependency: " + packageName.cyan);
-                        let dependencyName = packageName;
-                        for (var moduleName of modules) {
-                            if (config[moduleName] && config[moduleName].build.umd && config[moduleName].build.umd.packageName === packageName) {
-                                if (config[moduleName].build.es6) {
-                                    dependencyName = config[moduleName].build.es6.packageName;
-                                    colorConsole.log("    Replace Dependency: " + packageName.cyan + " by " + dependencyName.cyan);
-                                    break;
-                                }
-                            }
-                        }
-                        legacyPackageJson[key][dependencyName] = version;
-                    } else if (!module.isCore) {
-                        legacyPackageJson[key][packageName] = dependencies[packageName];
-                    }
-                });
-            }
-        });
-
-        // Inject tslib as a dependency
-        var mainPackageJSONPath = path.join(config.computed.rootFolder, "package.json");
-        var mainPackageJSON = fs.readJSONSync(mainPackageJSONPath);
-        var tslibSemver = mainPackageJSON["devDependencies"]["tslib"];
-        colorConsole.log("    Adding tslib version: ", tslibSemver.yellow);
-        legacyPackageJson["dependencies"]["tslib"] = tslibSemver;
-
-        let packageJSONPath = path.join(packagePath, "package.json");
-        fs.writeFileSync(packageJSONPath, JSON.stringify(legacyPackageJson, null, 4));
-
-        publish(version, es6Config.packageName, packagePath, true);
-        colorConsole.emptyLine();
-    });
-}
-
-/**
- * Process Additional Packages.
- */
-function processAdditionalPackages(version) {
-    config.additionalNpmPackages.forEach(package => {
-        colorConsole.log("Process " + "Additional".magenta + " Package: " + package.name.blue.bold);
-
-        let packageJson = require(package.computed.path + '/package.json');
-        packageJson.version = version;
-
-        colorConsole.log("    Update package version to: " + version.green);
-        fs.writeFileSync(path.join(package.computed.path, 'package.json'), JSON.stringify(packageJson, null, 4));
-
-        publish(version, package.name, package.computed.path);
-
-        colorConsole.emptyLine();
-    });
-}
-
-/**
- * Process Legacy Packages.
- */
-function processLegacyPackages(version) {
-    modules.forEach(moduleName => {
-        let module = config[moduleName];
-        colorConsole.log("Process " + "UMD".magenta + " Package: " + moduleName.blue.bold);
-
-        if (moduleName === "viewer") {
-            processLegacyViewer(module, version);
-        }
-        else {
-            let outputDirectory = module.build.legacyPackageOutputDirectory || module.computed.distDirectory;
-
-            if (module.build.requiredFiles) {
-                module.build.requiredFiles.forEach(file => {
-                    let source = path.join(config.computed.rootFolder, file);
-                    let destination = path.join(outputDirectory, path.basename(file));
-                    colorConsole.log("    Copy required file: ", source.cyan, destination.cyan);
-                    fs.copySync(source, destination);
-                });
-            }
-
-            // Package version
-            const packageJSONPath = module.computed ?
-                module.computed.packageJSONPath :
-                outputDirectory + '/package.json';
-            let packageJson = require(packageJSONPath);
-            colorConsole.log("    Update package version to: " + version.green);
-            packageJson.version = version;
-
-            // Package dependencies version
-            if (module.build.umd.dependencies) {
-                packageJson.dependencies = module.build.umd.dependencies;
-            }
-
-            // Package dependencies version
-            if (packageJson.dependencies) {
-                Object.keys(packageJson.dependencies).forEach(key => {
-                    if (key.indexOf("babylonjs") !== -1) {
-                        packageJson.dependencies[key] = version;
-                    }
-                });
-            }
-
-            // Package dev dependencies
-            if (module.build.umd.devDependencies) {
-                packageJson.devDependencies = module.build.umd.devDependencies;
-            }
-
-            // Typings
-            if (module.build.umd.typings) {
-                packageJson.typings = module.build.umd.typings;
-            }
-
-            // Main
-            if (module.build.umd.index) {
-                packageJson.main = module.build.umd.index;
-                packageJson.module = module.build.umd.index;
-                packageJson.esnext = module.build.umd.index;
-            }
-
-            // Files
-            if (module.build.umd.pacakagesFiles) {
-                packageJson.files = module.build.umd.pacakagesFiles;
-            }
-
-            // Write to disk output directory
-            fs.writeFileSync(path.join(outputDirectory, 'package.json'), JSON.stringify(packageJson, null, 4));
-
-            if (!module.build.legacyPackageOutputDirectory) {
-                let packageUMDPath = module.computed.packageUMDDirectory;
-                colorConsole.log("    Cleanup " + packageUMDPath.cyan);
-                rmDir(packageUMDPath);
-
-                if (module.build.umd.pacakagesFiles) {
-                    fs.ensureDirSync(packageUMDPath);
-                    for (let file of module.build.umd.pacakagesFiles.concat(["package.json"])) {
-                        let source = path.join(outputDirectory, file);
-                        let destination = path.join(packageUMDPath, path.basename(file));
-                        colorConsole.log("    Copy Package file: ", source.cyan, destination.cyan);
-                        fs.copyFileSync(source, destination);
-                    }
-                }
-                else {
-                    colorConsole.log("    Copy Package folder " + outputDirectory.cyan + " to " + packageUMDPath.cyan);
-                    fs.copySync(outputDirectory, packageUMDPath);
-                }
-                publish(version, moduleName, packageUMDPath);
-            }
-            else {
-                publish(version, moduleName, outputDirectory);
-            }
-
-            colorConsole.emptyLine();
-        }
-    });
-}
-
-/**
- * Special treatment for legacy viewer.
- */
-function processLegacyViewer(module, version) {
-
-    let projectPath = '../../Viewer';
-    let buildPath = projectPath + "/build/src/";
-
-    if (module.build.requiredFiles) {
-        module.build.requiredFiles.forEach(file => {
-            let source = path.join(config.computed.rootFolder, file);
-            let destination = path.join(buildPath, path.basename(file));
-            colorConsole.log("    Copy required file: ", source.cyan, destination.cyan);
-            fs.copySync(source, destination);
-        });
-    }
-
-    // The viewer needs to be built using tsc on the viewer's main repository
-    // build the viewer.
-    colorConsole.log("    Executing " + ('tsc -p ' + projectPath).yellow);
-
-    let tscCompile = shelljs.exec('tsc -p ' + projectPath);
-    if (tscCompile.code !== 0) {
-        throw new Error("tsc compilation failed");
-    }
-
-    let packageJson = require(buildPath + '/package.json');
-
-    let files = getFiles(buildPath).map(f => f.replace(buildPath + "/", "")).filter(f => f.indexOf("assets/") === -1);
-
-    packageJson.files = files;
-    packageJson.version = version;
-    packageJson.module = "index.js";
-    packageJson.main = "babylon.viewer.js";
-    packageJson.typings = "index.d.ts";
-
-    fs.writeFileSync(buildPath + '/package.json', JSON.stringify(packageJson, null, 4));
-
-    publish(version, "viewer", buildPath);
-    colorConsole.emptyLine();
-}
-
-/**
- * Prepare a UMD Dev folder npm linked for test purpose.
- */
-function prepareUMDDevPackages() {
-    config.modules.forEach(moduleName => {
-        let module = config[moduleName];
-        let umdConfig = module.build.umd;
-
-        colorConsole.log("Prepare " + "UMDDev".magenta + " Package: " + moduleName.blue.bold);
-
-        let packagePath = module.computed.packageUMDDirectory;
-        let packageDevPath = module.computed.packageUMDDevDirectory;
-
-        colorConsole.log("    Cleanup " + packageDevPath.cyan);
-        rmDir(packageDevPath);
-
-        colorConsole.log("    Copy Package folder " + packagePath.cyan + " to " + packageDevPath.cyan);
-        fs.copySync(packagePath, packageDevPath);
-
-        colorConsole.emptyLine();
-    });
-}
-
-/**
- * Prepare an es6 Dev folder npm linked for test purpose.
- */
-function prepareEs6DevPackages() {
-    config.modules.forEach(moduleName => {
-        let module = config[moduleName];
-        let es6Config = module.build.es6;
-
-        colorConsole.log("Prepare " + "ES6Dev".magenta + " Package: " + moduleName.blue.bold);
-
-        let packagePath = module.computed.packageES6Directory;
-        let packageDevPath = module.computed.packageES6DevDirectory;
-
-        colorConsole.log("    Cleanup " + packageDevPath.cyan);
-        rmDir(packageDevPath);
-
-        colorConsole.log("    Copy Package folder " + packagePath.cyan + " to " + packageDevPath.cyan);
-        fs.copySync(packagePath, packageDevPath);
-
-        colorConsole.emptyLine();
-    });
-}
-
-const createVersion = function(version) {
-    // Prevent to build for test Cases.
-    if (!doNotBuild) {
-        buildBabylonJSAndDependencies();
-    }
-
-    // Publish additional packages from the config.
-    processAdditionalPackages(version);
-
-    // Create the packages and publish if needed.
-    processLegacyPackages(version);
-
-    // Prepare es6 Dev Folder.
-    prepareUMDDevPackages();
-
-    // Do not publish es6 yet.
-    doNotPublish = true;
-    processEs6Packages(version);
-
-    // Prepare es6 Dev Folder.
-    prepareEs6DevPackages();
-}
-
-/**
- * Main function driving the publication.
- */
-module.exports = function(noBuild, noPublish, askVersion) {
-    doNotBuild = noBuild;
-    doNotPublish = noPublish;
-
-    if (askVersion) {
-        prompt.start();
-
-        prompt.get(['version'], function (err, result) {
-            const version = result.version;
-            
-            // Update the engine version if needed.
-            if (!version || !version.length) {
-                colorConsole.error("New version required.");
-                Process.exit(1);
-                return;
-            }
-
-            updateEngineVersion(version);
-            updateRootPackageVersion(version);
-            createVersion(version);
-
-            // Invite user to tag with the new version.
-            if (newVersion) {
-                colorConsole.log("Done, please tag git with " + version);
-            }
-        });
-    }
-    else {
-        const version = getEngineVersion();
-        createVersion(version);
-    }
-};

+ 23 - 0
Tools/Publisher/tasks/buildBabylonJSAndDependencies.js

@@ -0,0 +1,23 @@
+// Dependecies.
+const shelljs = require('shelljs');
+const path = require("path");
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+/**
+ * Build the folder with Gulp.
+ */
+function buildBabylonJSAndDependencies() {
+    colorConsole.log("Running gulp compilation");
+    let exec = shelljs.exec("gulp typescript-libraries typescript-es6", {
+        cwd: path.resolve(__dirname, "../../Gulp/")
+    });
+    if (exec.code) {
+        colorConsole.error("Error during compilation, aborting");
+        process.exit(1);
+    }
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = buildBabylonJSAndDependencies;

+ 69 - 0
Tools/Publisher/tasks/main.js

@@ -0,0 +1,69 @@
+// Dependecies.
+const prompt = require('prompt');
+const path = require('path');
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+// Helpers.
+const versionNumberManager = require("./versionNumberManager");
+const buildBabylonJSAndDependencies = require("./buildBabylonJSAndDependencies");
+const processAdditionalPackages = require("./processAdditionalPackages");
+const processLegacyPackages = require("./processLegacyPackages");
+const processEs6Packages = require("./processEs6Packages");
+const prepareUMDDevPackages = require("./prepareUMDDevPackages");
+const prepareEs6DevPackages = require("./prepareEs6DevPackages");
+
+// Path management.
+process.env.PATH += (path.delimiter + path.join(__dirname, '../node_modules', '.bin'));
+
+const createVersion = function(version) {
+    // Publish additional packages from the config.
+    processAdditionalPackages(version);
+
+    // Create the packages and publish if needed.
+    processLegacyPackages(version);
+
+    // Prepare es6 Dev Folder.
+    prepareUMDDevPackages();
+
+    // Do not publish es6 yet.
+    process.env.BABYLONJSREALPUBLISH = false;
+    processEs6Packages(version);
+
+    // Prepare es6 Dev Folder.
+    prepareEs6DevPackages();
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = function(production) {
+    if (production) {
+        prompt.start();
+
+        prompt.get(['version'], function (err, result) {
+            const version = result.version;
+
+            // Update the engine version if needed.
+            if (!version || !version.length) {
+                colorConsole.error("New version required.");
+                Process.exit(1);
+                return;
+            }
+
+            buildBabylonJSAndDependencies();
+            versionNumberManager.updateEngineVersion(version);
+            versionNumberManager.updateRootPackageVersion(version);
+
+            process.env.BABYLONJSREALPUBLISH = true;
+
+            createVersion(version);
+
+            // Invite user to tag with the new version.
+            colorConsole.log("Done, please tag git with " + version);
+        });
+    }
+    else {
+        const version = versionNumberManager.getEngineVersion();
+        createVersion(version);
+    }
+};

+ 35 - 0
Tools/Publisher/tasks/prepareEs6DevPackages.js

@@ -0,0 +1,35 @@
+// Dependecies.
+const fs = require('fs-extra');
+const rmDir = require("../../NodeHelpers/rmDir");
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+// Global Variables.
+const config = require("../../Config/config.js");
+
+/**
+ * Prepare an es6 Dev folder npm linked for test purpose.
+ */
+function prepareEs6DevPackages() {
+    config.modules.forEach(moduleName => {
+        let module = config[moduleName];
+        let es6Config = module.build.es6;
+
+        colorConsole.log("Prepare " + "ES6Dev".magenta + " Package: " + moduleName.blue.bold);
+
+        let packagePath = module.computed.packageES6Directory;
+        let packageDevPath = module.computed.packageES6DevDirectory;
+
+        colorConsole.log("    Cleanup " + packageDevPath.cyan);
+        rmDir(packageDevPath);
+
+        colorConsole.log("    Copy Package folder " + packagePath.cyan + " to " + packageDevPath.cyan);
+        fs.copySync(packagePath, packageDevPath);
+
+        colorConsole.emptyLine();
+    });
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = prepareEs6DevPackages;

+ 35 - 0
Tools/Publisher/tasks/prepareUMDDevPackages.js

@@ -0,0 +1,35 @@
+// Dependecies.
+const fs = require('fs-extra');
+const rmDir = require("../../NodeHelpers/rmDir");
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+// Global Variables.
+const config = require("../../Config/config.js");
+
+/**
+ * Prepare a UMD Dev folder npm linked for test purpose.
+ */
+function prepareUMDDevPackages() {
+    config.modules.forEach(moduleName => {
+        let module = config[moduleName];
+        let umdConfig = module.build.umd;
+
+        colorConsole.log("Prepare " + "UMDDev".magenta + " Package: " + moduleName.blue.bold);
+
+        let packagePath = module.computed.packageUMDDirectory;
+        let packageDevPath = module.computed.packageUMDDevDirectory;
+
+        colorConsole.log("    Cleanup " + packageDevPath.cyan);
+        rmDir(packageDevPath);
+
+        colorConsole.log("    Copy Package folder " + packagePath.cyan + " to " + packageDevPath.cyan);
+        fs.copySync(packagePath, packageDevPath);
+
+        colorConsole.emptyLine();
+    });
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = prepareUMDDevPackages;

+ 34 - 0
Tools/Publisher/tasks/processAdditionalPackages.js

@@ -0,0 +1,34 @@
+// Dependecies.
+const fs = require('fs-extra');
+const path = require('path');
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+// Helpers.
+const publish = require("../helpers/publish");
+
+// Global Variables.
+const config = require("../../Config/config.js");
+
+/**
+ * Process Additional Packages.
+ */
+function processAdditionalPackages(version) {
+    config.additionalNpmPackages.forEach(package => {
+        colorConsole.log("Process " + "Additional".magenta + " Package: " + package.name.blue.bold);
+
+        let packageJson = require(package.computed.path + '/package.json');
+        packageJson.version = version;
+
+        colorConsole.log("    Update package version to: " + version.green);
+        fs.writeFileSync(path.join(package.computed.path, 'package.json'), JSON.stringify(packageJson, null, 4));
+
+        publish(version, package.name, package.computed.path);
+
+        colorConsole.emptyLine();
+    });
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = processAdditionalPackages;

+ 112 - 0
Tools/Publisher/tasks/processEs6Packages.js

@@ -0,0 +1,112 @@
+// Dependecies.
+const fs = require('fs-extra');
+const path = require('path');
+const rmDir = require("../../NodeHelpers/rmDir");
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+// Helpers.
+const publish = require("../helpers/publish");
+const getFiles = require("../helpers/getFiles");
+
+// Global Variables.
+const config = require("../../Config/config.js");
+const modules = config.modules.concat(config.viewerModules);
+
+/**
+ * Process ES6 Packages.
+ */
+function processEs6Packages(version) {
+    config.modules.forEach(moduleName => {
+        let module = config[moduleName];
+        let es6Config = module.build.es6;
+
+        colorConsole.log("Process " + "ES6".magenta + " Package: " + moduleName.blue.bold);
+
+        let distPath = module.computed.distES6Directory;
+        let packagePath = module.computed.packageES6Directory;
+        let legacyPackageJson = require(module.computed.packageJSONPath);
+
+        colorConsole.log("    Cleanup " + packagePath.cyan);
+        rmDir(packagePath);
+
+        colorConsole.log("    Copy Dist folder " + distPath.cyan + " to " + packagePath.cyan);
+        fs.copySync(distPath, packagePath);
+
+        if (module.build.requiredFiles) {
+            module.build.requiredFiles.forEach(file => {
+                let source = path.join(config.computed.rootFolder, file);
+                let destination = path.join(packagePath, path.basename(file));
+                colorConsole.log("    Copy required file: ", source.cyan, destination.cyan);
+                fs.copySync(source, destination);
+            });
+        }
+        if (es6Config.requiredFiles) {
+            es6Config.requiredFiles.forEach(file => {
+                let source = path.join(config.computed.rootFolder, file);
+                let destination = path.join(packagePath, path.basename(file));
+                colorConsole.log("    Copy es6 required file: ", source.cyan, destination.cyan);
+                fs.copySync(source, destination);
+            });
+        }
+
+        legacyPackageJson.name = es6Config.packageName;
+        legacyPackageJson.version = version;
+        legacyPackageJson.main = es6Config.index || "index.js";
+        legacyPackageJson.module = es6Config.index || "index.js";
+        legacyPackageJson.esnext = es6Config.index || "index.js";
+        legacyPackageJson.typings = es6Config.typings || "index.d.ts";
+
+        if (es6Config.pacakagesFiles) {
+            legacyPackageJson.files = es6Config.pacakagesFiles;
+        }
+        else {
+            let files = getFiles(packagePath)
+                .map(f => f.replace(packagePath + "/", ""))
+                .filter(f => f.indexOf("assets/") === -1);
+            legacyPackageJson.files = files;
+        }
+
+        ["dependencies", "peerDependencies", "devDependencies"].forEach(key => {
+            if (legacyPackageJson[key]) {
+                let dependencies = legacyPackageJson[key];
+                legacyPackageJson[key] = {};
+                Object.keys(dependencies).forEach(packageName => {
+                    if (packageName.indexOf("babylonjs") !== -1) {
+                        colorConsole.log("    Checking Internal Dependency: " + packageName.cyan);
+                        let dependencyName = packageName;
+                        for (var moduleName of modules) {
+                            if (config[moduleName] && config[moduleName].build.umd && config[moduleName].build.umd.packageName === packageName) {
+                                if (config[moduleName].build.es6) {
+                                    dependencyName = config[moduleName].build.es6.packageName;
+                                    colorConsole.log("    Replace Dependency: " + packageName.cyan + " by " + dependencyName.cyan);
+                                    break;
+                                }
+                            }
+                        }
+                        legacyPackageJson[key][dependencyName] = version;
+                    } else if (!module.isCore) {
+                        legacyPackageJson[key][packageName] = dependencies[packageName];
+                    }
+                });
+            }
+        });
+
+        // Inject tslib as a dependency
+        var mainPackageJSONPath = path.join(config.computed.rootFolder, "package.json");
+        var mainPackageJSON = fs.readJSONSync(mainPackageJSONPath);
+        var tslibSemver = mainPackageJSON["devDependencies"]["tslib"];
+        colorConsole.log("    Adding tslib version: ", tslibSemver.yellow);
+        legacyPackageJson["dependencies"]["tslib"] = tslibSemver;
+
+        let packageJSONPath = path.join(packagePath, "package.json");
+        fs.writeFileSync(packageJSONPath, JSON.stringify(legacyPackageJson, null, 4));
+
+        publish(version, es6Config.packageName, packagePath, true);
+        colorConsole.emptyLine();
+    });
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = processEs6Packages;

+ 117 - 0
Tools/Publisher/tasks/processLegacyPackages.js

@@ -0,0 +1,117 @@
+// Dependecies.
+const fs = require('fs-extra');
+const path = require('path');
+const rmDir = require("../../NodeHelpers/rmDir");
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+// Helpers.
+const publish = require("../helpers/publish");
+const processLegacyViewer = require("./processLegacyViewer");
+
+// Global Variables.
+const config = require("../../Config/config.js");
+const modules = config.modules.concat(config.viewerModules);
+
+/**
+ * Process Legacy Packages.
+ */
+function processLegacyPackages(version) {
+    modules.forEach(moduleName => {
+        let module = config[moduleName];
+        colorConsole.log("Process " + "UMD".magenta + " Package: " + moduleName.blue.bold);
+
+        if (moduleName === "viewer") {
+            processLegacyViewer(module, version);
+        }
+        else {
+            let outputDirectory = module.build.legacyPackageOutputDirectory || module.computed.distDirectory;
+
+            if (module.build.requiredFiles) {
+                module.build.requiredFiles.forEach(file => {
+                    let source = path.join(config.computed.rootFolder, file);
+                    let destination = path.join(outputDirectory, path.basename(file));
+                    colorConsole.log("    Copy required file: ", source.cyan, destination.cyan);
+                    fs.copySync(source, destination);
+                });
+            }
+
+            // Package version
+            const packageJSONPath = module.computed ?
+                module.computed.packageJSONPath :
+                outputDirectory + '/package.json';
+            let packageJson = require(packageJSONPath);
+            colorConsole.log("    Update package version to: " + version.green);
+            packageJson.version = version;
+
+            // Package dependencies version
+            if (module.build.umd.dependencies) {
+                packageJson.dependencies = module.build.umd.dependencies;
+            }
+
+            // Package dependencies version
+            if (packageJson.dependencies) {
+                Object.keys(packageJson.dependencies).forEach(key => {
+                    if (key.indexOf("babylonjs") !== -1) {
+                        packageJson.dependencies[key] = version;
+                    }
+                });
+            }
+
+            // Package dev dependencies
+            if (module.build.umd.devDependencies) {
+                packageJson.devDependencies = module.build.umd.devDependencies;
+            }
+
+            // Typings
+            if (module.build.umd.typings) {
+                packageJson.typings = module.build.umd.typings;
+            }
+
+            // Main
+            if (module.build.umd.index) {
+                packageJson.main = module.build.umd.index;
+                packageJson.module = module.build.umd.index;
+                packageJson.esnext = module.build.umd.index;
+            }
+
+            // Files
+            if (module.build.umd.pacakagesFiles) {
+                packageJson.files = module.build.umd.pacakagesFiles;
+            }
+
+            // Write to disk output directory
+            fs.writeFileSync(path.join(outputDirectory, 'package.json'), JSON.stringify(packageJson, null, 4));
+
+            if (!module.build.legacyPackageOutputDirectory) {
+                let packageUMDPath = module.computed.packageUMDDirectory;
+                colorConsole.log("    Cleanup " + packageUMDPath.cyan);
+                rmDir(packageUMDPath);
+
+                if (module.build.umd.pacakagesFiles) {
+                    fs.ensureDirSync(packageUMDPath);
+                    for (let file of module.build.umd.pacakagesFiles.concat(["package.json"])) {
+                        let source = path.join(outputDirectory, file);
+                        let destination = path.join(packageUMDPath, path.basename(file));
+                        colorConsole.log("    Copy Package file: ", source.cyan, destination.cyan);
+                        fs.copyFileSync(source, destination);
+                    }
+                }
+                else {
+                    colorConsole.log("    Copy Package folder " + outputDirectory.cyan + " to " + packageUMDPath.cyan);
+                    fs.copySync(outputDirectory, packageUMDPath);
+                }
+                publish(version, moduleName, packageUMDPath);
+            }
+            else {
+                publish(version, moduleName, outputDirectory);
+            }
+
+            colorConsole.emptyLine();
+        }
+    });
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = processLegacyPackages;

+ 61 - 0
Tools/Publisher/tasks/processLegacyViewer.js

@@ -0,0 +1,61 @@
+// Dependecies.
+const shelljs = require('shelljs');
+const fs = require('fs-extra');
+const path = require('path');
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+// Helpers.
+const publish = require("../helpers/publish");
+const getFiles = require("../helpers/getFiles");
+
+// Global Variables.
+const config = require("../../Config/config.js");
+
+/**
+ * Special treatment for legacy viewer.
+ */
+function processLegacyViewer(module, version) {
+
+    let projectPath = '../../../Viewer';
+    let buildPath = projectPath + "/build/src/";
+
+    if (module.build.requiredFiles) {
+        module.build.requiredFiles.forEach(file => {
+            let source = path.join(config.computed.rootFolder, file);
+            let destination = path.join(buildPath, path.basename(file));
+            colorConsole.log("    Copy required file: ", source.cyan, destination.cyan);
+            fs.copySync(source, destination);
+        });
+    }
+
+    // The viewer needs to be built using tsc on the viewer's main repository
+    // build the viewer.
+    colorConsole.log("    Executing " + ('tsc -p ' + projectPath).yellow);
+
+    let tscCompile = shelljs.exec('tsc -p ' + projectPath, {
+        cwd: path.resolve(__dirname)
+    });
+    if (tscCompile.code !== 0) {
+        throw new Error("tsc compilation failed");
+    }
+
+    let packageJson = require(buildPath + 'package.json');
+
+    let files = getFiles(buildPath).map(f => f.replace(buildPath + "/", "")).filter(f => f.indexOf("assets/") === -1);
+
+    packageJson.files = files;
+    packageJson.version = version;
+    packageJson.module = "index.js";
+    packageJson.main = "babylon.viewer.js";
+    packageJson.typings = "index.d.ts";
+
+    fs.writeFileSync(buildPath + '/package.json', JSON.stringify(packageJson, null, 4));
+
+    publish(version, "viewer", buildPath);
+    colorConsole.emptyLine();
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = processLegacyViewer;

+ 60 - 0
Tools/Publisher/tasks/versionNumberManager.js

@@ -0,0 +1,60 @@
+// Dependecies.
+const fs = require('fs-extra');
+const path = require('path');
+const colorConsole = require("../../NodeHelpers/colorConsole");
+
+// Global Variables.
+const config = require("../../Config/config.js");
+const enginePath = path.join(config.core.computed.srcDirectory, "Engines/engine.ts");
+
+/**
+ * Get the version from the engine class for Babylon
+ */
+function getEngineVersion() {
+    colorConsole.log("Get version from engine.ts");
+    const engineContent = fs.readFileSync(enginePath).toString();
+
+    const versionRegex = new RegExp(`public static get Version\\(\\): string {[\\s\\S]*return "([\\s\\S]*?)";[\\s\\S]*}`, "gm");
+    const match = versionRegex.exec(engineContent);
+    if (match && match.length) {
+        const version = match[1];
+        colorConsole.log("Version found: " + version.green);
+        colorConsole.emptyLine();
+        return version;
+    }
+
+    colorConsole.error("Version not found in engine.ts");
+    process.exit(1);
+}
+
+/**
+ * Update the version in the engine class for Babylon
+ */
+function updateEngineVersion(newVersion) {
+    colorConsole.log("Updating version in engine.ts to: " + newVersion.green);
+    let engineContent = fs.readFileSync(enginePath).toString();
+    let replaced = engineContent.replace(/(public static get Version\(\): string {\s*return ")(.*)(";\s*})/g, "$1" + newVersion + "$3");
+    fs.writeFileSync(enginePath, replaced);    
+    colorConsole.emptyLine();
+}
+
+/**
+ * Update the root package.json version
+ */
+function updateRootPackageVersion(newVersion) {
+    colorConsole.log("Updating version in /package.json to: " + newVersion.green);
+    const packageJSONPath = config.core.computed.packageJSONPath;
+    const packageJson = require(packageJSONPath);
+    packageJson.version = newVersion;
+    fs.writeFileSync(packageJSONPath, JSON.stringify(packageJson, null, 4));
+    colorConsole.emptyLine();
+}
+
+/**
+ * Main function driving the publication.
+ */
+module.exports = {
+    getEngineVersion,
+    updateEngineVersion,
+    updateRootPackageVersion
+};

+ 0 - 11
Tools/Publisher/test.js

@@ -1,11 +0,0 @@
-// Dependecies.
-const publisher = require('./publisher');
-
-// CMD Arguments Management.
-const doNotBuild = true;
-const doNotPublish = true;
-
-/**
- * Main function driving the publication.
- */
-publisher(doNotBuild, doNotPublish, false);

+ 43 - 0
dist/preview release/package.json

@@ -0,0 +1,43 @@
+{
+    "author": {
+        "name": "David CATUHE"
+    },
+    "contributors": [
+        "David ROUSSET",
+        "Sebastien VANDENBERGHE",
+        "Raanan Weber"
+    ],
+    "name": "babylonjs",
+    "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
+    "version": "4.0.0-alpha.16",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/BabylonJS/Babylon.js.git"
+    },
+    "main": "babylon.js",
+    "files": [
+        "babylon.d.ts",
+        "babylon.js",
+        "babylon.max.js",
+        "babylon.max.js.map",
+        "Oimo.js",
+        "readme.md"
+    ],
+    "typings": "babylon.d.ts",
+    "keywords": [
+        "3D",
+        "javascript",
+        "html5",
+        "webgl"
+    ],
+    "license": "Apache-2.0",
+    "engines": {
+        "node": "*"
+    },
+    "readme": "Babylon.js is a 3D engine based on webgl and javascript",
+    "readmeFilename": "README.md",
+    "dependencies": [],
+    "devDependencies": [],
+    "module": "babylon.js",
+    "esnext": "babylon.js"
+}

+ 130 - 0
dist/preview release/readme.md

@@ -0,0 +1,130 @@
+# Babylon.js
+
+Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.
+
+[![npm version](https://badge.fury.io/js/babylonjs.svg)](https://badge.fury.io/js/babylonjs)
+[![Build Status](https://travis-ci.com/BabylonJS/Babylon.js.svg?branch=master)](https://travis-ci.com/BabylonJS/Babylon.js)
+[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/BabylonJS/Babylon.js.svg)](http://isitmaintained.com/project/BabylonJS/Babylon.js "Average time to resolve an issue")
+[![Percentage of issues still open](https://isitmaintained.com/badge/open/babylonJS/babylon.js.svg)](https://isitmaintained.com/project/babylonJS/babylon.js "Percentage of issues still open")
+[![Build Size](https://img.badgesize.io/BabylonJS/Babylon.js/master/dist/preview%20release/babylon.js.svg?compression=gzip)](https://img.badgesize.io/BabylonJS/Babylon.js/master/dist/preview%20release/babylon.js.svg?compression=gzip)
+
+**Any questions?** Here is our official [forum](https://forum.babylonjs.com/).
+
+## CDN
+
+- <https://cdn.babylonjs.com/babylon.js>
+- <https://cdn.babylonjs.com/babylon.max.js>
+
+Additional references can be found on <https://cdn.babylonjs.com/xxx> where `xxx` is the folder structure you can find in the /dist folder like <https://cdn.babylonjs.com/gui/babylon.gui.min.js>
+
+For the preview release, use the following URLs:
+
+- <https://preview.babylonjs.com/babylon.js>
+- <https://preview.babylonjs.com/babylon.max.js>
+
+Additional references can be found on <https://preview.babylonjs.com/xxx> where xxx is the folder structure you can find in the /dist/preview release folder like <https://preview.babylonjs.com/gui/babylon.gui.min.js>
+
+## npm
+
+BabylonJS and its modules are published on npm with full typing support. To install, use:
+
+```text
+npm install babylonjs --save
+```
+
+This will allow you to import BabylonJS entirely using:
+
+```javascript
+import * as BABYLON from 'babylonjs';
+```
+
+or individual classes using:
+
+```javascript
+import { Scene, Engine } from 'babylonjs';
+```
+
+If using TypeScript, don't forget to add 'babylonjs' to 'types' in `tsconfig.json`:
+
+```json
+    ...
+    "types": [
+        "babylonjs",
+        "anotherAwesomeDependency"
+    ],
+    ...
+```
+
+To add a module, install the respective package. A list of extra packages and their installation instructions can be found on the [babylonjs user on npm](https://www.npmjs.com/~babylonjs).
+
+## Usage
+
+See [Getting Started](https://doc.babylonjs.com/#getting-started):
+
+```javascript
+// Get the canvas DOM element
+var canvas = document.getElementById('renderCanvas');
+// Load the 3D engine
+var engine = new BABYLON.Engine(canvas, true, {preserveDrawingBuffer: true, stencil: true});
+// CreateScene function that creates and return the scene
+var createScene = function(){
+    // Create a basic BJS Scene object
+    var scene = new BABYLON.Scene(engine);
+    // Create a FreeCamera, and set its position to {x: 0, y: 5, z: -10}
+    var camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 5, -10), scene);
+    // Target the camera to scene origin
+    camera.setTarget(BABYLON.Vector3.Zero());
+    // Attach the camera to the canvas
+    camera.attachControl(canvas, false);
+    // Create a basic light, aiming 0, 1, 0 - meaning, to the sky
+    var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), scene);
+    // Create a built-in "sphere" shape; its constructor takes 6 params: name, segment, diameter, scene, updatable, sideOrientation
+    var sphere = BABYLON.Mesh.CreateSphere('sphere1', 16, 2, scene, false, BABYLON.Mesh.FRONTSIDE);
+    // Move the sphere upward 1/2 of its height
+    sphere.position.y = 1;
+    // Create a built-in "ground" shape; its constructor takes 6 params : name, width, height, subdivision, scene, updatable
+    var ground = BABYLON.Mesh.CreateGround('ground1', 6, 6, 2, scene, false);
+    // Return the created scene
+    return scene;
+}
+// call the createScene function
+var scene = createScene();
+// run the render loop
+engine.runRenderLoop(function(){
+    scene.render();
+});
+// the canvas/window resize event handler
+window.addEventListener('resize', function(){
+    engine.resize();
+});
+```
+
+## Preview release
+
+Preview version of **4.0** can be found [here](https://github.com/BabylonJS/Babylon.js/tree/master/dist/preview%20release).
+If you want to contribute, please read our [contribution guidelines](https://github.com/BabylonJS/Babylon.js/blob/master/contributing.md) first.
+
+## Documentation
+
+- [Documentation](https://doc.babylonjs.com)
+- [Examples](https://doc.babylonjs.com/examples)
+
+## Useful links
+
+- Official web site: [www.babylonjs.com](https://www.babylonjs.com/)
+- Online [playground](https://playground.babylonjs.com/) to learn by experimentating
+- Online [sandbox](https://www.babylonjs.com/sandbox) where you can test your .babylon and glTF scenes with a simple drag'n'drop
+- Online [shader creation tool](https://www.babylonjs.com/cyos/) where you can learn how to create GLSL shaders
+- 3DS Max [exporter](https://github.com/BabylonJS/Exporters/tree/master/3ds%20Max) can be used to generate a .babylon file from 3DS Max
+- Maya [exporter](https://github.com/BabylonJS/Exporters/tree/master/Maya) can be used to generate a .babylon file from 3DS Max
+- Blender [exporter](https://github.com/BabylonJS/Exporters/tree/master/Blender) can be used to generate a .babylon file from Blender 3d
+- Unity 5[ (deprecated) exporter](https://github.com/BabylonJS/Exporters/tree/master/Unity) can be used to export your geometries from Unity 5 scene editor(animations are supported)
+- [glTF Tools](https://github.com/KhronosGroup/glTF#gltf-tools) by KhronosGroup
+
+## Features
+
+To get a complete list of supported features, please visit our [website](https://www.babylonjs.com/#specifications).
+
+## Build
+
+Babylon.js is automatically built using [Gulp](https://gulpjs.com/). For further instructions see the readme at [/Tools/Gulp](https://github.com/BabylonJS/Babylon.js/tree/master/Tools/Gulp).