summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--gulpfile.js17
-rw-r--r--package.json46
-rw-r--r--tasks/cdn.js119
-rw-r--r--tasks/common.js87
-rw-r--r--tasks/config.js25
-rw-r--r--tasks/zip.js140
7 files changed, 436 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2c085d1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules
+target
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..4277a46
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,17 @@
+"use strict";
+var gulp = require('gulp');
+require('require-dir')('./tasks');
+
+var version = '0.3.0';
+
+gulp.task('default', function() {
+ console.log('\n Use:\n gulp <stage|deploy[:cdn:zip]>\n');
+});
+
+gulp.task('clean', ['clean:cdn', 'clean:zip']);
+
+gulp.task('deploy', ['deploy:cdn', 'deploy:zip']);
+
+// can't run all the verification concurrently until sauce-connect-launcher supports
+// multiple tunnels
+//gulp.task('verify', ['verify:cdn', 'verify:zip]);
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..b5e0726
--- /dev/null
+++ b/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "vaadin-components",
+ "version": "0.3.0",
+ "description": "A set of high-quality Web Components with a customizable Sass based theme",
+ "author": "Vaadin Ltd",
+ "license": "Apache License 2.0",
+ "dependencies": {
+ "bower": "latest",
+ "fs-extra": "latest",
+ "gulp": "latest",
+ "gulp-git": "latest",
+ "gulp-json-editor": "latest",
+ "gulp-markdown": "^1.0.0",
+ "gulp-rename": "latest",
+ "gulp-replace": "latest",
+ "gulp-util": "latest",
+ "web-component-tester": "3.3.10",
+ "yargs": "latest",
+ "gulp-git": "latest"
+ },
+ "devDependencies": {
+ "chalk": "latest",
+ "gemini": "^0.12.0",
+ "gemini-express": "^0.9.2",
+ "gemini-sauce": "^0.9.1",
+ "gulp-bower": "0.0.10",
+ "gulp-download": "0.0.1",
+ "gulp-insert": "latest",
+ "gulp-rsync": "0.0.5",
+ "gulp-unzip": "^0.1.3",
+ "gulp-zip": "^2.0.3",
+ "lodash": "^3.5.0",
+ "node-ssh-exec": "^0.1.1",
+ "require-dir": "^0.1.0",
+ "scp2": "^0.2.1",
+ "wct-teamcity-reporter": "1.0.1"
+ },
+ "keywords": [
+ "vaadin",
+ "components",
+ "web",
+ "components",
+ "webcomponents",
+ "gwt"
+ ]
+}
diff --git a/tasks/cdn.js b/tasks/cdn.js
new file mode 100644
index 0000000..e5aaeed
--- /dev/null
+++ b/tasks/cdn.js
@@ -0,0 +1,119 @@
+var bower = require('gulp-bower');
+var config = require('./config');
+var common = require('./common');
+var gulp = require('gulp');
+var fs = require('fs-extra');
+var markdown = require('gulp-markdown');
+var replace = require('gulp-replace');
+var rsync = require('gulp-rsync');
+var gutil = require('gulp-util');
+var _ = require('lodash');
+var args = require('yargs').argv;
+var git = require('gulp-git');
+
+var stagingBasePath = config.paths.staging.cdn;
+var version = args.release || args.preRelease || args.autoRevert ? config.version : config.snapshotVersion;
+var stagingPath = stagingBasePath + '/' + version;
+var testPath = process.cwd() + '/' + stagingPath + '/test';
+
+gulp.task('clean:cdn', function() {
+ fs.removeSync(stagingBasePath);
+});
+
+gulp.task('cdn:stage-bower_components', function() {
+ return bower({
+ directory: stagingPath,
+ forceLatest: true,
+ cmd: 'install'
+ });
+});
+
+gulp.task('cdn:stage-vaadin-components', ['clean:cdn'], function() {
+ return gulp.src(['README.md', 'LICENSE.md', 'vaadin-components.html'])
+ .pipe(markdown())
+ .pipe(gulp.dest(stagingPath + "/vaadin-components"));
+});
+
+gulp.task('stage:cdn',
+ ['cdn:stage-bower_components',
+ 'cdn:stage-vaadin-components']);
+
+gulp.task('deploy:cdn', ['stage:cdn'], function() {
+ common.checkArguments(['cdnUsername', 'cdnDestination']);
+ var hostName = args.cdnHostname || 'cdn.vaadin.com';
+
+ gutil.log('Uploading to cdn (rsync): ' + stagingPath + ' -> '+ args.cdnUsername + '@' + hostName + ':' + args.cdnDestination + version);
+
+ return gulp.src(stagingPath)
+ .pipe(rsync({
+ username: args.cdnUsername,
+ hostname: hostName,
+ root: stagingPath,
+ emptyDirectories: false,
+ recursive: true,
+ clean: true,
+ silent: true,
+ destination: args.cdnDestination + version
+ }));
+});
+
+gulp.task('cdn-test:clean', function() {
+ fs.removeSync(stagingPath + '/test');
+});
+
+gulp.task('cdn-test:install-dependencies', function() {
+ return bower({
+ directory: stagingPath,
+ cmd: 'install'
+ }, [['web-component-tester#2.2.6']]);
+});
+
+config.components.forEach(function (n) {
+ gulp.task('cdn-test:stage:' + n, ['cdn-test:clean', 'cdn-test:install-dependencies'], function(done) {
+ fs.mkdirsSync(testPath);
+ return git.clone('https://github.com/vaadin/' + n, {cwd: testPath}, function (err) {
+ gulp.src(testPath + '/' + n + '/test/**')
+ .pipe(replace(/(src|href)=("|')(.*?)\.\.\/\.\.\/(bower_components|node_modules)\/(.*?)\//mg, '$1=$2https://cdn.vaadin.com/vaadin-components/'+ version + '/$5/'))
+ .pipe(replace(/(src|href)=("|')(.*?)\.\.\//mg, '$1=$2https://cdn.vaadin.com/vaadin-components/'+ version +'/' + n + '/'))
+ .pipe(replace(/(src|href)=("|')(.*?)(web-component-tester)\//mg, '$1=$2../../web-component-tester/'))
+ .pipe(gulp.dest(testPath + '/' + n + '/test/'));
+ done();
+ });
+ });
+});
+
+gulp.task('cdn-test:stage', _.map(config.components, function (n) {
+ return 'cdn-test:stage:' + n;
+}));
+
+gulp.task('verify:cdn', ['cdn-test:stage'], function(done) {
+ if(args.autoRevert) {
+ common.checkArguments(['cdnUsername', 'cdnDestination']);
+ }
+
+ // use unique browser combination because bower,cdn,zip verifications are run
+ // at the same time and TeamCity test results will get mixed up if same browsers are used.
+ common.testSauce(
+ ['target/cdn/' + version + '/test/**/index.html'],
+ ['Windows 7/firefox@36'],
+ 'vaadin-components / cdn.vaadin.com / ' + version,
+ function(err) {
+ common.autoRevert(err, function() {
+ gutil.log('Deleting folder ' + args.cdnDestination + version);
+
+ require('node-ssh-exec')({
+ host: 'cdn.vaadin.com',
+ username: args.cdnUsername,
+ privateKey: config.paths.privateKey()
+ }, 'rm -rf ' + args.cdnDestination + version, function (error, response) {
+ if (error) {
+ throw error;
+ }
+
+ gutil.log(response);
+
+ done(err);
+ });
+
+ }, done)});
+});
diff --git a/tasks/common.js b/tasks/common.js
new file mode 100644
index 0000000..d4ba658
--- /dev/null
+++ b/tasks/common.js
@@ -0,0 +1,87 @@
+var args = require('yargs').argv;
+var chalk = require('chalk');
+var wct = require('web-component-tester').test;
+var _ = require('lodash');
+var gutil = require('gulp-util');
+
+function cleanDone(done) {
+ return function(error) {
+ if (error) {
+ // Pretty error for gulp.
+ error = new Error(chalk.red(error.message || error));
+ error.showStack = false;
+ }
+ done(error);
+ };
+}
+
+function checkArguments(arguments) {
+ _.forEach(arguments, function(a) {
+ if(!args.hasOwnProperty(a)) {
+ throw Error('Required argument \'--'+ a +'\' is missing.');
+ }
+ });
+}
+
+function localAddress() {
+ var ip, tun, ifaces = require('os').networkInterfaces();
+ Object.keys(ifaces).forEach(function (ifname) {
+ ifaces[ifname].forEach(function (iface) {
+ if ('IPv4' == iface.family && !iface.internal) {
+ if (!ip) ip = iface.address;
+ if (/tun/.test(ifname)) tun = iface.address;
+ }
+ });
+ });
+ return tun || ip;
+}
+
+function test(options, done) {
+ wct(options, cleanDone(done));
+}
+
+module.exports = {
+ localAddress: localAddress,
+ test: test,
+ checkArguments: checkArguments,
+
+ testSauce: function(suites, browsers, build, done) {
+ test(
+ {
+ suites: suites,
+ browserOptions: {
+ name: localAddress() + ' / ' + new Date(),
+ build: build
+ },
+
+ plugins: {
+ //local: {
+ // browsers: ['chrome']
+ //},
+ sauce: {
+ username: args.sauceUsername,
+ accessKey: args.sauceAccessKey,
+ browsers: browsers
+ },
+ 'teamcity-reporter': args.teamcity
+ },
+ webserver: {
+ hostname: localAddress()
+ }
+ }, done);
+ },
+
+ autoRevert: function(err, handler, done) {
+ if(err) {
+ gutil.log(err.toString());
+ if(args.autoRevert) {
+ handler();
+ } else {
+ gutil.log('No action. Use --auto-revert to revert changes.')
+ done(err);
+ }
+ } else {
+ done();
+ }
+ }
+};
diff --git a/tasks/config.js b/tasks/config.js
new file mode 100644
index 0000000..bfbf19f
--- /dev/null
+++ b/tasks/config.js
@@ -0,0 +1,25 @@
+var args = require('yargs').argv;
+var fs = require('fs');
+
+var userhome = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
+
+module.exports = {
+ components: ['vaadin-grid'],
+ snapshotVersion: '0.3.0-snapshot',
+ version: args.version || '0.3.0-snapshot',
+ paths: {
+ staging: {
+ bower: 'target/bower',
+ cdn: 'target/cdn',
+ zip: 'target/zip'
+ },
+ userhome: userhome,
+ privateKey: function() {
+ try {
+ return fs.readFileSync(userhome + '/.ssh/id_rsa');
+ } catch(error) {
+ return fs.readFileSync(userhome + '/.ssh/id_dsa');
+ }
+ }
+ }
+};
diff --git a/tasks/zip.js b/tasks/zip.js
new file mode 100644
index 0000000..fc0f854
--- /dev/null
+++ b/tasks/zip.js
@@ -0,0 +1,140 @@
+var _ = require('lodash');
+var args = require('yargs').argv;
+var bower = require('gulp-bower');
+var common = require('./common');
+var config = require('./config');
+var download = require('gulp-download');
+var fs = require('fs-extra');
+var gulp = require('gulp');
+var gutil = require('gulp-util');
+var replace = require('gulp-replace');
+var unzip = require('gulp-unzip');
+var zip = require('gulp-zip');
+
+var stagingPath = config.paths.staging.zip;
+var version = args.release || args.preRelease ? config.version : config.snapshotVersion;
+var filename = 'vaadin-components-' + version + '.zip';
+var majorMinorVersion = version.replace(/(\d+\.\d+)(\.|-)(.*)/, '$1');
+
+
+gulp.task('clean:zip', function() {
+ fs.removeSync(stagingPath);
+});
+
+gulp.task('stage:zip', ['clean:zip', 'stage:cdn'], function() {
+ return gulp.src(config.paths.staging.cdn + '/' + version + '/**/*')
+ .pipe(zip(filename))
+ .pipe(gulp.dest(stagingPath));
+});
+
+gulp.task('zip:upload', ['stage:zip'], function(done) {
+ common.checkArguments(['zipUsername', 'zipDestination']);
+ var hostName = args.zipHostname || 'vaadin.com';
+ var path = args.zipDestination + majorMinorVersion + '/' + version + '/' + filename;
+
+ gutil.log('Uploading zip package (scp): ' + stagingPath + '/' + filename + ' -> ' + args.zipUsername + '@' + hostName + ':' + path);
+
+ require('scp2').scp(stagingPath + '/' + filename, {
+ host: hostName,
+ username: args.zipUsername,
+ privateKey: config.paths.privateKey(),
+ path: path
+ }, function(err) {
+ done(err);
+ })
+});
+
+function ssh(command, done) {
+ var hostName = args.sshHostname || 'vaadin.com';
+ gutil.log('SSH: ' + hostName + ' -> ' + command);
+
+ require('node-ssh-exec')({
+ host: hostName,
+ username: args.zipUsername,
+ privateKey: config.paths.privateKey()
+ }, command,
+ function (err) {
+ done(err);
+ });
+}
+
+gulp.task('zip:update-references', ['zip:upload'], function(done) {
+ common.checkArguments(['zipUsername', 'zipDestination']);
+
+ if(args.release) {
+ ssh("sed -i '1i components/" + majorMinorVersion + '/' + version + "' " + args.zipDestination + 'VERSIONS', done);
+ } else if(args.preRelease) {
+ ssh("sed -i '1i components/" + majorMinorVersion + '/' + version + "' " + args.zipDestination + 'PRERELEASES', done);
+ } else {
+ ssh('echo components/' + majorMinorVersion + '/' + version + ' > ' + args.zipDestination + 'SNAPSHOT', done);
+ }
+});
+
+gulp.task('deploy:zip', ['zip:upload', 'zip:update-references']);
+
+gulp.task('zip-test:clean', function() {
+ fs.removeSync(stagingPath + '/test');
+});
+
+gulp.task('zip-test:download', ['zip-test:clean'], function() {
+ var url = args.zipUrl || 'https://vaadin.com/download/components';
+ return download(url + '/' + majorMinorVersion +'/' + version + '/' + filename)
+ .pipe(gulp.dest(stagingPath + '/test'));
+});
+
+gulp.task('zip-test:unzip', ['zip-test:download'], function() {
+ return gulp.src(stagingPath + '/test/' + filename)
+ .pipe(unzip())
+ .pipe(gulp.dest(stagingPath + '/test'));
+});
+
+gulp.task('zip-test:install-wct', ['zip-test:download'], function() {
+ return bower({
+ cwd: stagingPath + '/test',
+ directory: '.',
+ cmd: 'install'
+ }, [['web-component-tester#2.2.6']]);
+});
+
+// TODO: Haven't been fixed for the new project structure. Once the tests are in use,
+// apply similar changes as in cdn.js
+config.components.forEach(function (n) {
+ gulp.task('zip-test:stage:' + n, ['zip-test:download'], function() {
+ return gulp.src('vaadin-components/' + n + '/test/**/*')
+ .pipe(replace(/(src|href)=("|')(.*?)\.\.\/\.\.\/\.\.\/\.\.\/(bower_components|node_modules)\//mg, '$1=$2../../$3'))
+ .pipe(replace(/(src|href)=("|')(.*?)\.\.\/\.\.\/\.\.\/(bower_components|node_modules)\//mg, '$1=$2../../$3'))
+ .pipe(replace(/(src|href)=("|')(.*?)\.\.\/(vaadin-)/mg, '$1=$2../../' + n + '/$3$4'))
+ .pipe(gulp.dest(stagingPath + '/test/test/' + n + '/'));
+ });
+});
+
+gulp.task('zip-test:stage', _.map(config.components, function(n) {
+ return 'zip-test:stage:'+n;
+}));
+
+gulp.task('verify:zip', ['zip-test:unzip', 'zip-test:install-wct', 'zip-test:stage'], function(done) {
+ if(args.autoRevert) {
+ common.checkArguments(['zipUsername', 'zipDestination']);
+ }
+
+ common.testSauce(
+ ['target/zip/test/test/**/index.html'],
+ ['Windows 7/internet explorer@11'],
+ 'vaadin-components / vaadin.com / ' + version,
+ function(err) {
+ common.autoRevert(err, function() {
+ var path = args.zipDestination + majorMinorVersion + '/' + version;
+
+ gutil.log('Deleting package ' + path);
+
+ // remove the version from VERSIONS
+ ssh('grep -v "components/' + majorMinorVersion + '/' + version + '" ' +
+ args.zipDestination + 'VERSIONS > temp && mv temp ' + args.zipDestination + 'VERSIONS', function(error) {
+ if(error) done(error);
+
+ // remove the package
+ ssh('rm -rf ' + path, done);
+ });
+ }, done);
+ });
+});