Загрузка данных
workflow:
rules:
- if: $CI_COMMIT_TAG
- if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
include:
- project: 'moex-admins/moex-dop/moex-dop-cicd'
ref: 'itt_template'
file: '/teams/itt/mr_approval.yml'
- project: 'moex-admins/moex-dop/moex-dop-cicd'
ref: 'itt_template'
file: '/teams/itt/sonar-nodejs.yml'
rules:
- if: $CI_PIPELINE_SOURCE == "pipeline"
when: never
- if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^bugfix\/.*$/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^release\/.*$/
- if: $CI_COMMIT_REF_NAME =~ /^release\/.*$/ && $CI_COMMIT_BEFORE_SHA == "0000000000000000000000000000000000000000"
stages:
- build
- test
- sast
- publish
variables:
PACKAGE_NAME: moex-chart
SONARQUBE_PROJECT_KEY: info-trade-terminal_${CI_PROJECT_NAME}
SONARQUBE_PROJECT_NAME: ${CI_PROJECT_NAME}
SONARQUBE_COVERAGE_REPORT_USE: 'true'
TEST_ENABLED: 'true'
SONARQUBE_ENABLED: 'true'
SONARSCANNER_IMAGE: moex-docker-static-hosted-nexus-dev.tech.moex.com/sonarsource/sonar-scanner-cli:5.0
build:
stage: build
image: moex-docker-static-hosted-nexus-dev.tech.moex.com/node:22.11.0-bookworm-jq
script:
- |
npm config set loglevel verbose
npm config set ignore-scripts true
rm -f package-lock.json
VERSION=${CI_COMMIT_TAG:-"0.0.0"}
npm version $VERSION --no-git-tag-version || true
npm install
npm run build:lib:js
npm run build:lib:types
npm pack
mkdir -p pack-result
mv $PACKAGE_NAME-*.tgz pack-result
artifacts:
paths:
- pack-result/
rules:
- if: $CI_COMMIT_TAG
- if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
test:
stage: test
image: moex-docker-static-hosted-nexus-dev.tech.moex.com/node:22.11.0-bookworm-jq
script:
- |
npm config set loglevel verbose
npm config set ignore-scripts true
npm install
npm run coverage
test -f coverage/lcov.info
artifacts:
paths:
- coverage/lcov.info
expire_in: 1 day
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
publish:
stage: publish
image: moex-docker-static-hosted-nexus-dev.tech.moex.com/node:22.11.0-bookworm-jq
variables:
GIT_STRATEGY: none
dependencies:
- build
script:
- |
cd pack-result
TGZ_FILE=$(ls -t ${PACKAGE_NAME}-*.tgz 2>/dev/null | head -n 1)
curl -v \
-H "Authorization: Basic ${DOP_NPM_NEXUS_TOKEN}" \
-X POST \
"https://nexus-dev.tech.moex.com/service/rest/v1/components?repository=trade-radar-npm-private-hosted" \
-F "npm.asset=@./${TGZ_FILE};type=application/octet-stream" \
--fail
rules:
- if: $CI_COMMIT_TAG
when: manual
/* eslint-disable @typescript-eslint/no-var-requires, import/no-extraneous-dependencies */
const path = require('path');
const autoprefixer = require('autoprefixer');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const removeBeforeAfterBoxSizing = require('./.build/postcss-remove- before-after-box-sizing.cjs');
const base = {
entry: './src/index.ts',
resolve: {
extensions: ['.tsx', '.ts', '.jsx', '.js'],
alias: {
'@src': path.resolve(__dirname, 'src'),
'@core': path.resolve(__dirname, 'src/core'),
'@components': path.resolve(__dirname, 'src/components'),
'@lib': path.resolve(__dirname, 'moex-chart', 'src'),
},
},
module: {
rules: [
// Транспиляция TS/JSX через Babel
{
test: /\.[jt]sx?$/,
use: [{ loader: 'babel-loader' }],
exclude: /node_modules/,
},
// CSS
{
test: /\.css$/,
exclude: /\.module\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: { plugins: [removeBeforeAfterBoxSizing(), autoprefixer] },
},
},
],
},
{
test: /\.scss$/,
exclude: /\.module\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: false,
importLoaders: 2,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [autoprefixer],
},
},
},
{
loader: 'sass-loader',
},
],
},
{
test: /\.module\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: { localIdentName: '[name]__[local]__[hash:base64:5]' },
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: { plugins: [removeBeforeAfterBoxSizing(), autoprefixer] },
},
},
],
},
{
test: /\.module\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]',
},
importLoaders: 2,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: { plugins: [removeBeforeAfterBoxSizing(), autoprefixer] },
},
},
{
loader: 'sass-loader',
},
],
},
],
},
plugins: [new MiniCssExtractPlugin({ filename: 'styles.css' })],
optimization: {
minimize: true,
minimizer: ['...', new CssMinimizerPlugin()],
usedExports: true,
concatenateModules: true,
},
};
const esm = {
...base,
name: 'esm',
mode: 'production',
output: {
path: path.resolve(process.cwd(), 'dist'),
filename: 'index.js',
library: { type: 'module' },
chunkFormat: 'module',
},
experiments: { outputModule: true },
};
const cjs = {
...base,
name: 'cjs',
mode: 'production',
output: {
path: path.resolve(process.cwd(), 'dist'),
filename: 'index.cjs',
library: { type: 'commonjs2' },
},
};
module.exports = [esm, cjs];
/* eslint-disable @typescript-eslint/no-var-requires, import/no-extraneous-dependencies */
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-controls',
'@storybook/addon-docs',
],
framework: {
name: '@storybook/react-webpack5',
options: {},
},
core: {
builder: '@storybook/builder-webpack5',
disableTelemetry: true,
},
webpackFinal: async (config) => {
config.resolve.extensions = [...(config.resolve.extensions || []), '.js', '.cjs', '.ts', '.tsx'];
config.resolve.alias = {
...config.resolve.alias,
'@src': path.resolve(__dirname, '../src'),
'@core': path.resolve(__dirname, '../src/core'),
'@components': path.resolve(__dirname, '../src/components'),
'@lib': process.env.buildType === 'local' ? path.resolve(process.cwd(), 'src') : 'moex-chart',
};
return {
...config,
module: {
...config.module,
rules: [
...config.module.rules,
{
test: /\.tsx?$/,
use: {
loader: 'ts-loader',
options: {
configFile: path.resolve(__dirname, '../tsconfig.json'),
transpileOnly: true,
},
},
exclude: /node_modules/,
},
{
test: /\.module\.s?css$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.scss$/,
exclude: /\.module\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
],
},
plugins: [...config.plugins],
};
},
};