FE-598: Initial config (#1)

This commit is contained in:
Alexandra Usacheva 2018-04-20 18:26:12 +03:00 committed by GitHub
parent 17b139bc7e
commit de2f99ae56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 12634 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.idea
/node_modules/
/dist/
Dockerfile
.DS_Store
/.cache-loader/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "build_utils"]
path = build_utils
url = git+ssh://git@github.com/rbkmoney/build_utils

25
Dockerfile.sh Executable file
View File

@ -0,0 +1,25 @@
#!/bin/bash
cat <<EOF
FROM $BASE_IMAGE
MAINTAINER Ildar Galeev <i.galeev@rbkmoney.com>
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/vhosts.d/wallet.conf
COPY containerpilot.json /etc/containerpilot.json
CMD /bin/containerpilot -config file:///etc/containerpilot.json /usr/sbin/nginx -g "daemon off;"
EXPOSE 8080
LABEL base_image_tag=$BASE_IMAGE_TAG
LABEL build_image_tag=$BUILD_IMAGE_TAG
# A bit of magic to get a proper branch name
# even when the HEAD is detached (Hey Jenkins!
# BRANCH_NAME is available in Jenkins env).
LABEL branch=$( \
if [ "HEAD" != $(git rev-parse --abbrev-ref HEAD) ]; then \
echo $(git rev-parse --abbrev-ref HEAD); \
elif [ -n "$BRANCH_NAME" ]; then \
echo $BRANCH_NAME; \
else \
echo $(git name-rev --name-only HEAD); \
fi)
LABEL commit=$(git rev-parse HEAD)
LABEL commit_number=$(git rev-list --count HEAD)
EOF

41
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,41 @@
#!groovy
build('wallet-utils', 'docker-host') {
checkoutRepo()
loadBuildUtils()
def pipeDefault
def withWsCache
runStage('load pipeline') {
env.JENKINS_LIB = "build_utils/jenkins_lib"
pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy")
withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy")
}
pipeDefault() {
runStage('init') {
withGithubSshCredentials {
sh 'make wc_init'
}
}
runStage('build') {
sh 'make wc_build'
}
runStage('build image') {
sh 'make build_image'
}
try {
if (env.BRANCH_NAME == 'master') {
runStage('push image') {
sh 'make push_image'
}
}
} finally {
runStage('rm local image') {
sh 'make rm_local_image'
}
}
}
}

42
Makefile Normal file
View File

@ -0,0 +1,42 @@
SUBMODULES = build_utils
SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES))
UTILS_PATH := build_utils
TEMPLATES_PATH := .
# Name of the service
SERVICE_NAME := wallet
# Service image default tag
SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD)
# The tag for service image to be pushed with
SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG)
# Base image for the service
BASE_IMAGE_NAME := service-fe
BASE_IMAGE_TAG := 768cf0f40600e290060502e047dd2e86d4fd6020
BUILD_IMAGE_TAG := 55e987e74e9457191a5b4a7c5dc9e3838ae82d2b
CALL_W_CONTAINER := init test build clean submodules
.PHONY: $(CALL_W_CONTAINER)
all: build
-include $(UTILS_PATH)/make_lib/utils_image.mk
-include $(UTILS_PATH)/make_lib/utils_container.mk
$(SUBTARGETS): %/.git: %
git submodule update --init $<
touch $@
submodules: $(SUBTARGETS)
init:
npm install
build:
npm run build
clean:
rm -rf dist

1
build_utils Submodule

@ -0,0 +1 @@
Subproject commit f7fe66c9f3d4f37566a04c521b28aa168b7a88ec

45
config/app-config.js Normal file
View File

@ -0,0 +1,45 @@
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const rules = require('./common-rules');
module.exports = {
name: 'app',
stats: {
children: false,
moduleTrace: false,
modules: false
},
entry: {
app: './src/app/index.tsx',
react: ['react', 'react-dom'],
// vendor: [],
// polyfills: []
},
resolve: {
modules: ['node_modules', path.join(__dirname, 'src/app')],
extensions: ['.ts', '.tsx', '.js'],
alias: {
app: __dirname + '/../src/app'
}
},
module: {
rules
},
optimization: {
splitChunks: {
chunks: "all"
}
},
plugins: [
new ForkTsCheckerWebpackPlugin({
checkSyntacticErrors: true,
formatter: 'codeframe',
tslint: true
}),
new HtmlWebpackPlugin({
template: './src/app/index.html',
filename: 'app.html'
})
]
};

54
config/common-rules.js Normal file
View File

@ -0,0 +1,54 @@
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const rules = [
{
test: /\.(ts|tsx)$/,
use: [
{
loader: 'thread-loader',
options: {
workers: require('os').cpus().length - 1
}
},
'cache-loader',
{
loader: 'ts-loader',
options: {
transpileOnly: true,
happyPackMode: true
}
}],
exclude: '/node_modules/'
},
{
test: /\.(css|scss)$/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
minimize: true,
modules: true,
namedExport: true,
localIdentName: '[local]__[hash:5]'
}
},
'sass-loader'
],
fallback: 'style-loader'
})
},
{
test: /\.(woff|woff2)$/,
use: [{
loader: 'file-loader',
options: {
name: '[hash:8].[ext]',
mimetype: 'mimetype=application/font-woff',
outputPath: './fonts/'
}
}]
}
];
module.exports = rules;

10
config/helpers.js Normal file
View File

@ -0,0 +1,10 @@
const path = require('path');
const _root = path.resolve(__dirname, '..');
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [_root].concat(args));
}
exports.root = root;

View File

@ -0,0 +1,29 @@
const path = require('path');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const rules = require('./common-rules');
module.exports = {
name: 'initializer',
stats: {
children: false,
moduleTrace: false,
modules: false
},
entry: {
'wallet-utils': './src/initializer/index.ts'
},
resolve: {
modules: ['node_modules', path.join(__dirname, 'src/initializer')],
extensions: ['.ts', '.js']
},
module: {
rules
},
plugins: [
new ForkTsCheckerWebpackPlugin({
checkSyntacticErrors: true,
formatter: 'codeframe',
tslint: true
})
]
};

View File

@ -0,0 +1,15 @@
const helpers = require('./helpers');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const prepareOutputConfig = (outputPath, jsFilenamePattern = '[name]', cssFilenamePattern = '[name]') => ({
output: {
filename: `${jsFilenamePattern}.js`,
path: helpers.root(outputPath),
publicPath: './'
},
plugins: [
new ExtractTextPlugin({filename: `${cssFilenamePattern}.css`})
]
});
module.exports = prepareOutputConfig;

32
config/webpack.dev.js Normal file
View File

@ -0,0 +1,32 @@
const path = require('path');
const WriteFilePlugin = require('write-file-webpack-plugin');
const merge = require('webpack-merge');
const appConfig = require('./app-config');
const initializerConfig = require('./initializer-config');
const prepareOutputConfig = require('./prepare-output-config');
const commonDevConfig = {
devtool: 'source-map',
mode: 'development',
plugins: [
new WriteFilePlugin({
log: false
})
],
devServer: {
contentBase: path.join(__dirname, '../dist'),
compress: true,
disableHostCheck: false,
stats: 'minimal'
}
};
const baseOutput = 'dist';
const prepareModule = (baseConfig, outputPath) =>
merge(merge(baseConfig, prepareOutputConfig(outputPath)), commonDevConfig);
module.exports = [
prepareModule(appConfig, `${baseOutput}/v1`),
prepareModule(initializerConfig, baseOutput)
];

26
config/webpack.prod.js Normal file
View File

@ -0,0 +1,26 @@
const webpack = require('webpack');
const merge = require('webpack-merge');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const appConfig = require('./app-config');
const initializerConfig = require('./initializer-config');
const prepareOutputConfig = require('./prepare-output-config');
const commonProdConfig = {
mode: 'production',
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),
new BundleAnalyzerPlugin({
analyzerMode: 'disabled'
})
]
};
const baseOutput = 'dist';
const prepareModule = (baseConfig, outputPath, jsPattern, cssPattern) =>
merge(merge(baseConfig, prepareOutputConfig(outputPath, jsPattern, cssPattern)), commonProdConfig);
module.exports = [
prepareModule(appConfig, `${baseOutput}/v1`, '[name].[hash:20]', '[hash:20]'),
prepareModule(initializerConfig, baseOutput)
];

13
containerpilot.json Normal file
View File

@ -0,0 +1,13 @@
{
"consul": "{{ .CONSUL_ADDR }}",
"services": [
{
"name": "{{ .SERVICE_NAME }}",
"port": 8080,
"health": "/usr/bin/curl --silent --show-error --output /dev/null localhost:8080",
"poll": 1,
"ttl": 2,
"interfaces": ["inet6", "inet"]
}
]
}

15
nginx.conf Normal file
View File

@ -0,0 +1,15 @@
server {
listen 8080;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

12098
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

55
package.json Normal file
View File

@ -0,0 +1,55 @@
{
"name": "wallet-utils",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"clear": "rimraf dist && rimraf .cache-loader",
"build": "npm run clear && webpack --colors --progress --config config/webpack.prod.js",
"start": "npm run clear && webpack-dev-server --colors --progress --config config/webpack.dev.js --port 7080 --host ::"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rbkmoney/wallet-utils.git"
},
"author": "rbkmoney",
"license": "",
"bugs": {
"url": "https://github.com/rbkmoney/wallet-utils/issues"
},
"homepage": "https://github.com/rbkmoney/wallet-utils#readme",
"devDependencies": {
"@types/react": "~16.3.11",
"@types/react-dom": "~16.0.5",
"cache-loader": "~1.2.2",
"copy-webpack-plugin": "~4.5.1",
"css-loader": "~0.28.11",
"extract-text-webpack-plugin": "~4.0.0-alpha.0",
"file-loader": "~1.1.11",
"fork-ts-checker-webpack-plugin": "~0.4.1",
"html-webpack-plugin": "~3.2.0",
"node-sass": "~4.8.3",
"rimraf": "~2.6.2",
"sass-loader": "~7.0.1",
"style-loader": "~0.21.0",
"thread-loader": "~1.1.5",
"ts-loader": "~4.2.0",
"tslint": "~5.9.1",
"tslint-immutable": "~4.5.4",
"tslint-loader": "~3.6.0",
"tslint-react": "~3.5.1",
"typescript": "~2.8.1",
"webpack": "~4.6.0",
"webpack-bundle-analyzer": "~2.10.0",
"webpack-cli": "~2.0.14",
"webpack-dev-server": "~3.1.3",
"webpack-merge": "~4.1.0",
"write-file-webpack-plugin": "~4.2.0"
},
"dependencies": {
"react": "~16.3.2",
"react-dom": "~16.3.2",
"redux-form": "~7.3.0",
"redux-saga": "~0.16.0"
}
}

12
src/app/index.html Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="user-scalable=no,width=device-width,initial-scale=1,maximum-scale=1">
<title>Wallet Utils</title>
</head>
<body>
<div id="app"></div>
</body>
</html>

13
src/app/index.tsx Normal file
View File

@ -0,0 +1,13 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import './styles/main.scss';
const app = document.getElementById('app');
/* tslint:disable:no-expression-statement */
ReactDOM.render(
<div>start</div>,
app
);
/* tslint:enable:no-expression-statement */

29
src/app/styles/main.scss Normal file
View File

@ -0,0 +1,29 @@
@import './responsive.scss';
:global {
body,
html,
#app {
margin: 0;
position: relative;
height: auto;
min-height: 100%;
width: 100%;
min-width: 320px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
&._loading {
height: 100%;
}
@include responsive(sm) {
height: 100%;
min-width: 680px;
}
@media (min-height: 701px) and (min-width: 768px) {
overflow-y: hidden;
}
}
}

0
src/app/styles/main.scss.d.ts vendored Normal file
View File

View File

@ -0,0 +1,19 @@
@mixin responsive($media) {
@if $media == sm {
@media (min-width: 768px) {
@content;
}
} @else if $media == md {
@media (min-width: 992px) {
@content;
}
} @else if $media == lg {
@media (min-width: 1200px) {
@content;
}
} @else if $media == xlg {
@media (min-width: 1700px) {
@content;
}
}
}

0
src/initializer/index.ts Normal file
View File

20
tsconfig.json Normal file
View File

@ -0,0 +1,20 @@
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"moduleResolution": "node",
"module": "es2015",
"target": "es5",
"jsx": "react",
"lib": ["es2015", "dom"],
"baseUrl": ".",
"paths": {
"app/*": ["./src/app/*"]
},
"pretty": true
},
"include": [
"./src/**/*"
]
}

31
tslint.json Normal file
View File

@ -0,0 +1,31 @@
{
"extends": ["tslint:recommended", "tslint-react", "tslint-immutable"],
"rules": {
"quotemark": [true, "single"],
"member-access": [true, "no-public"],
"trailing-comma": false,
"ordered-imports": false,
"no-console": [true, "log"],
"max-line-length": false,
"object-literal-sort-keys": false,
"interface-name": false,
"no-namespace": false,
"no-var-keyword": true,
"no-parameter-reassignment": true,
"typedef": [true, "call-signature"],
"readonly-keyword": true,
"readonly-array": true,
"no-let": true,
"no-object-mutation": true,
"no-delete": true,
"no-method-signature": true,
"no-this": true,
"no-class": true,
"no-mixed-interface": true,
"no-expression-statement": true,
"no-if-statement": true
}
}