рд╕рднреА рдПрдХ рдмрд╛рд░ рдореЗрдВ: рдмрдВрдбрд▓ рдЖрдХрд╛рд░ рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдЬрд╛рдВрдЪ

рд╕рднреА рдХреЛ рдореЗрд░рд╛ рдирдорд╕реНрдХрд╛рд░, рдореЗрд░рд╛ рдирд╛рдо рдЗрд▓рд┐рдпрд╛ рд╣реИред рдореИрдВ рд▓рдЧрднрдЧ 6 рд╡рд░реНрд╖реЛрдВ рд╕реЗ рдЖрдИрдЯреА рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдкрд┐рдЫрд▓реЗ 2 рд╡рд░реНрд╖реЛрдВ рд╕реЗ - Yandex.Money рдХрдВрдкрдиреА рдореЗрдВ рдлреНрд░рдВрдЯ-рдПрдВрдб рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВред рдЬрд┐рдореНрдореЗрджрд╛рд░рд┐рдпреЛрдВ рдореЗрдВ "рдореЗрд░рд╛ рдЦрд╛рддрд╛" рдкреНрд░реЛрдЬреЗрдХреНрдЯ (рдФрд░ рдирд╣реАрдВ, рдпрд╣ рдХреЗрд╡рд▓ "рдЧрд▓рдд рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдХреЛ рд╕рд╣реА рдХрд░рдирд╛", "рдмрдЯрди рдХрд╛ рд░рдВрдЧ рдмрджрд▓рдирд╛", рдпрд╛ "рдЬрд▓реНрджреА рд╕реЗ рдЖрдХрд╛рд░ рдХреЛ рд╕реНрд╡реИрдк рдХрд░рдирд╛") рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рдХреБрдЫ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдмрдирд╛рдП рд░рдЦрдирд╛ / рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред


рд╡рд┐рдХрд╛рд╕ рд╡рд┐рднрд╛рдЧ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЖрдВрддрд░рд┐рдХ рдЪреБрдиреМрддреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИ - рд╣рдо рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрд╣рддреЗ рд╣реИрдВ рдЬреЛ рд╕реАрдзреЗ рдореБрдЦреНрдп рдЙрддреНрдкрд╛рджреЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИрдВред рдпреЗ рдРрд╕реЗ рдХрд╛рд░реНрдп рд╣реИрдВ рдЬреЛ рд╕рд╛рдорд╛рдЬрд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧреА рд╣реЛрдВрдЧреЗ рдФрд░ рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ, рд╕реАрдЖрдИ / рд╕реАрдбреА, рдФрд░ рдЕрдзрд┐рдХ рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд░рд┐рд▓реАрдЬрд╝ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрд┐рдд рдмреЙрдЯ рдХреЛ рдкрд░рд┐рд╖реНрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдСрдмреНрдЬреЗрдХреНрдЯ рджреНрд╡рд╛рд░рд╛ рд╕реНрд╡-рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдореБрдЦрд░ рдХреЗ рд▓рд┐рдП IDEA рдХреЗ рд▓рд┐рдП рдкреНрд▓рдЧ-рдЗрди рдХрд░реЗрдВ, рдФрд░ рдкреБрд░рд╛рдиреЗ UI-рд▓рд╛рдпрдмреНрд░реЗрд░реА рдХреЛ рд░реАрдлрд╝реНрд░реИрдХреНрдЯрд░ рдХрд░реЗрдВред рдЗрд╕ рддрд░рд╣ рдХреА "рдЪреБрдиреМрддрд┐рдпреЛрдВ" рдкрд░ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рд╡реЗ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрддрд▓рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╣рд╛рди рд╣реИрдВред


рдПрдХ рдмрд┐рдВрджреБ рдкрд░, рдореБрдЭреЗ рдмрд╣реБрдд рдкрд╣рд▓реЗ рд▓рдЧрд╛ рдерд╛ рдХрд┐ рдореБрдЭреЗ рдЖрд╡реЗрджрди рдХреЗ рдЧреНрд░рд╛рд╣рдХ рдмрдВрдбрд▓ рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рд╕реНрд╡рдд: рд╕рддреНрдпрд╛рдкрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдореЗрдВ рд░реБрдЪрд┐ рдереАред рдЖрдЦрд┐рд░рдХрд╛рд░, рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЬрд╛рдВрдЪ рдХреА рдЬрд╛ рд╕рдХрдиреЗ рд╡рд╛рд▓реА рд╣рд░ рдЪреАрдЬ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЬрд╛рдВрдЪрдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрддрд╛ рд╣реИред


рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, рдкрд░рд┐рдгрд╛рдо рдХреЗрд╡рд▓ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд╛рд░реНрдп рдирд╣реАрдВ рдерд╛, рдмрд▓реНрдХрд┐ рдХрд┐рд╕реА рднреА рдЪреЗрдХрд░реНрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдореЛрдВ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░реНрдпреЛрдВ (рдХреЛрд░ / рдХреЛрд░) рдХреЗ рд╕рд╛рде рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп (рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ)ред рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рд╢рдВрдХреБ рднрд░рд╛ рд╣реБрдЖ рдерд╛, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВ рднреА рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред


рддреЛ, рдЬреЗрдирдХрд┐рдВрд╕, рдмрд┐рдЯрдмрдХреЗрдЯ, рдореЗрд▓ (рдпрд╛ рдЯреЗрд▓реАрдЧреНрд░рд╛рдо, рд╕реБрд╕реНрдд - рдЖрдкрдХреЛ рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдП) рдФрд░ рдмрдВрдбрд▓ рдХреЗ рдЖрдХрд╛рд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдореЗрдВ рдпрд╣ рд╕рдм рджреЛрд╕реНрдд рдмрдирд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред


рдЫрд╡рд┐


рдкреНрд░рддреНрдпреЗрдХ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдмрд┐рдЯрдмрдХреЗрдЯ рдореЗрдВ 2 рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдЬрд╛рдВрдЪ рд╣реЛрддреА рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдмрд┐рдирд╛ рд╡рд┐рд▓рдп рдЕрд╕рдВрднрд╡ рд╣реИ: рдЬреАрд░рд╛ рдореЗрдВ рдХрд╛рд░реНрдп "рд╕рддреНрдпрд╛рдкрд┐рдд" рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЬреЗрдирдХрд┐рдВрд╕ рдореЗрдВ рд╕рднреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдЬрд╛рдВрдЪ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╢реБрд░реВ рдФрд░ рдкреВрд░реА рд╣реЛ рдЬрд╛рддреА рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, Bitbucket рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдП рдЧрдП рд╣реБрдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЬреЗрдирдХрд┐рдВрд╕ рдХреЛ рдПрдХ рд╢рд╛рдЦрд╛ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрдирд╛рдПрдВ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреА рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЪреЗрдХ рдХрд╛ рдкреВрд░рд╛ рдмрдВрдбрд▓ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬреЙрдм рд╡рд┐рдж рдЪреЗрдХ (рдХрдореНрдкреНрд░реЗрд╢рд░) рдореЗрдВ рдХрдИ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рд╣реИрдВ:


  • рд▓рд┐рдВрдЯ рд▓рд┐рдкрд┐;
  • рдЪрд▓ рд░рд╣реЗ рдкрд░реАрдХреНрд╖рдг;
  • тАФ , pull request , merge build publish Nexus, npm;
  • package.json.

, Bitbucket commit_checker. , , . challenge- commit_checker pipeline .
checker- -?


( c)


. , ( ) тАФ pull request. , , . , : , , , , 3 . , ( ). , , merge .


. , , : 600 (, , , - ).


тАФ , , pull request , merge , . .


, ...


, . , , API ( , Telegram). , .


. Jenkins job ( job). groove- , npm- , groove bin . , тАФ , Bitbucket , merge .


, , : groove- node тАФ .



: Groove Node?


GrooveтАФ , - .1. : , JS, // JS, Groove.
2. .
Node1. : , Node.
2. , /.
3. /Jira API/Bitbucket API.
4. -, , [size-limit](https://www.npmjs.com/package/size-limit).
1. Node, Jenkins .
2. API Jenkins /.

, Node.


┬л, ┬╗, 3


, . ( , Jira), . , .




, checker-core. , , .


. тАФ : -, /, dist, , . тАФ .


тАФ pull request.


тАФ ? :


  • dev/master ( ), - . тАФ .
  • / . тАФ , .
  • Git , , package.json, API Bitbucket dev/master , . , .

тАФ ?


, , , тАФ . тАФ . , , .


, , BitBucket ( Jenkins package.json). тАж


, , : ┬л!┬╗, , , , .


?



. - , : , - .


. : , , тАж : ┬л Jenkins? - ┬╗, тАФ , Jenkins ( ). -> -> -> .


, . , , (, ). , .



(, ) .


size-limit: , , .


. , тАж !


, roadmap .



, , size-limit , тАФ , . , , API , CLI. . cli- . .


, -, , , .


:


Checker-core


!


/src тАФ   
    |__ /tasks тАФ      ; ,  ,  ,   ,  .    - `job`.
    |__ /models тАФ ,   ;      `core`. ,      , , npm-.    `job`,  `tasks`   ,   `job,`   .  ,          `tasks`   `job`.
    |__ /types тАФ  .
    |__ /utils тАФ   (, ,    (npm)).
    |__ /errors тАФ ,   .
    |__ /enums тАФ  .
    |__ /decorators тАФ ,   `utils`, `tasks`, `job`.
    |__ /declarations тАФ  ,     Typescript.


Checker


Checker , . , , ..


Module


Module /, . ( , ..).



get-issue-assignees


. Checker project, assignee, lead.
Examples


import {
    Checker,
    Logger,
    IChecker,
    JiraManagerSettings,
    GetIssueAssignee
} from 'checker-core';
import {JiraSettings} from 'jira-manager';

import {IJobSettings} from '../types/IJobSettings';

export class ExampleJob {
    readonly _checker: IChecker;
    _jiraSettings: JiraManagerSettings;

    constructor(settings: IJobSettings) {
        if (settings === void 0) {
            throw new Error('Has no Checker settings');
        }

        this._checker = new Checker(settings.checker);
        this._jiraSettings = new JiraSettings(settings.jira);

        Logger.info('-- ExampleJob:');
        Logger.info(this._checker.appName);
    }

    start() {
        const getIssueAssignee = new GetIssueAssignee();

        return getIssueAssignee.run(this._checker, this._jiraSettings);
    }
}

get-last-merged-issue


. Checker .
Examples


import {Checker, Logger, IChecker, GetLastMergedIssue} from 'checker-core';

import {IJobSettings} from '../types/IJobSettings';

export class ExampleJob {
    readonly _checker: IChecker;

    constructor(settings: IJobSettings) {
        if (settings === void 0) {
            throw new Error('Has no Checker settings');
        }

        this._checker = new Checker(settings);

        Logger.info('-- ExampleJob:');
        Logger.info(this._checker.appName);
    }

    start() {
        const getLastMergedIssue = new GetLastMergedIssue();

        return getLastMergedIssue.run(this._checker);
    }
}

get-last-commit-issue


. Checker .


Examples


import {Checker, Logger, IChecker, GetLastCommitIssue} from 'checker-core';

import {IJobSettings} from '../types/IJobSettings';

export class ExampleJob {
    readonly _checker: IChecker;

    constructor(settings: IJobSettings) {
        if (settings === void 0) {
            throw new Error('Has no Checker settings');
        }

        this._checker = new Checker(settings);

        Logger.info('-- ExampleJob:');
        Logger.info(this._checker.appName);
    }

    start() {
        const getLastCommitIssue = new GetLastCommitIssue();

        return getLastCommitIssue.run(this._checker);
    }
}

send-notification send-smtp-notification


. .


send-notification send-smtp-notification тАФ . smtp- IMailTransportSettings.
Examples


import {
    Checker,
    Logger,
    IChecker,
    IMailTransportSettings,
    IMailContent,
    SendSmtpNotification
} from 'checker-core';

import {IJobSettings} from '../types/IJobSettings';

export class ExampleJob {
    readonly _checker: IChecker;
    _emailSettings: IMailTransportSettings;

    constructor(settings: IJobSettings) {
        if (settings === void 0) {
            throw new Error('Has no Checker settings');
        }

        this._checker = new Checker(settings.checker);
        this._emailSettings = settings.email;

        Logger.info('-- ExampleJob:');
        Logger.info(this._checker.appName);
    }

    start() {
        const sendSmtpNotification = new SendSmtpNotification();
        const mailContent: IMailContent = {
            subject: '',
            content: ' , ?'
        };

        return sendSmtpNotification.run(this._checker, mailContent, this._emailSettings);
    }
}


: , .



Logger


.


Npm


Nexus.


mailTransport


( mail linux nodemailer smtp).


Decorators


logAsyncMethod


, .


process.env.IS_DEBUG_MODE , .


validate


. .


Examples
import {
    notNullProp, validate, required,
    validInfo, notNull, requiredProp
} from 'checker-core';

class TestSum {
    @validate
    static sum(
        @required
        @notNull
        @requiredProp(['a'])
        @notNullProp(['a'])
        @validInfo('a', Object)
        a: Object,
        @required
        @notNull
        @requiredProp(['b'])
        @notNullProp(['b'])
        @validInfo('b', Object)
        b: Object
    ) {
        return a.a + b.b;
    }
}

Errors


MissingRequiredArgument


.


MissingRequiredProperty


, .


NullArgument


, null.


NullProperty


, , null.


TypeMismatch


.


bundle-size-checker


checker-core core, :


/src тАФ   
    |__ /bin тАФ  , CLI     ,  2  :            `job`.         , ,    1 `process.exit(1)`;
    |__ /jobs тАФ ,       (`checker` + ,   ),        .      `task`, `utils`,    ;
    |__ /tasks тАФ      ; ,  ,  ,   ,  .    - `job`;
    |__ /models тАФ ,   ,      `core`. ,      , , npm-.    `job`,  `tasks`   ,   `job`,   .  ,          `tasks`   `job`;
    |__ /types тАФ  ;
    |__ /utils тАФ   (, ,    (npm));
    |__ /errors тАФ ,   ;
    |__ /enums тАФ  ;
    |__ /decorators тАФ    `utils`, `tasks`, `job`;
    |__ /declarations тАФ  ,     Typescript.

, job тАФ , , checker-, , , , - , , , ( , ..).


:


import path from 'path';
import {JiraSettings} from 'jira-manager';
import {
    Logger,
    JiraManagerSettings,
    IMailTransportSettings,
    MissingRequiredProperty
} from 'checker-core';
import {Module} from '../models/module';
import {CompareBundleSize} from '../tasks/compare-bundle-size';
import {Checker} from '../models';
import {IJobCheckBundleSizeSettings} from '../types/IJobCheckBundleSizeSettings';
import {IModule} from '../types/IModule';
import {IModuleSettings} from '../types/IModuleSettings';
import {GetMetaInfo} from '../tasks/get-meta-info';
import {CheckBundleSizeNotEmpty} from '../tasks/check-bundle-size-not-empty';
import {GetBundleSize} from '../tasks/get-bundle-size';
import {ReadFileError} from '../errors/ReadFileError';
import {IPackageJson} from '../types/IPackageJson';
import {IChecker} from '../types/IChecker';
import {FilterException} from '../tasks/filter-exception';

//      .
export class CheckBundleSize {
    readonly _checker: IChecker;
    readonly _jobName = 'CheckBundleSize';

    _moduleSettings: IModuleSettings;
    _checkerModule: IModule;
    _jiraSettings: JiraManagerSettings;
    _emailSettings: IMailTransportSettings;

    constructor(settings: IJobCheckBundleSizeSettings) {
        if (settings.checker === void 0) {
            throw new MissingRequiredProperty(this._jobName, 'constructor', 'settings', 'checker');
        }

        this._moduleSettings = settings.module;
        this._emailSettings = settings.emailSettings;
        this._jiraSettings = new JiraSettings(settings.jira);
        this._checker = new Checker(settings.checker);

        try {
            const packageJsonPath = path.resolve(this._checker.rootPath, 'package.json');
            const packageJson: IPackageJson = require(packageJsonPath);
            this._checkerModule = new Module(
                packageJson,
                this._moduleSettings.maxBundleSize,
                this._moduleSettings.needCheckBundleSize
            );
        } catch (err) {
            Logger.info('Can nott load package.json');
            throw new ReadFileError(this._jobName, 'package.json');
        }

        Logger.info(`${this._jobName}:`);
        Logger.info(this._checker.appName);
    }

    //     
    async start() {
        try {
            const getBundleSizeTask = new GetBundleSize();
            const getMetaInfo = new GetMetaInfo();
            const checkBundleSizeEmpty = new CheckBundleSizeNotEmpty();
            const compareBundleSize = new CompareBundleSize();

            const getBundleSize = await getBundleSizeTask.run(this._checker, this._checkerModule);

            if (!getBundleSize) {
                return;
            }

            await getMetaInfo.run(this._checker, this._jiraSettings);
            await checkBundleSizeEmpty.run(this._checker, this._checkerModule);

            await compareBundleSize.run(this._checker, this._checkerModule);
        } catch (err) {
            const filterException = new FilterException(this._emailSettings);
            await filterException.run(this._checker  v , this._checkerModule, err);

            throw err;
        }
    }
}

bin , cli .


тАж
const checkBundleSize = new CheckBundleSize(settings);

checkBundleSize.start()
    .then(() => {
        process.exit(0);
    })
    .catch((err: Error) => {
        console.error(err);
        console.error(`Can fail build: ${canFailBuild}`);
        if (canFailBuild) {
            process.exit(1);
        } else {
            process.exit(0);
        }
    });


/ , , (, , ). , : , , . roadmap . , тАФ .


, .


. : ? , open source.


All Articles