Модель ветвления GIT описана здесь.
Для коммитов и pull requests включен commitlint. Ниже описан формат.
Для enums feat, bug обязательно должен указываться номер задачи в jira.
Формат:
${ENUM}(TASK,COMPONENT_NAME|SCOPE): Что было сделано?
ENUM:
- feat - добавлена новая фича. Для этого enum будет произведен релиз minor версии пакетов
- bug - исправлена ошибка. Для этого enum будет произведен релиз patch версии пакетов
- wip (work in progress) - промежуточные изменения
- refactor - произведен рефакторинг. Для этого enum будет произведен релиз patch версии пакетов
- doc - внесены изменения в .md файлы или storybook. Для этого enum релиз произведен не будет
- build - внесены изменения в сборке пакетов. Для этого enum будет произведен релиз patch версии пакетов
- chore - внесены изменения в настройку окружения проекта (линтеры, ci...). Для этого enum релиз произведен не будет
- test - написаны или изменены тесты проекта
COMPONENT_NAME - имя измененного компонента (наименование директорий из ui/src).
SCOPE разделены по пакетам и ограничены несколькими из них:
- icons
- fonts При внесении изменений в эти пакеты вместо COMPONENT_NAME необходимо указывать SCOPE.
feat(UIKIT-123,Button): Добавлен props color
feat(Button): Добавлен props color
feat(UIKIT-123,Button): Добавлен props color
feat(UIKIT-123, Button): Добавлен props color
feat(UIKIT-123,icons): Добавлена иконка PlusFillMd
feat(UIKIT-123, PlusFillMd): Добавлена иконка
feat(UIKIT-123,icons): Добавлены иконки PlusFillMd, ProfileFillMd, InfoFillMd
feat(UIKIT-123, PlusFillMd, ProfileFillMd, InfoFillMd): Добавлены иконки
Для проекта подключены авторелизы npm пакетов с помощью semantic-release. Semantic-release определяет новую версию пакета по названию коммита, а именно по его enum:
- feat - релиз minor версии пакетов
- bug - релиз patch версии пакетов
- wip (work in progress) - релиз произведен не будет
- refactor - релиз patch версии пакетов
- doc - релиз произведен не будет
- build - релиз patch версии пакетов
- chore - релиз произведен не будет
- major - будет произведен релиз major версии
При внесении изменений в main ветку запускается релиз пакетов. При релизе происходит следующее:
- В
create_release.yml
срабатывает триггер на push в main - Semantic-release определяет новую версию пакета
- Если новая версия пакета отличается от предыдущей, то запускается билд каждого пакета и его паблишинг в npm. Все пакеты релизятся сразу с одной версией
- Semantic-release генерирует changelog и создает новый release на github, добавляя в описание сгенерированный changelog
- После успешного паблишинга пакетов, в телеграм канал отправляется уведомление о новой версии пакетов
При написании кода должна быть реализована поддержка 17 версии React
Для документирования компонентов используется storybook.
Здесь находится основной стенд storybook.
Для каждого PR создается свой стенд с storybook. Ссылку на стенд вы увидите в CI Github под пунктом "publish storybook".
В качестве шаблона для написания stories необходимо использовать:
- TextField для
@astral/components
- FormTextField для
@astral/form
На основе *.stories.tsx
файлов storybook автоматически генерирует документацию в виде .mdx
файлов.
Именно сгенерированные .mdx
файлы отображаются в разделе Docs.
Storybook автоматически генерирует API Props на основе типов typescript.
ℹ️ Если какой-либо prop не попал в сгенерированное API, то необходимо править функцию filterProp в файле main.js.
Любой экспортируемый компонент из .stories.tsx
считается story и попадает в Docs.
Представленный ниже компонент будет преобразован в соответствующий раздел в Docs.
/**
* Prop ```colorIntensity``` позволяет задать интенсивность указанного ```color```.
*/
export const ColorIntensity = () => (
<Grid container spacing={6}>
<Typography color="info" colorIntensity="300">
text[300]. Электронная отчетность и документооборот
</Typography>
<Typography color="red" colorIntensity="200">
red[200]. Электронная отчетность и документооборот
</Typography>
<Typography color="grey" colorIntensity="400">
grey[400]. Электронная отчетность и документооборот
</Typography>
</Grid>
);
Каждая story по-дефолту оборачивается в контейнер с версткой, описанным в preview файле:
- Контент центрируется
- Между элементами добавляется стандартный отступ
- Элементы переносятся на следующую строку, если не влезают
- Для мобильного разрешения элементы выстраиваются в одну колонку
Если дефолтной верстки контейнера хватает, то можно использовать fragment
для оборачивая story:
export const Statuses = () => (
<>
<TextField required error helperText="Обязательно" label="Имя" />
<TextField
success
helperText="Удачно завершился процесс проверки"
label="Email"
/>
</>
);
Если дефолтного контейнера не хватает, то можно написать для story свой:
export const Variants = () => (
<ButtonsContainer columns={4}>
<Button>Contained</Button>
<Button variant="light">Light</Button>
<Button variant="link">Link</Button>
<Button variant="text">Text</Button>
</ButtonsContainer>
);
Комментарии оставленные для story попадают в .mdx
файлы.
При этом комментарии поддерживают markdown.
Для story:
/**
* Prop ```noWrap``` позволяет добавить ```...```, если текст не помещается в контейнер.
*
* Если необходимо умное ограничение длинны поля с tooltip, смотрите на [OverflowTypography](/docs/components-overflowtypography--docs).
*/
export const Ellipsis = () => (
<div style={{ width: '200px' }}>
<Typography noWrap>
Электронная отчетность и документооборот. Электронная отчетность и
документооборот
</Typography>
</div>
);
Будет сгенерирована документация.
Для каждого компонента должен быть реализован storybook.
Каждый *.stories.tsx
файл должен соответствовать следующей структуре:
- Meta - метаданные компонента 2. Описание (optional) 3. Ссылка на Figma (required) 4. Ссылка на Guide (required)
- Interaction - интерактивная story, у которой можно менять пропсы через ui
- Example - story, показывающая как компонент может применяться в проекте
- Stories - остальные кейсы для компонента
ℹ️ При написании stories необходимо учитывать мобильные разрешения. Дефолтный контейнер учитывает мобильные разрешения.
/**
* Весь текст должен задаваться через Typography.
*
* ### [Figma](https://www.figma.com/file/3ghN4WjSgkKx5rETR64jqh/Sirius-Design-System-(%D0%90%D0%9A%D0%A2%D0%A3%D0%90%D0%9B%D0%AC%D0%9D%D0%9E)?type=design&node-id=1-347&mode=design&t=lMvg1tmjfSIA2lhp-0)
* ### [Guide]()
*/
const meta: Meta<typeof Typography> = {
title: 'Components/Typography',
component: Typography,
};
Meta
необходим для того, чтобы storybook смог получить основную информацию о компоненте и сгенерировать API по пропсам.
title
задает в каком разделе sidebar будет находиться компонент.
Комментарии для Meta попадают в description компонента. В описании может находиться назначение компонента, либо рекомендации по его использованию. Если название компонента говорит само за себя (например, Button), то description можно опустить.
В комментарии Meta обязательно должна присутствовать ссылка на макеты компонента.
В комментарии Meta обязательно должна присутствовать ссылка на Guide для компонента.
Для генерации story, в которой можно будет в ui менять props, используется Interaction
объект.
type Story = StoryObj<typeof Typography>;
export const Interaction: Story = {
args: {
children: 'Электронная отчетность и документооборот',
},
parameters: {
docs: {
disable: true,
},
},
};
Interaction story не должна попадать в Docs раздел.
parameters.docs.disable
позволяет отключить отображение story в Docs.
args
позволяет подставить в Controls
панель дефолтные значения пропсов.
Первой story должен быть всегда Example - пример использования компонента в проекте. Example необходимо брать из макетов Figma.
export const Example = () => (
<ExamplePaper>
<Typography variant="h3" component="h2" gutterBottom>
Заявка успешно отправлена
</Typography>
<Typography paragraph>
Заявка{' '}
<Typography color="info" component="span">
22
</Typography>{' '}
была отправлена на ваш email
</Typography>
</ExamplePaper>
);
После Example должны быть реализованы кейсы использования компонента. Кейсы формирует разработчик самостоятельно.
Для каждого значимого props должен быть описан свой кейс.
В примере для Typography кейсы сформированы по основным props.
Если у prop или кейса есть особенности, то необходимо добавить к ним описание через комментарий к story:
/**
* Prop ```noWrap``` позволяет добавить ```...```, если текст не помещается в контейнер.
*
* Если необходимо умное ограничение длинны поля с tooltip, смотрите на [OverflowTypography](/docs/components-overflowtypography--docs).
*/
export const Ellipsis = () => (
<div style={{ width: '200px' }}>
<Typography noWrap>
Электронная отчетность и документооборот. Электронная отчетность и
документооборот
</Typography>
</div>
);
Если у компонента есть специфичные кейсы, не относящиеся к какому-либо одному props, то их необходимо отобразить и по необходимости описать через комментарий.
Для компонентов-оберток достаточно указать ссылку на storybook исходного компонента и описать stories для уникальных кейсов.
В stories необходимо использовать фейковые данные для демонстрации кейсов.
Для подготовки набора данных необходимо использовать методы для генерации фейковых данных. Пример:
- Методы для генерации фейковых данных должны находится в файле
faker.ts
При использовании фейковых коллекций внутри story необходимо вручную описывать первый элемент массива:
export const LoadingWithData = () => {
const columns: DataGridColumns<DataItem> = [
{
field: 'documentName',
label: 'Наименование документа',
sortable: true,
},
...FAKE_COLUMNS,
];
const data: DataGridRowWithOptions<DataItem> = [
{
id: '1',
documentName: 'Договор 1'
},
...makeDataList(9),
];
return (
<ConfigProvider
imagesMap={{
defaultErrorImgSrc: errorIllustration,
noDataImgSrc: noDataIllustration,
outdatedReleaseErrorImgSrc: '',
}}
>
<DataGridInfiniteWrapper>
<NewDataGridInfinite<DataItem, SortField>
keyId="id"
rows={data}
isLoading
columns={columns}
/>
</DataGridInfiniteWrapper>
</ConfigProvider>
);
};
Данное правило позволяет улучшить UX чтения документации - разработчик видит какой тип данных принимает компонент.
Тесты в проекте пишутся с использованием vitest и react-testing-library.
Тесты должны соблюдать принципы, описанные в Astral Unit Testing Guide.
Тестами покрываются сущности, экспортируемые из поставляемых пакетов, к ним относятся:
- Утилиты
- Компоненты
- Хуки
Все экспортируемые утилиты должны быть покрыты тестами.
Для тестирования компонентов используется react-testing-library + jsdom.
- Проверить доступность ref (при необходимости)
- Проверить базовый сценарий отображения
- Проверить все измененные mui props или новые props (если props не связаны с изменением исключительно CSS)
Точно должно быть покрыто тестами:
- Функционал, написанный для компонента в репозитории. Если функционал предоставляется внешней библиотекой, то его тестировать не надо.
- Проверка реакции компонента на пользовательские ивенты (click, focus, tab...)
- Вариативность props
Не тестируется:
- CSS. Используемые инструменты не умеют правильно эмулировать каскад в css. Примеры таких кейсов: проверка ширины бордера элемента, проверка цвета элемента...
Здесь описан style guide по написанию тестов.
При создании новых пакетов необходимо:
- Релизнуть тестовую версию пакета. В противном случае CI проверки PR упадет с ошибкой (npm не позволяет создавать новые пакеты по токену)