@rt-tools/agent-kit 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -6
- package/assets/hooks/browser-device-id.sh +20 -0
- package/assets/hooks/browser-guard-device-id.sh +27 -0
- package/assets/hooks/browser-guard-no-listing.sh +17 -0
- package/assets/hooks/browser-guard-no-other-drivers.sh +78 -0
- package/assets/hooks/browser-guard-require-select.sh +53 -0
- package/assets/hooks/commit-msg.sh +26 -0
- package/assets/hooks/constitution-index.sh +42 -0
- package/assets/hooks/dev-server-guard.sh +113 -0
- package/assets/hooks/docs-guard.sh +96 -0
- package/assets/hooks/git-guard-delivery.sh +110 -0
- package/assets/hooks/git-guard-main.sh +72 -0
- package/assets/hooks/git-guard-push-tests.sh +73 -0
- package/assets/hooks/lint-after-edit.sh +94 -0
- package/assets/hooks/qa-dataid-guard.sh +81 -0
- package/assets/hooks/reuse-first-guard.sh +83 -0
- package/assets/hooks/skill-gate-rearm.sh +22 -0
- package/assets/hooks/skill-gate.sh +68 -0
- package/assets/hooks/skill-loaded.sh +20 -0
- package/assets/hooks/sql-guard.sh +129 -0
- package/assets/patterns/angular-patterns-state.md +94 -0
- package/assets/patterns/api-layer-pair.md +78 -0
- package/assets/patterns/browser-verification-measure.md +83 -0
- package/assets/patterns/browser-verification-stand.md +79 -0
- package/assets/patterns/component-structure-new.md +98 -0
- package/assets/patterns/doc-style-sweep.md +100 -0
- package/assets/patterns/doc-style-write.md +106 -0
- package/assets/patterns/git-workflow-commit.md +175 -0
- package/assets/patterns/git-workflow-merge.md +82 -0
- package/assets/patterns/git-workflow-migration.md +58 -0
- package/assets/patterns/git-workflow-restart.md +49 -0
- package/assets/patterns/lib-layers-move.md +77 -0
- package/assets/patterns/lib-layers-new.md +70 -0
- package/assets/patterns/permissions-procedure.md +69 -0
- package/assets/patterns/platform-access-di.md +70 -0
- package/assets/patterns/reuse-first-extend.md +73 -0
- package/assets/patterns/seo-page.md +92 -0
- package/assets/patterns/seo-verify.md +64 -0
- package/assets/patterns/shared-code-new.md +80 -0
- package/assets/patterns/spec-driven-domain.md +100 -0
- package/assets/patterns/spec-driven-rule.md +112 -0
- package/assets/patterns/styling-bem-component.md +77 -0
- package/assets/patterns/styling-bem-layout.md +67 -0
- package/assets/patterns/testing-e2e.md +90 -0
- package/assets/patterns/testing-unit.md +93 -0
- package/assets/patterns/translations-key.md +51 -0
- package/assets/patterns/ts-procedure.md +66 -0
- package/assets/rules/angular-patterns.md +52 -0
- package/assets/rules/api-layer.md +53 -0
- package/assets/rules/browser-verification.md +69 -0
- package/assets/rules/component-structure.md +48 -0
- package/assets/rules/doc-style.md +61 -0
- package/assets/rules/git-workflow.md +106 -0
- package/assets/rules/lib-layers.md +54 -0
- package/assets/rules/permissions.md +52 -0
- package/assets/rules/platform-access.md +49 -0
- package/assets/rules/reuse-first.md +69 -0
- package/assets/rules/seo.md +50 -0
- package/assets/rules/shared-code.md +45 -0
- package/assets/rules/spec-driven.md +89 -0
- package/assets/rules/styling-bem.md +59 -0
- package/assets/rules/testing.md +69 -0
- package/assets/rules/translations.md +52 -0
- package/assets/rules/typescript-conventions.md +46 -0
- package/assets/templates/gate-map.sh +37 -0
- package/assets/templates/implementation.md +38 -0
- package/assets/templates/pattern.md +4 -0
- package/assets/templates/project.sh +41 -0
- package/assets/templates/rule.md +12 -23
- package/lib/assets.d.ts +8 -0
- package/lib/assets.d.ts.map +1 -1
- package/lib/assets.js +12 -1
- package/lib/assets.js.map +1 -1
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +21 -2
- package/lib/commands.js.map +1 -1
- package/lib/companion.d.ts +53 -0
- package/lib/companion.d.ts.map +1 -0
- package/lib/companion.js +33 -0
- package/lib/companion.js.map +1 -0
- package/lib/config.d.ts +24 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +33 -1
- package/lib/config.js.map +1 -1
- package/lib/stamp.d.ts +2 -5
- package/lib/stamp.d.ts.map +1 -1
- package/lib/stamp.js +25 -10
- package/lib/stamp.js.map +1 -1
- package/lib/sync.d.ts +3 -0
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js +20 -1
- package/lib/sync.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.3.0.tgz +0 -0
- package/rt-tools-agent-kit-0.2.0.tgz +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: doc-style-sweep
|
|
3
|
+
kind: pattern
|
|
4
|
+
rule: doc-style
|
|
5
|
+
description: Паттерн правила doc-style. Брать, когда документ накопил список работ и его надо разобрать на действующее и закрытое — признак отбора, обход по утверждениям, сверка с очередью работ, измерение потерь, куда девать доводы за отсрочку и судьба самого файла. Не брать для написания нового текста — это паттерн doc-style-write.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Разбор документа, накопившего список работ
|
|
9
|
+
|
|
10
|
+
Паттерн правила `doc-style`. Что при этом должно быть верно — закон
|
|
11
|
+
`{{lawsDir}}/project-documentation.md`, статья о том, что предстоящая работа перечислена в одном
|
|
12
|
+
месте.
|
|
13
|
+
|
|
14
|
+
## Когда брать
|
|
15
|
+
|
|
16
|
+
- Документ перечисляет, что осталось сделать, а очередь работ перечисляет то же самое.
|
|
17
|
+
- Файл вырос настолько, что его перестали читать целиком.
|
|
18
|
+
- Планы лежат вперемешку: часть исполнена, часть нет, и по тексту это не различить.
|
|
19
|
+
|
|
20
|
+
## Признак отбора — один, и он решается до первой правки
|
|
21
|
+
|
|
22
|
+
**Утверждение остаётся в документе, если править его никто не собирается.** Всё остальное —
|
|
23
|
+
работа, и её место в очереди работ.
|
|
24
|
+
|
|
25
|
+
| Что нашлось | Куда |
|
|
26
|
+
| ------------------------------------------------------- | --------------------------------------------------------------- |
|
|
27
|
+
| дыра, которую будут чинить | задача; строка из документа уходит |
|
|
28
|
+
| дыра, которую решено не чинить | остаётся, вместе с причиной |
|
|
29
|
+
| условный отказ («заведём, если случай окажется частым») | остаётся |
|
|
30
|
+
| вывод разбора, не ставший правилом | остаётся |
|
|
31
|
+
| описание сделанного | удаляется без переноса: о нём говорят закрытые задачи и история |
|
|
32
|
+
| утверждение, разошедшееся с деревом | удаляется как протухшее, а не переносится в задачу |
|
|
33
|
+
|
|
34
|
+
Спрашивать владельца об этом наборе не нужно — он записан здесь. Спрашивать стоит одно: судьбу
|
|
35
|
+
самого файла, когда в нём не осталось ничего.
|
|
36
|
+
|
|
37
|
+
## Обход идёт по утверждениям, а не по пунктам
|
|
38
|
+
|
|
39
|
+
Работа лежит и в прозе: раздел без единого маркера обход по списку не увидит вовсе. Абзац
|
|
40
|
+
судится тем же признаком, что и пункт.
|
|
41
|
+
|
|
42
|
+
## Номер задачи стоит в нескольких местах
|
|
43
|
+
|
|
44
|
+
Прежде чем считать «пункты без задачи», надо знать все формы записи — в заголовке, отдельной
|
|
45
|
+
строкой у раздела и в конце пункта. Разбор, знающий одну форму, ошибается молча. **Число,
|
|
46
|
+
полученное разбором текста, сверяется на выборке руками до того, как его называют.**
|
|
47
|
+
|
|
48
|
+
## Сверка с очередью работ
|
|
49
|
+
|
|
50
|
+
У пункта есть задача — это ещё не значит, что задача несёт его содержание. Перед удалением
|
|
51
|
+
меряется покрытие: сколько значимых слов пункта встречается в теле его задачи. Пункт, покрытый
|
|
52
|
+
наполовину и меньше, читается глазами и разводится на три исхода:
|
|
53
|
+
|
|
54
|
+
- живое уточнение, которого в задаче нет, — дописать в тело;
|
|
55
|
+
- другой дефект — завести своей задачей;
|
|
56
|
+
- протухшее — удалить, **не** перенося. Иначе разбор занесёт в задачу ложь.
|
|
57
|
+
|
|
58
|
+
**Наследование номера от заголовка — предположение, а не факт.** Пункт под заголовком с
|
|
59
|
+
несколькими номерами не принадлежит ни одному из них: привязка проверяется чтением.
|
|
60
|
+
|
|
61
|
+
## Сделанность читается по дереву
|
|
62
|
+
|
|
63
|
+
Утверждение о том, что задача не сделана, стареет так же, как любое другое. Проверяется то, о
|
|
64
|
+
чём собираешься сказать «не сделано», — поиском по дереву, а не памятью.
|
|
65
|
+
|
|
66
|
+
## Доводы за отсрочку — это «чего это стоит»
|
|
67
|
+
|
|
68
|
+
Раздел «что стоит отложить» переезжает не в архив, а **в тела тех задач, которых он касается**:
|
|
69
|
+
там он и есть оценка цены. В файле он остаётся, только если отсрочка — решение владельца, а не
|
|
70
|
+
предложение разбора. Признак — записанный ответ владельца с датой.
|
|
71
|
+
|
|
72
|
+
## Ссылки на снятые разделы
|
|
73
|
+
|
|
74
|
+
Задача, чьё тело ссылается на раздел документа, после разбора ведёт в пустоту, и проверка путей
|
|
75
|
+
этого не видит: она читает файлы репозитория, а не тела задач. Строка снимается тем же заходом.
|
|
76
|
+
|
|
77
|
+
## Судьба файла
|
|
78
|
+
|
|
79
|
+
- Осталось незадачное — файл живёт, и его вступление объявляет новый признак отбора.
|
|
80
|
+
- Не осталось ничего, а документ описывал состоявшуюся работу — уезжает в архив.
|
|
81
|
+
- Не осталось ничего, и это был список работ — удаляется.
|
|
82
|
+
|
|
83
|
+
Разбор целиком — одна задача и одна ветка: делится то, что придётся откатывать порознь, а здесь
|
|
84
|
+
откат общий. Правка кода, найденная по дороге, в эту ветку не идёт — иначе откат разбора унесёт
|
|
85
|
+
починку.
|
|
86
|
+
|
|
87
|
+
## Что чинится в дереве следом
|
|
88
|
+
|
|
89
|
+
Документ — не единственное место, обещающее, что работа живёт в нём. Снятое имя вычищается одним
|
|
90
|
+
проходом по всему дереву, включая описания ролей, скилы, README и комментарии в коде.
|
|
91
|
+
|
|
92
|
+
## Частые промахи
|
|
93
|
+
|
|
94
|
+
- Обход по маркированным пунктам: половина работы лежит прозой и переживает разбор.
|
|
95
|
+
- «На это есть задача» без чтения её тела: пункт удалён, содержание потеряно.
|
|
96
|
+
- Число пунктов названо владельцу до сверки на выборке.
|
|
97
|
+
- Протухшее утверждение перенесено в задачу и стало действующим указанием.
|
|
98
|
+
- Доводы за отсрочку оставлены в документе: он снова становится вторым списком работ.
|
|
99
|
+
- Разбор поделён на несколько задач «по объёму» — признак деления не объём, а раздельный откат.
|
|
100
|
+
- Архив тронут: он описывает состояние на момент написания и под новые термины не правится.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: doc-style-write
|
|
3
|
+
kind: pattern
|
|
4
|
+
rule: doc-style
|
|
5
|
+
description: Паттерн правила doc-style. Брать при написании любой прозы проекта — правил, спеков, README, комментариев в коде, тел коммитов, описаний PR. Примеры «так» и «не так» на каждую договорённость о формулировке. Не брать для устройства спека — это правило spec-driven.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Как формулировать
|
|
9
|
+
|
|
10
|
+
Паттерн правила `doc-style`. Что при этом должно быть верно — закон
|
|
11
|
+
`{{lawsDir}}/project-documentation.md`.
|
|
12
|
+
|
|
13
|
+
## Когда брать
|
|
14
|
+
|
|
15
|
+
- Пишется правило, статья закона, пункт спека или README.
|
|
16
|
+
- Пишется комментарий в коде, тело коммита, описание PR.
|
|
17
|
+
|
|
18
|
+
## Статья — одна фраза
|
|
19
|
+
|
|
20
|
+
Сама статья укладывается в одно предложение. Следом — не больше двух предложений о том, что
|
|
21
|
+
сломается иначе, и только если из самой фразы это не видно. Обоснование, у которого была
|
|
22
|
+
альтернатива, идёт в «Ловушки» правила, а не в закон: разросшийся пункт читают по диагонали, а
|
|
23
|
+
закон говорит, что верно, — не почему когда-то выбрали так.
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
✗ **Взрослых в записи хотя бы один — на любом пути записи, без исключений.** Нижнюю
|
|
27
|
+
границу держит хранилище: путей записи три, и проверка в одном из них закрывает не все.
|
|
28
|
+
Верхнюю ограничением хранилища не выразить — она лежит в самой записи и меняется
|
|
29
|
+
владельцем.
|
|
30
|
+
|
|
31
|
+
✓ **Взрослых в записи хотя бы один.** Исключений нет.
|
|
32
|
+
✓ **Взрослые и дети не превышают вместимость.**
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Что верно, а не где это держится
|
|
36
|
+
|
|
37
|
+
«Держит хранилище, а не служба», «проверяется в транзакции», «умолчание колонки», «на трёх
|
|
38
|
+
путях записи из четырёх», имена функций и колонок внутри фразы — это устройство кода. Читателю
|
|
39
|
+
нужно знать, **что** верно.
|
|
40
|
+
|
|
41
|
+
Место исполнения меняется при первом же переносе, и документ, который его называет, устаревает
|
|
42
|
+
молча. Для него заведён отдельный файл — `implementation.md` рядом с правилом.
|
|
43
|
+
|
|
44
|
+
Исключение — «Ловушки» правила: там устройство кода называется прямо, потому что ловушка и есть
|
|
45
|
+
место, где на него наступают.
|
|
46
|
+
|
|
47
|
+
## Без утверждений о будущем
|
|
48
|
+
|
|
49
|
+
«Не планируется», «не будет», «отдельная задача по запросу» — это намерение владельца, а не
|
|
50
|
+
свойство системы. Что не сделано — да, почему не сделано — да, что не будет сделано никогда —
|
|
51
|
+
нет.
|
|
52
|
+
|
|
53
|
+
Ошибка беззвучная: сверять утверждение о будущем не с чем, оно проходит любую проверку.
|
|
54
|
+
|
|
55
|
+
Отсюда же: того, чего нет в документе о продукте, пересказ не утверждает. Домысел при пересказе
|
|
56
|
+
звучит убедительнее исходника — он короче и категоричнее.
|
|
57
|
+
|
|
58
|
+
## Простыми словами
|
|
59
|
+
|
|
60
|
+
Афоризмы, метафоры и инверсии затрудняют чтение и ничего не добавляют.
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
✗ запись о прошлом не должна упираться в правило, появившееся позже
|
|
64
|
+
✗ пустой список без текста и отказ без кнопки выглядят одинаково — как сломанная страница
|
|
65
|
+
|
|
66
|
+
✓ запись, внесённую владельцем, пропажа события из ленты не снимает
|
|
67
|
+
✓ у пустого списка должен быть текст, у отказа — кнопка повтора
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Проверка: прочитать фразу вслух. Если так не говорят — переписать.
|
|
71
|
+
|
|
72
|
+
## Факт проверяется, а не вспоминается
|
|
73
|
+
|
|
74
|
+
Перед тем как написать, что код делает то-то, — открыть код и посмотреть. Пересказ по памяти
|
|
75
|
+
выглядит так же уверенно, как проверенное утверждение, и отличить их потом нечем.
|
|
76
|
+
|
|
77
|
+
Особенно это касается отказов: недостижимый отказ, названный в документе, живёт там годами —
|
|
78
|
+
проверить его читателю нечем.
|
|
79
|
+
|
|
80
|
+
## Не пересказывать то, у чего есть источник
|
|
81
|
+
|
|
82
|
+
- типы и поля контракта — ссылкой на сам контракт;
|
|
83
|
+
- колонки и индексы — ссылкой на схему хранилища;
|
|
84
|
+
- числа, которые правит владелец, — только как они применяются;
|
|
85
|
+
- слои и имена классов — правило `lib-layers` и сам код.
|
|
86
|
+
|
|
87
|
+
## Комментарии в коде
|
|
88
|
+
|
|
89
|
+
Те же правила. Комментарий отвечает на вопрос «почему так, а не иначе» — если ответ неочевиден.
|
|
90
|
+
Что делает строка, видно из строки.
|
|
91
|
+
|
|
92
|
+
Многострочный комментарий над каждой функцией — признак того, что объяснение подменило имя.
|
|
93
|
+
Сначала переименовать, потом писать комментарий.
|
|
94
|
+
|
|
95
|
+
Комментарий, оправдывающий отклонение от правила, держит это отклонение на себе: пока
|
|
96
|
+
объяснение выглядит убедительно, отклонение не трогают. Факт в нём проверяется, когда
|
|
97
|
+
комментарий пишут, и перепроверяется, когда отклонение снимают.
|
|
98
|
+
|
|
99
|
+
## Частые промахи
|
|
100
|
+
|
|
101
|
+
- Чужой проект назван в коммите, PR, комментарии или документе. Ни имени репозитория, ни
|
|
102
|
+
«портировано из», ни ссылок на его файлы — нигде.
|
|
103
|
+
- Число написано по памяти, а не пересчитано командой в том же коммите.
|
|
104
|
+
- Пункт плана вычеркнут по памяти о работе, а не по дереву.
|
|
105
|
+
- Формулировка звучит как заголовок, а не как статья: «работа со скидками» нарушить нельзя,
|
|
106
|
+
«применяется одна максимальная скидка» — можно.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-workflow-commit
|
|
3
|
+
kind: pattern
|
|
4
|
+
rule: git-workflow
|
|
5
|
+
description: Паттерн правила git-workflow. Брать на заведение задачи, ветки, коммит, пуш и создание PR — план до первой задачи, заведение задачи всеми шагами сразу, перевод по колонкам, слияние двух задач в одну, работа от учётной записи машинной работы, формат заголовка, строка связи с задачей, состав PR, чеклист проверок до публикации. Не брать для миграций и перезапуска прода — это паттерны git-workflow-migration и git-workflow-restart.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Ветка, коммит и PR
|
|
9
|
+
|
|
10
|
+
Паттерн правила `git-workflow`. Что при этом должно быть верно — закон `{{lawsDir}}/delivery.md`.
|
|
11
|
+
|
|
12
|
+
## Когда брать
|
|
13
|
+
|
|
14
|
+
- Заводится задача, с которой начинается правка.
|
|
15
|
+
- Заводится ветка под задачу.
|
|
16
|
+
- Готовится коммит или пуш.
|
|
17
|
+
- Открывается PR.
|
|
18
|
+
- Работа перешла на следующий шаг, и задача переставляется в другую колонку.
|
|
19
|
+
|
|
20
|
+
## Сначала план, потом задачи
|
|
21
|
+
|
|
22
|
+
Работа, из которой выходит больше одной задачи, начинается с плана, и план показывается
|
|
23
|
+
владельцу до того, как заведена первая задача. Разбивка — решение о том, что делается и в каком
|
|
24
|
+
порядке, и принимает его владелец, а не тот, кто заводит.
|
|
25
|
+
|
|
26
|
+
Заведённые до согласования задачи стоят в очереди как решённое дело: они показывают работу,
|
|
27
|
+
которую никто не заказывал, и убирать их потом дороже, чем не заводить.
|
|
28
|
+
|
|
29
|
+
Признак тот же, что у деления на ветки, — раздельный откат. Один дефект планом не описывается:
|
|
30
|
+
для него сразу заводится задача.
|
|
31
|
+
|
|
32
|
+
Плана нет, а работа делится — сначала пишется план, показывается, и только после ответа
|
|
33
|
+
владельца заводится первая задача. Ответ «делай» — тоже ответ; молчание им не является.
|
|
34
|
+
|
|
35
|
+
## Сначала задача, потом ветка
|
|
36
|
+
|
|
37
|
+
Заведение состоит из нескольких шагов: сама задача, номер в её заголовке, добавление в очередь,
|
|
38
|
+
начальное состояние. Очередь к репозиторию обычно не привязана, поэтому добавление само не
|
|
39
|
+
случается, и задача без него не видна ни в очереди, ни владельцу. Все шаги делает одна команда
|
|
40
|
+
— не рука.
|
|
41
|
+
|
|
42
|
+
Название задачи говорит, что не так, а не что сделать: PR потом переводит его в сделанное.
|
|
43
|
+
Номер в заголовок руками не пишется — он известен только после создания.
|
|
44
|
+
|
|
45
|
+
## Две задачи, которые чинятся одной правкой
|
|
46
|
+
|
|
47
|
+
Если по ходу выяснилось, что правка закрывает и соседнюю задачу, — это одна задача, а не две.
|
|
48
|
+
Слить их можно, пока правка не въехала в главную ветку: недостающее из поглощённой дописывается
|
|
49
|
+
в тело первой, и только потом поглощённая закрывается и снимается с очереди. Порядок важен —
|
|
50
|
+
удаление уносит с собой ссылки на неё из чужих тел.
|
|
51
|
+
|
|
52
|
+
После слияния ветки поглощения нет: она въехала, и откатывается целиком.
|
|
53
|
+
|
|
54
|
+
## Ветка заводится отдельным вызовом
|
|
55
|
+
|
|
56
|
+
Гард главной ветки разбирает текст команды и смотрит ветку на момент запуска, поэтому составная
|
|
57
|
+
команда отклоняется целиком — ветки в ней ещё нет:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
✗ git checkout -b <ветка> && git commit -m '…'
|
|
61
|
+
✓ git checkout -b <ветка>
|
|
62
|
+
✓ git commit -F -
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Имя ветки несёт номер задачи. Гард поставки разбирает его на месте и отбивает промах в форме до
|
|
66
|
+
первого коммита, а по номеру спрашивает очередь: задача должна существовать, быть открытой,
|
|
67
|
+
стоять в очереди и иметь исполнителя.
|
|
68
|
+
|
|
69
|
+
Имя без номера законно, пока ветка живёт локально — под пробу и разбор. PR с неё не откроется:
|
|
70
|
+
правка, доезжающая до главной ветки, начинается с задачи.
|
|
71
|
+
|
|
72
|
+
## Колонка задачи двигается вместе с работой
|
|
73
|
+
|
|
74
|
+
Ветка заведена — задача уже не в начальной колонке, а в работе. PR открыт — она ждёт разбора.
|
|
75
|
+
Оба перевода делает одна команда, вторым вызовом сразу за тем, который его вызвал.
|
|
76
|
+
|
|
77
|
+
Перевод не откладывается на потом: очередь читают между шагами, а не после них. Задача с
|
|
78
|
+
открытым PR, простоявшая в начальной колонке, всё это время выглядела нетронутой — и разбора за
|
|
79
|
+
неё никто не ждал.
|
|
80
|
+
|
|
81
|
+
## Коммит подписывается учётной записью машинной работы
|
|
82
|
+
|
|
83
|
+
Токен читается в переменную и не печатается; автор и коммиттер задаются переменными той же
|
|
84
|
+
команды. Правка общей настройки здесь не годится — она переписала бы подпись владельцу:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
TOKEN=$(tr -d '\n' < <файл с токеном>)
|
|
88
|
+
|
|
89
|
+
GIT_AUTHOR_NAME="<бот>" GIT_AUTHOR_EMAIL="<адрес бота>" \
|
|
90
|
+
GIT_COMMITTER_NAME="<бот>" GIT_COMMITTER_EMAIL="<адрес бота>" \
|
|
91
|
+
git commit -F -
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Заголовок — `тип(область): описание`, без точки в конце. Набор типов и областей задан
|
|
95
|
+
настройкой проверки заголовка.
|
|
96
|
+
|
|
97
|
+
## Документ едет тем же коммитом
|
|
98
|
+
|
|
99
|
+
Гард документов требует пару и называет её сам. Обход — строка в теле коммита, причина
|
|
100
|
+
обязательна:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
Docs-skip: правка только в сценариях хука, зеркала у него нет
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Номер задачи стоит в её заголовке и в заголовке PR
|
|
107
|
+
|
|
108
|
+
Форма одна на оба. Номер стоит в самом заголовке, а не только в теле: в списке PR тела не
|
|
109
|
+
видно. Тот же номер несёт и имя ветки — поэтому задача, ветка и PR читаются как одно.
|
|
110
|
+
|
|
111
|
+
Задача говорит, что не так; PR тем же номером отчитывается, что сделано. Инфинитив из задачи в
|
|
112
|
+
заголовок PR не переносится: «исправить» становится «исправлено».
|
|
113
|
+
|
|
114
|
+
Тип и область коммита в заголовок PR не идут: род правки и область уже видны метками.
|
|
115
|
+
|
|
116
|
+
## PR прикрепляется к задаче
|
|
117
|
+
|
|
118
|
+
Тело начинается со строки связи с задачей — по ней в очереди заполняется поле связанных PR.
|
|
119
|
+
Ревьювер, исполнитель и метки задаются той же командой, и PR без них не открывается.
|
|
120
|
+
|
|
121
|
+
Ревьювер — всегда владелец: без запроса разбора PR не показывается ему в очереди. Метки берутся
|
|
122
|
+
у задачи целиком — и род правки, и все её области; читаются они у задачи, а не выбираются по
|
|
123
|
+
памяти.
|
|
124
|
+
|
|
125
|
+
Строка связи обязательна: без неё PR не прикрепляется к задаче. Она же означает, что задача
|
|
126
|
+
закрывается целиком — половину задачи одним PR не выкатывают: у задачи одна ветка, и работа,
|
|
127
|
+
которая в неё не влезает, делится на задачи до того, как ветка заводится.
|
|
128
|
+
|
|
129
|
+
Тело перечитывается всякий раз, когда в ветку что-то влилось после публикации: отчёт утверждает
|
|
130
|
+
про дерево, а дерево с тех пор изменилось.
|
|
131
|
+
|
|
132
|
+
## Что проверяется до публикации PR
|
|
133
|
+
|
|
134
|
+
Проверок на самом PR нет: выкатка запускается пушем в главную ветку, и до слияния никто не
|
|
135
|
+
гоняет ничего. Линтеры и юниты снимает гейт пуша — ниже то, чего он не знает.
|
|
136
|
+
|
|
137
|
+
1. **В ветке только та правка, за которой её заводили** — сводка расхождения с главной веткой.
|
|
138
|
+
Чужой домен в списке файлов означает, что правка расползлась.
|
|
139
|
+
2. **Ни мока, ни подменённого ответа, ни отладочной строки** — расхождение читается целиком, а
|
|
140
|
+
не по именам файлов. На прод они уезжают молча и портят настоящие данные.
|
|
141
|
+
3. **Документ едет тем же коммитом.** Пару называет гард, но спек домена и правку его поведения
|
|
142
|
+
он не знает — это остаётся за автором.
|
|
143
|
+
4. **Проверки текстов и раскладки зелёные.**
|
|
144
|
+
5. **Все приложения собираются.** Гейт пуша сборку обычно не гоняет.
|
|
145
|
+
6. **Видимый текст заведён во всех локалях.**
|
|
146
|
+
7. **Правка вёрстки подтверждена замером**, а не взглядом, и снята при узком экране — паттерн
|
|
147
|
+
`browser-verification-measure`.
|
|
148
|
+
8. **Правка публичной разметки проверена на прод-сборке по всем локалям** — паттерн
|
|
149
|
+
`seo-verify`.
|
|
150
|
+
9. **Тело PR начинается строкой связи с задачей**, а метки, ревьювер и исполнитель стоят.
|
|
151
|
+
10. **Заголовок PR несёт номер задачи и называет её сделанной** — тем же номером, что у задачи
|
|
152
|
+
и в имени ветки.
|
|
153
|
+
11. **Очередь работ сходится.** Задача в очереди, с исполнителем и номером в заголовке; PR один
|
|
154
|
+
на задачу, и закрывает он её целиком.
|
|
155
|
+
|
|
156
|
+
Сразу после публикации задача переставляется в разбор, и сверка очереди прогоняется ещё раз: до
|
|
157
|
+
открытия PR колонку она не судит, а после открытия расхождение видит.
|
|
158
|
+
|
|
159
|
+
Сделанное рассуждением и сделанное замером в теле PR разводятся прямо: непроверенное, названное
|
|
160
|
+
проверенным, ревьювер принимает за проверенное.
|
|
161
|
+
|
|
162
|
+
## Частые промахи
|
|
163
|
+
|
|
164
|
+
- **Добавление в индекс нескольких путей не добавляет ничего, если хоть один путь не
|
|
165
|
+
существует.** Команда обрывается на первом промахе целиком, а следующая правка последнего
|
|
166
|
+
коммита уносит в него всё, что осталось в индексе. Состав коммита читается сразу после него,
|
|
167
|
+
а не на разборе PR.
|
|
168
|
+
- **Задача, заведённая мимо команды, в очередь не попадает и гардом не отбивается** — он
|
|
169
|
+
смотрит команду, а не задачу. Ловится это только сверкой очереди.
|
|
170
|
+
- **Исполнитель у задачи сам не проставляется** ни при заведении через веб, ни при добавлении в
|
|
171
|
+
очередь.
|
|
172
|
+
- **Колонка сама не двигается** ни от заведения ветки, ни от открытия PR: очередь ветки не
|
|
173
|
+
видит вовсе, а связь с PR заполняет только поле связанных PR.
|
|
174
|
+
- **Постраничный обход очереди через общий флаг уходит в повтор первой страницы** — курсор
|
|
175
|
+
берётся из ответа руками, а полнота сверяется с общим числом элементов.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-workflow-merge
|
|
3
|
+
kind: pattern
|
|
4
|
+
rule: git-workflow
|
|
5
|
+
description: Паттерн правила git-workflow. Брать, когда главная ветка вливается в ветку задачи и разрешается конфликт — порядок слияния, разбор конфликта по роду файла, сверка дописанного веткой с очередью работ, проверки после разрешения, перечитывание тела уже открытого PR. Не брать для заведения ветки, коммита и PR — это паттерн git-workflow-commit.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Вливание главной ветки в ветку задачи
|
|
9
|
+
|
|
10
|
+
Паттерн правила `git-workflow`. Что при этом должно быть верно — закон `{{lawsDir}}/delivery.md`.
|
|
11
|
+
|
|
12
|
+
## Когда брать
|
|
13
|
+
|
|
14
|
+
- PR отмечен конфликтующим, и его надо вернуть к сливаемому состоянию.
|
|
15
|
+
- Главная ветка ушла вперёд, и ветку задачи надо подтянуть до проверок.
|
|
16
|
+
- Коммит переносится отдельным выбором.
|
|
17
|
+
|
|
18
|
+
## Порядок
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
git fetch origin
|
|
22
|
+
git merge origin/<главная ветка> --no-edit
|
|
23
|
+
git diff --name-only --diff-filter=U # что встало конфликтом
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Список конфликтов читается целиком до первого разрешения: род файла решает приём, и разные
|
|
27
|
+
файлы одного слияния разрешаются по-разному.
|
|
28
|
+
|
|
29
|
+
| Что встало конфликтом | Как разрешается |
|
|
30
|
+
| --------------------- | ------------------------------------------------------------------------------ |
|
|
31
|
+
| код | ловушка правила `git-workflow` про сторону-удаление; после — проверка повторов |
|
|
32
|
+
| спек домена | сохранением обеих сторон — правило `spec-driven`; после — проверка спеков |
|
|
33
|
+
| накопительный список | признаком отбора — паттерн `doc-style-sweep` |
|
|
34
|
+
|
|
35
|
+
## Что дописала ветка, видно только от точки расхождения
|
|
36
|
+
|
|
37
|
+
Конфликтный маркер показывает место, а не правку: сторона ветки в нём — её допись вместе со
|
|
38
|
+
всем, что лежало в файле до неё.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git diff "$(git merge-base origin/<главная ветка> HEAD)" HEAD -- <файл>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Дописанное веткой сверяется с очередью работ, а не переносится по умолчанию
|
|
45
|
+
|
|
46
|
+
Раздел, который ветка дописала в накопительный список, к моменту слияния обычно уже стоит
|
|
47
|
+
задачей: ветка живёт неделями, а замеченный по ходу дефект заводится задачей сразу. Перенести
|
|
48
|
+
его второй раз — завести вторую запись об одной работе.
|
|
49
|
+
|
|
50
|
+
Когда задача несёт то же содержание, сторона ветки не переносится:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git checkout --theirs <файл> && git add <файл>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
При слиянии `--theirs` — влитая главная ветка, а `--ours` — ветка задачи; при перебазировании
|
|
57
|
+
стороны меняются местами. Взятая не та сторона стирает работу молча.
|
|
58
|
+
|
|
59
|
+
## Проверки после разрешения
|
|
60
|
+
|
|
61
|
+
Конфликт в текстах кода не задевает, и зелёная сборка про него ничего не говорит:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
grep -rn '^<<<<<<< \|^>>>>>>> ' --exclude-dir=node_modules --exclude-dir=.git .
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Следом гоняются проверки текстов, раскладки, повторов и очереди работ, а если конфликт задел
|
|
68
|
+
хуки — их сценарии. Коммит слияния подписывается так же, как любой другой, — паттерн
|
|
69
|
+
`git-workflow-commit`. После пуша состояние читается у самого PR, а не по своему дереву.
|
|
70
|
+
|
|
71
|
+
## Тело открытого PR перечитывается после слияния
|
|
72
|
+
|
|
73
|
+
Отчёт описывал дерево на день, когда его написали. Вливание главной ветки меняет то, о чём он
|
|
74
|
+
утверждает: тело говорит про записи, которые главная ветка к тому времени уже разобрала.
|
|
75
|
+
|
|
76
|
+
## Частые промахи
|
|
77
|
+
|
|
78
|
+
- «Сохранить обе стороны» применено ко всем файлам одинаково: в спеке это верно, в коде и в
|
|
79
|
+
накопительном списке — нет.
|
|
80
|
+
- Сторона ветки перенесена без сверки с очередью работ: одна работа стала двумя записями.
|
|
81
|
+
- После разрешения прогнана сборка, а проверки текстов — нет: конфликта в них сборке не видно.
|
|
82
|
+
- Тело PR оставлено прежним: ревьювер читает утверждение о дереве, которого больше нет.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-workflow-migration
|
|
3
|
+
kind: pattern
|
|
4
|
+
rule: git-workflow
|
|
5
|
+
description: Паттерн правила git-workflow. Брать при правке схемы хранилища и каталога миграций — прогон цепочки на одноразовом хранилище, написание файла миграции разницей, догон локального хранилища. Не брать для коммита и PR — это паттерн git-workflow-commit.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Миграция и прогон цепочки
|
|
9
|
+
|
|
10
|
+
Паттерн правила `git-workflow`. Что при этом должно быть верно — закон `{{lawsDir}}/delivery.md`.
|
|
11
|
+
|
|
12
|
+
## Когда брать
|
|
13
|
+
|
|
14
|
+
- Правится схема хранилища.
|
|
15
|
+
- Заводится или переименовывается каталог миграции.
|
|
16
|
+
- Ветка с новой миграцией готовится к слиянию.
|
|
17
|
+
|
|
18
|
+
## Цепочка гоняется на одноразовом хранилище
|
|
19
|
+
|
|
20
|
+
Линтеры, тесты и сборки порядок миграций не трогают вовсе, а проверка соответствия схемы идёт
|
|
21
|
+
уже после слияния. Поэтому ветка прогоняется до слияния на пустом хранилище:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
docker run -d --rm --name <проба> -e <пароль> -p <порт>:<порт> <образ хранилища>
|
|
25
|
+
docker exec <проба> <проверка готовности> # накат до готовности падает на соединении
|
|
26
|
+
<адрес хранилища> npx <инструмент> migrate deploy
|
|
27
|
+
<адрес хранилища> npx <инструмент> migrate diff --from-config-datasource --to-schema <схема> --exit-code
|
|
28
|
+
docker stop <проба>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Одноразовое хранилище, а не своё: гард запросов отбивает схемные команды, и завести базу под
|
|
32
|
+
проверку иначе нечем. Адрес ставится префиксом самой команды — экспорт между вызовами не живёт.
|
|
33
|
+
|
|
34
|
+
## Файл миграции пишется тем же хранилищем
|
|
35
|
+
|
|
36
|
+
Команда разработчика для миграций не запускается: любое расхождение состояния она лечит
|
|
37
|
+
предложением сбросить хранилище, а в локальном лежат данные владельца. Файл берётся разницей
|
|
38
|
+
между накатанной цепочкой и схемой.
|
|
39
|
+
|
|
40
|
+
Каталог заводится **после** наката цепочки: пустой каталог, попавший в накат, помечается
|
|
41
|
+
применённым, и его содержимое на это хранилище уже не встанет.
|
|
42
|
+
|
|
43
|
+
## Локальное хранилище догоняет ветку
|
|
44
|
+
|
|
45
|
+
Переименованная миграция остаётся в нём под прежним именем, и накат падает на «объект уже
|
|
46
|
+
существует». Состояние правится отметкой о применении, повторный накат его не чинит.
|
|
47
|
+
|
|
48
|
+
## Частые промахи
|
|
49
|
+
|
|
50
|
+
- Метку времени ставит момент создания, а порядок применения лексикографический: миграция из
|
|
51
|
+
ветки, начатой раньше, встаёт перед той, от которой зависит. На существующем хранилище это
|
|
52
|
+
незаметно — падает только накат с нуля.
|
|
53
|
+
- Флаги инструмента не те, что в примерах из сети, и на неизвестный флаг он печатает справку, а
|
|
54
|
+
не строку ошибки. Какие флаги есть сейчас, смотрят в его собственной справке.
|
|
55
|
+
- Запись в боевое хранилище запрещена совсем: схема меняется миграцией через выкатку, данные —
|
|
56
|
+
через интерфейс.
|
|
57
|
+
- Строки адресуются по первичному ключу, а не по маске: удаление по маске уносит вместе с
|
|
58
|
+
пробными записями настоящие.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-workflow-restart
|
|
3
|
+
kind: pattern
|
|
4
|
+
rule: git-workflow
|
|
5
|
+
description: Паттерн правила git-workflow. Брать при ручном перезапуске прода — после правки окружения прода, при разборе выкатки, при подъёме контейнера на сервере. Команда с явным тегом образа по хешу коммита, способ узнать выкаченный хеш и чем сверять результат. Не брать для коммита и миграций — это паттерны git-workflow-commit и git-workflow-migration.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Ручной перезапуск прода
|
|
9
|
+
|
|
10
|
+
Паттерн правила `git-workflow`. Что при этом должно быть верно — закон `{{lawsDir}}/delivery.md`.
|
|
11
|
+
|
|
12
|
+
## Когда брать
|
|
13
|
+
|
|
14
|
+
- Правилось окружение прода, и контейнер надо поднять заново.
|
|
15
|
+
- Разбирается, что именно сейчас выкачено.
|
|
16
|
+
- Контейнер поднимается на сервере руками, мимо выкатки по слиянию.
|
|
17
|
+
|
|
18
|
+
## Команда обязана нести хеш коммита
|
|
19
|
+
|
|
20
|
+
Выкатка ставит образы по хешу коммита. Без явного тега подъём контейнера подставляет умолчание
|
|
21
|
+
«последний», а оно в реестре отстаёт от главной ветки — прод молча откатывается на старый образ
|
|
22
|
+
и при этом отвечает:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
IMAGE_TAG='<хеш>' docker compose -f <состав прода> --env-file <окружение> pull <службы>
|
|
26
|
+
IMAGE_TAG='<хеш>' docker compose -f <состав прода> --env-file <окружение> up -d --no-build --remove-orphans
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Хеш берётся до перезапуска
|
|
30
|
+
|
|
31
|
+
У выкаченного контейнера или у последнего слияния в главную ветку:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
docker inspect <контейнер> --format '{{.Config.Image}}'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Сверка идёт по журналу, а не по коду ответа
|
|
38
|
+
|
|
39
|
+
Подмена образа видна только по пропавшим строкам нового кода: сводка запуска из журнала
|
|
40
|
+
исчезает, хотя строка «приложение поднялось» остаётся на месте. После перезапуска — тот же
|
|
41
|
+
осмотр образа и наличие ожидаемых строк в журнале.
|
|
42
|
+
|
|
43
|
+
## Частые промахи
|
|
44
|
+
|
|
45
|
+
- Вывод «прод жив, значит выкатилось» — код ответа подмену образа не показывает.
|
|
46
|
+
- Переменные окружения, секреты и записи имён ставятся **до** слияния: слияние выкатывает
|
|
47
|
+
сразу, и ветка, зависящая от новой переменной, встаёт на проде до того, как переменную
|
|
48
|
+
заведут.
|
|
49
|
+
- Заход на сервер в автоматическом режиме режется правилом — нужен обычный.
|