Travis & Development's CI with surge
Adding Travis CI with custom deploy script for deploying in surge static files. Major changes in code: * Adding dynamic-import-node for fixing Travis tests * Add babel-polyfill * Adding a comment in PR using GitHub REST API with deployed link
This commit is contained in:
parent
01e8e08617
commit
888d6a7614
7
.babelrc
7
.babelrc
|
@ -14,5 +14,12 @@
|
|||
"@babel/plugin-syntax-dynamic-import",
|
||||
"transform-es3-member-expression-literals",
|
||||
"transform-es3-property-literals"
|
||||
],
|
||||
"env": {
|
||||
"test": {
|
||||
"plugins": [
|
||||
"dynamic-import-node"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- "8"
|
||||
os:
|
||||
- linux
|
||||
before_script:
|
||||
- npm install -g truffle
|
||||
- npm install -g surge
|
||||
- git clone https://github.com/gnosis/gnosis-safe-contracts.git
|
||||
- cd gnosis-safe-contracts
|
||||
- truffle compile && cd ..
|
||||
after_success:
|
||||
- npm run build
|
||||
- |
|
||||
if [ ${TRAVIS_BRANCH} = "master" ]; then
|
||||
export NODE_ENV=production;
|
||||
else
|
||||
export NODE_ENV=development;
|
||||
fi
|
||||
- chmod ugo+x ./config/deploy/deploy.sh
|
||||
- ./config/deploy/deploy.sh
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
#!/bin/bash
|
||||
|
||||
echo "Deployment script for gnosis-safe-team"
|
||||
|
||||
# Split on "/", ref: http://stackoverflow.com/a/5257398/689223
|
||||
REPO_SLUG_ARRAY=(${TRAVIS_REPO_SLUG//\// })
|
||||
REPO_OWNER=${REPO_SLUG_ARRAY[0]}
|
||||
REPO_NAME=${REPO_SLUG_ARRAY[1]}
|
||||
|
||||
DEPLOY_PATH=./build_webpack
|
||||
|
||||
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST=()
|
||||
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]
|
||||
then
|
||||
if [ "$NODE_ENV" == "production" ]
|
||||
then
|
||||
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(release-${TRAVIS_PULL_REQUEST}-pr)
|
||||
else
|
||||
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(staging-${TRAVIS_PULL_REQUEST}-pr)
|
||||
fi
|
||||
elif [ -n "${TRAVIS_TAG// }" ] #TAG is not empty
|
||||
then
|
||||
if [ "$NODE_ENV" == "production" ]
|
||||
then
|
||||
|
||||
#sorts the tags and picks the latest
|
||||
#sort -V does not work on the travis machine
|
||||
#sort -V ref: http://stackoverflow.com/a/14273595/689223
|
||||
#sort -t ... ref: http://stackoverflow.com/a/4495368/689223
|
||||
#reverse with sed ref: http://stackoverflow.com/a/744093/689223
|
||||
#git tags | ignore release candidates | sort versions | reverse | pick first line
|
||||
LATEST_TAG=`git tag | grep -v rc | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n | sed '1!G;h;$!d' | sed -n 1p`
|
||||
echo $LATEST_TAG
|
||||
|
||||
if [ "$TRAVIS_TAG" == "$LATEST_TAG" ]
|
||||
then
|
||||
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(latest)
|
||||
fi
|
||||
|
||||
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(${TRAVIS_TAG}-tag)
|
||||
fi
|
||||
else
|
||||
DEPLOY_SUBDOMAIN_UNFORMATTED_LIST+=(${TRAVIS_BRANCH}-branch)
|
||||
fi
|
||||
|
||||
for DEPLOY_SUBDOMAIN_UNFORMATTED in "${DEPLOY_SUBDOMAIN_UNFORMATTED_LIST[@]}"
|
||||
do
|
||||
echo $DEPLOY_SUBDOMAIN_UNFORMATTED
|
||||
|
||||
# replaces non alphanumeric symbols with "-"
|
||||
# sed -r is only supported in linux, ref http://stackoverflow.com/a/2871217/689223
|
||||
# Domain names follow the RFC1123 spec [a-Z] [0-9] [-]
|
||||
# The length is limited to 253 characters
|
||||
# https://en.wikipedia.org/wiki/Domain_Name_System#Domain_name_syntax
|
||||
DEPLOY_SUBDOMAIN=`echo "$DEPLOY_SUBDOMAIN_UNFORMATTED" | sed -r 's/[^A-Za-z0-9]+/\-/g'`
|
||||
echo $DEPLOY_SUBDOMAIN
|
||||
|
||||
DEPLOY_DOMAIN=https://${DEPLOY_SUBDOMAIN}-${REPO_NAME}-${REPO_OWNER}.surge.sh
|
||||
|
||||
surge --project ${DEPLOY_PATH} --domain $DEPLOY_DOMAIN;
|
||||
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ]
|
||||
then
|
||||
# Using the Issues api instead of the PR api
|
||||
# Done so because every PR is an issue, and the issues api allows to post general comments,
|
||||
# while the PR api requires that comments are made to specific files and specific commits
|
||||
GITHUB_PR_COMMENTS=https://api.github.com/repos/${TRAVIS_REPO_SLUG}/issues/${TRAVIS_PULL_REQUEST}/comments
|
||||
curl -H "Authorization: token ${GITHUB_API_TOKEN}" --request POST ${GITHUB_PR_COMMENTS} --data '{"body":"Travis automatic deployment: '${DEPLOY_DOMAIN}'"}'
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Deploy domain: ${DEPLOY_DOMAIN}"
|
|
@ -1,18 +1,18 @@
|
|||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const cssvars = require('postcss-simple-vars');
|
||||
const webpack = require('webpack');
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
||||
const autoprefixer = require('autoprefixer')
|
||||
const cssvars = require('postcss-simple-vars')
|
||||
const webpack = require('webpack')
|
||||
|
||||
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
const ManifestPlugin = require('webpack-manifest-plugin');
|
||||
const url = require('url');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
const ManifestPlugin = require('webpack-manifest-plugin')
|
||||
const url = require('url')
|
||||
|
||||
var paths = require('./paths');
|
||||
var getClientEnvironment = require('./env');
|
||||
const paths = require('./paths')
|
||||
const getClientEnvironment = require('./env')
|
||||
|
||||
var cssvariables = require(paths.appSrc + '/theme/variables');
|
||||
const cssvariables = require(`${paths.appSrc}/theme/variables`)
|
||||
|
||||
const postcssPlugins = [
|
||||
autoprefixer({
|
||||
|
@ -21,25 +21,24 @@ const postcssPlugins = [
|
|||
'last 4 versions',
|
||||
'Firefox ESR',
|
||||
'not ie < 9', // React doesn't support IE8 anyway
|
||||
]
|
||||
],
|
||||
}),
|
||||
cssvars({
|
||||
variables: function () {
|
||||
return Object.assign({}, cssvariables);
|
||||
variables() {
|
||||
return Object.assign({}, cssvariables)
|
||||
},
|
||||
silent: true
|
||||
silent: true,
|
||||
}),
|
||||
];
|
||||
]
|
||||
|
||||
function ensureSlash(path, needsSlash) {
|
||||
var hasSlash = path.endsWith('/');
|
||||
const hasSlash = path.endsWith('/')
|
||||
if (hasSlash && !needsSlash) {
|
||||
return path.substr(path, path.length - 1);
|
||||
return path.substr(path, path.length - 1)
|
||||
} else if (!hasSlash && needsSlash) {
|
||||
return path + '/';
|
||||
} else {
|
||||
return path;
|
||||
return `${path}/`
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// We use "homepage" field to infer "public path" at which the app is served.
|
||||
|
@ -47,22 +46,23 @@ function ensureSlash(path, needsSlash) {
|
|||
// single-page apps that may serve index.html for nested URLs like /todos/42.
|
||||
// We can't use a relative path in HTML because we don't want to load something
|
||||
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
|
||||
var homepagePath = require(paths.appPackageJson).homepage;
|
||||
var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/';
|
||||
const homepagePath = require(paths.appPackageJson).homepage
|
||||
// var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/';
|
||||
const homepagePathname = '/'
|
||||
// Webpack uses `publicPath` to determine where the app is being served from.
|
||||
// It requires a trailing slash, or the file assets will get an incorrect path.
|
||||
var publicPath = ensureSlash(homepagePathname, true);
|
||||
const publicPath = ensureSlash(homepagePathname, true)
|
||||
// `publicUrl` is just like `publicPath`, but we will provide it to our app
|
||||
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
|
||||
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
|
||||
var publicUrl = ensureSlash(homepagePathname, false);
|
||||
const publicUrl = ensureSlash(homepagePathname, false)
|
||||
// Get environment variables to inject into our app.
|
||||
var env = getClientEnvironment(publicUrl);
|
||||
const env = getClientEnvironment(publicUrl)
|
||||
|
||||
// Assert this just to be safe.
|
||||
// Development builds of React are slow and not intended for production.
|
||||
if (env['process.env'].NODE_ENV !== '"production"') {
|
||||
throw new Error('Production builds must have NODE_ENV=production.');
|
||||
throw new Error('Production builds must have NODE_ENV=production.')
|
||||
}
|
||||
|
||||
// This is the production configuration.
|
||||
|
@ -77,17 +77,17 @@ module.exports = {
|
|||
cacheGroups: {
|
||||
vendor: {
|
||||
test: /node_modules/,
|
||||
name: "vendor",
|
||||
chunks: "all",
|
||||
name: 'vendor',
|
||||
chunks: 'all',
|
||||
enforce: true,
|
||||
minSize: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
minSize: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
entry: [
|
||||
require.resolve('./polyfills'),
|
||||
paths.appIndexJs
|
||||
paths.appIndexJs,
|
||||
],
|
||||
output: {
|
||||
// The build folder.
|
||||
|
@ -98,7 +98,7 @@ module.exports = {
|
|||
filename: 'static/js/[name].[chunkhash:8].js',
|
||||
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
|
||||
// We inferred the "public path" (such as / or /my-project) from homepage.
|
||||
publicPath: publicPath
|
||||
publicPath,
|
||||
},
|
||||
resolve: {
|
||||
modules: [
|
||||
|
@ -114,7 +114,7 @@ module.exports = {
|
|||
alias: {
|
||||
'~': paths.appSrc,
|
||||
'#': paths.appContracts,
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
module: {
|
||||
|
@ -123,8 +123,8 @@ module.exports = {
|
|||
test: /\.(js|jsx)$/,
|
||||
include: paths.appSrc,
|
||||
use: {
|
||||
loader: "babel-loader"
|
||||
}
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(scss|css)$/,
|
||||
|
@ -136,20 +136,20 @@ module.exports = {
|
|||
options: {
|
||||
importLoaders: 1,
|
||||
modules: true,
|
||||
minimize: true
|
||||
}
|
||||
minimize: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
plugins: postcssPlugins,
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
}),
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
// Generates an `index.html` file with the <script> injected.
|
||||
|
@ -166,8 +166,8 @@ module.exports = {
|
|||
keepClosingSlash: true,
|
||||
minifyJS: true,
|
||||
minifyCSS: true,
|
||||
minifyURLs: true
|
||||
}
|
||||
minifyURLs: true,
|
||||
},
|
||||
}),
|
||||
// Makes some environment variables available to the JS code, for example:
|
||||
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
|
||||
|
@ -180,7 +180,7 @@ module.exports = {
|
|||
// to their corresponding output file so that tools can pick it up without
|
||||
// having to parse `index.html`.
|
||||
new ManifestPlugin({
|
||||
fileName: 'asset-manifest.json'
|
||||
fileName: 'asset-manifest.json',
|
||||
}),
|
||||
// new BundleAnalyzerPlugin()
|
||||
],
|
||||
|
@ -189,6 +189,6 @@ module.exports = {
|
|||
node: {
|
||||
fs: 'empty',
|
||||
net: 'empty',
|
||||
tls: 'empty'
|
||||
tls: 'empty',
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2310,6 +2310,15 @@
|
|||
"babel-runtime": "6.26.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-dynamic-import-node": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-1.2.0.tgz",
|
||||
"integrity": "sha512-yeDwKaLgGdTpXL7RgGt5r6T4LmnTza/hUn5Ul8uZSGGMtEjYo13Nxai7SQaGCTEzUtg9Zq9qJn0EjEr7SeSlTQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-plugin-syntax-dynamic-import": "6.18.0"
|
||||
}
|
||||
},
|
||||
"babel-plugin-istanbul": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz",
|
||||
|
@ -20792,16 +20801,6 @@
|
|||
"requires": {
|
||||
"has-flag": "3.0.0"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz",
|
||||
"integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async-limiter": "1.0.0",
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
"babel-core": "^7.0.0-bridge.0",
|
||||
"babel-eslint": "^7.2.3",
|
||||
"babel-loader": "^8.0.0-beta.0",
|
||||
"babel-plugin-dynamic-import-node": "^1.2.0",
|
||||
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es3-property-literals": "^6.22.0",
|
||||
"css-loader": "^0.28.10",
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/*eslint-disable*/
|
||||
// Do this as the first thing so that any code reading it knows the right env.
|
||||
process.env.NODE_ENV = 'production';
|
||||
|
||||
|
@ -124,17 +125,12 @@ function build(previousSizeMap) {
|
|||
console.log('Creating an optimized production build...');
|
||||
webpack(config).run((err, stats) => {
|
||||
if (err) {
|
||||
printErrors('Failed to compile.', [err]);
|
||||
printErrors('Failed to compile A.', [err]);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (stats.compilation.errors.length) {
|
||||
printErrors('Failed to compile.', stats.compilation.errors);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (process.env.CI && stats.compilation.warnings.length) {
|
||||
printErrors('Failed to compile.', stats.compilation.warnings);
|
||||
printErrors('Failed to compile B.', stats.compilation.errors);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'babel-polyfill'
|
||||
import { MuiThemeProvider } from 'material-ui/styles'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
|
@ -12,5 +13,5 @@ const Root = () => (
|
|||
|
||||
ReactDOM.render(
|
||||
<Root />,
|
||||
document.getElementById('root')
|
||||
);
|
||||
document.getElementById('root'),
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue