@rt-tools/agent-kit 0.11.0 → 0.13.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/assets/checks/board-runs.github.mjs +87 -0
- package/assets/checks/board.github.mjs +0 -40
- package/assets/checks/check-board.github.mjs +39 -8
- package/assets/checks/check-file-size.mjs +19 -4
- package/assets/checks/check-schema-drift.mjs +28 -5
- package/assets/checks/check-state-next.mjs +10 -2
- package/assets/checks/rt-kit-checks.config.mjs +28 -2
- package/assets/commands/feedback.md +8 -0
- package/assets/defaults/project.sh +59 -6
- package/assets/defaults/turn-map.md +8 -6
- package/assets/hooks/browser-guard-device-id.sh +3 -1
- package/assets/hooks/browser-guard-no-asking.sh +3 -1
- package/assets/hooks/browser-guard-no-other-drivers.sh +6 -4
- package/assets/hooks/browser-guard-require-select.sh +4 -2
- package/assets/hooks/claim-guard.sh +3 -1
- package/assets/hooks/conscience-guard.sh +3 -1
- package/assets/hooks/dev-server-guard.sh +6 -4
- package/assets/hooks/dispatch.sh +69 -0
- package/assets/hooks/docs-guard.sh +6 -4
- package/assets/hooks/exam-guard.sh +5 -3
- package/assets/hooks/git-guard-delivery-folder.sh +99 -0
- package/assets/hooks/git-guard-delivery-signature.sh +10 -4
- package/assets/hooks/git-guard-delivery.sh +58 -74
- package/assets/hooks/git-guard-main.sh +6 -4
- package/assets/hooks/git-guard-push-tests.sh +8 -6
- package/assets/hooks/grill-gate.sh +4 -2
- package/assets/hooks/handoff-entry-guard.sh +4 -2
- package/assets/hooks/handoff-write.sh +27 -6
- package/assets/hooks/hook-input.sh +77 -0
- package/assets/hooks/lint-after-edit.sh +5 -3
- package/assets/hooks/override-write-guard.sh +107 -0
- package/assets/hooks/postmortem-guard.sh +3 -1
- package/assets/hooks/proposal-guard.sh +3 -1
- package/assets/hooks/prose-style-guard.sh +5 -3
- package/assets/hooks/qa-dataid-guard.sh +4 -2
- package/assets/hooks/rerun-guard.sh +6 -4
- package/assets/hooks/reuse-first-guard.sh +5 -3
- package/assets/hooks/rule-article.sh +99 -0
- package/assets/hooks/rule-source-guard.sh +126 -0
- package/assets/hooks/skill-gate-rearm.sh +3 -1
- package/assets/hooks/skill-gate.sh +23 -2
- package/assets/hooks/skill-loaded.sh +3 -1
- package/assets/hooks/sql-guard-request.sh +2 -1
- package/assets/hooks/sql-guard.sh +4 -2
- package/assets/hooks/task-flow-guard.sh +24 -4
- package/assets/hooks/turn-exit-guard.sh +59 -17
- package/assets/hooks/waiting-turn-guard.sh +3 -1
- package/assets/hooks/window-fill-guard.sh +6 -4
- package/assets/laws/work-conduct.md +5 -9
- package/assets/patterns/dependencies-upgrade.md +1 -1
- package/assets/patterns/doc-style-write.md +3 -3
- package/assets/patterns/git-workflow-commit.azure.md +2 -202
- package/assets/patterns/git-workflow-commit.github.md +2 -258
- package/assets/patterns/git-workflow-commit.gitlab.md +1 -217
- package/assets/patterns/git-workflow-docker.md +3 -3
- package/assets/patterns/git-workflow-merge.md +3 -2
- package/assets/patterns/git-workflow-migration.md +3 -3
- package/assets/patterns/git-workflow-pr.azure.md +224 -0
- package/assets/patterns/git-workflow-pr.github.md +280 -0
- package/assets/patterns/git-workflow-pr.gitlab.md +240 -0
- package/assets/patterns/git-workflow-restart.md +3 -3
- package/assets/patterns/git-workflow-secrets.md +3 -3
- package/assets/patterns/task-flow-archive.md +195 -0
- package/assets/patterns/task-flow-close.md +72 -240
- package/assets/patterns/task-flow-handoff.md +4 -4
- package/assets/patterns/task-flow-resume.md +5 -3
- package/assets/pitfalls/agent-kit.md +80 -0
- package/assets/pitfalls/doc-style.md +80 -0
- package/assets/pitfalls/git-workflow.azure.md +50 -0
- package/assets/pitfalls/git-workflow.github.md +78 -0
- package/assets/pitfalls/git-workflow.gitlab.md +49 -0
- package/assets/pitfalls/spec-driven.md +36 -0
- package/assets/pitfalls/styling-bem.md +45 -0
- package/assets/pitfalls/task-flow.md +62 -0
- package/assets/pitfalls/testing.md +70 -0
- package/assets/rules/deploy-flow.azure.md +114 -0
- package/assets/rules/deploy-flow.github.md +122 -0
- package/assets/rules/deploy-flow.gitlab.md +116 -0
- package/assets/rules/doc-style.md +25 -76
- package/assets/rules/git-workflow.azure.md +6 -92
- package/assets/rules/git-workflow.github.md +20 -128
- package/assets/rules/git-workflow.gitlab.md +6 -93
- package/assets/rules/spec-driven.md +39 -30
- package/assets/rules/styling-bem.md +20 -39
- package/assets/rules/task-flow.md +56 -222
- package/assets/rules/testing.md +3 -64
- package/assets/rules/turn-conduct.md +210 -0
- package/assets/rules/typescript-conventions.md +15 -0
- package/assets/skills/agent-kit.md +67 -89
- package/assets/templates/pitfalls.md +10 -0
- package/assets/templates/proposal.md +16 -1
- package/assets/templates/rule.md +5 -3
- package/bin/agent-kit.d.ts.map +1 -1
- package/bin/agent-kit.js +1 -42
- package/bin/agent-kit.js.map +1 -1
- package/lib/assets.d.ts.map +1 -1
- package/lib/assets.js +6 -1
- package/lib/assets.js.map +1 -1
- package/lib/cascade.d.ts.map +1 -1
- package/lib/cascade.js +19 -1
- package/lib/cascade.js.map +1 -1
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +1 -0
- package/lib/commands.js.map +1 -1
- package/lib/config.d.ts +16 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +8 -0
- package/lib/config.js.map +1 -1
- package/lib/hooks-map.d.ts +13 -0
- package/lib/hooks-map.d.ts.map +1 -1
- package/lib/hooks-map.js +33 -1
- package/lib/hooks-map.js.map +1 -1
- package/lib/proposals.d.ts +5 -1
- package/lib/proposals.d.ts.map +1 -1
- package/lib/proposals.js +74 -5
- package/lib/proposals.js.map +1 -1
- package/lib/ship.d.ts +1 -2
- package/lib/ship.d.ts.map +1 -1
- package/lib/ship.js +0 -54
- package/lib/ship.js.map +1 -1
- package/lib/shipment.d.ts.map +1 -1
- package/lib/shipment.fixture.d.ts +39 -0
- package/lib/shipment.fixture.d.ts.map +1 -0
- package/lib/shipment.fixture.js +99 -0
- package/lib/shipment.fixture.js.map +1 -0
- package/lib/shipment.js +59 -7
- package/lib/shipment.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.13.0.tgz +0 -0
- package/assets/commands/agent-kit-digest.md +0 -89
- package/assets/commands/rules-review.md +0 -98
- package/assets/patterns/cargo-triage-mark.md +0 -119
- package/assets/rules/cargo-triage.md +0 -126
- package/lib/cargo-state.d.ts +0 -62
- package/lib/cargo-state.d.ts.map +0 -1
- package/lib/cargo-state.js +0 -118
- package/lib/cargo-state.js.map +0 -1
- package/rt-tools-agent-kit-0.11.0.tgz +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: git-workflow
|
|
3
3
|
kind: rule
|
|
4
4
|
law: delivery
|
|
5
|
-
description: Правило под «Закон о поставке» для дерева в Azure DevOps. Брать на заведение задачи, ветки, коммит, пуш, создание PR, слияние, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет рабочий элемент как начало работы, его состояние как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав PR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-
|
|
5
|
+
description: Правило под «Закон о поставке» для дерева в Azure DevOps. Брать на заведение задачи, ветки, коммит, пуш, создание PR, слияние, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет рабочий элемент как начало работы, его состояние как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав PR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-pr, git-workflow-merge. Выкатка, образы и миграции — правило deploy-flow.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Поставка — как это устроено здесь
|
|
@@ -12,6 +12,9 @@ description: Правило под «Закон о поставке» для д
|
|
|
12
12
|
учётная запись машинной работы и области коммита — при этом дереве, в `implementation.md`
|
|
13
13
|
рядом: их не угадать, и общими они не бывают.
|
|
14
14
|
|
|
15
|
+
**Холодная часть:** `pitfalls.md` рядом — ловушки, грабли, на которые уже наступали.
|
|
16
|
+
Грузится по требованию, а не вместе с правилом.
|
|
17
|
+
|
|
15
18
|
## Как это называется здесь
|
|
16
19
|
|
|
17
20
|
| В законе | Здесь |
|
|
@@ -23,9 +26,6 @@ description: Правило под «Закон о поставке» для д
|
|
|
23
26
|
| состояние задачи в очереди работ | поле `State` рабочего элемента: `New` у заведённого, `Active` у взятого в работу, `Resolved` у ждущего разбора. Набор состояний зависит от процесса проекта и назван в `implementation.md`; закрытая задача уходит из очереди слиянием |
|
|
24
27
|
| PR о задаче | заголовок PR `[<номер>] <Что сделано>` — тот же номер, что у рабочего элемента, и его название, переведённое в сделанное; тип и область коммита сюда не идут |
|
|
25
28
|
| обсуждение правки | разбор PR: ревьювер — владелец репозитория, исполнитель — учётная запись машинной работы, метки — те же, что у рабочего элемента |
|
|
26
|
-
| попадание правки в главную ветку | слияние PR; оно же запускает выкатку — `azure-pipelines.yml` |
|
|
27
|
-
| образ того коммита | `IMAGE_TAG=<sha>` в командах `docker compose` на сервере |
|
|
28
|
-
| изменение хранилища | миграция в `prisma/migrations/<метка>_<имя>/` |
|
|
29
29
|
| запись о правке | коммит формата `type(scope): description` — типы `feat`, `fix`, `refactor`, `docs`, `style`, `test`, `chore`, `perf`; области — в `implementation.md` |
|
|
30
30
|
| автор машинной работы | отдельная учётная запись; её имя и место токена — в `implementation.md`. Токен лежит вне репозитория |
|
|
31
31
|
|
|
@@ -128,11 +128,6 @@ flowchart TD
|
|
|
128
128
|
не нужна вовсе, а заведённая живёт своей жизнью: состояния под неё нет, из очереди она не
|
|
129
129
|
уходит и остаётся в ней после слияния навсегда. Находит такие сверка очереди — строкой на
|
|
130
130
|
каждую.
|
|
131
|
-
- **Конвейер судит по составу правки, а не гоняет всё подряд.** Шаги, которым нечего проверять,
|
|
132
|
-
пропускаются по признаку, посчитанному от главной ветки: ветка, не тронувшая ни строки кода,
|
|
133
|
-
не поднимает стенда, не снимает кадров и не собирает образов. Признак объявляется переменной
|
|
134
|
-
задания и считается один раз, а не переспрашивается в каждом условии. Пропущенный шаг виден в
|
|
135
|
-
прогоне пропущенным — молча выпавший читается как пройденный.
|
|
136
131
|
- **Отставшее состояние находится сверкой очереди, а не глазами.** Сверка судит состояние по
|
|
137
132
|
PR в обе стороны: открытый PR при элементе не в разборе и разбор без открытого PR — оба
|
|
138
133
|
расхождения. Момента, когда задачу берут в работу, ей не видно: ветки на доске нет.
|
|
@@ -144,36 +139,6 @@ flowchart TD
|
|
|
144
139
|
исполнитель открывает карточку раньше, чем замысел эпика, а планирует по замыслу. Одна пометка без
|
|
145
140
|
другой лжёт молча, поэтому сверка очереди судит пару в обе стороны. Помечается только то, что
|
|
146
141
|
законно не делится: пометка объёма правом делить не становится.
|
|
147
|
-
- **Слияние в главную ветку выкатывает прод.** Фильтры путей конвейера покрывают документы
|
|
148
|
-
отдельно, поэтому переменные окружения, секреты и записи имён ставятся до слияния, а не
|
|
149
|
-
после.
|
|
150
|
-
- **Признак режима объявлен в образе, а не только в составе прода.** Значение, заданное
|
|
151
|
-
составом, действует лишь на контейнер, поднятый этим составом; ручной прогон того же образа
|
|
152
|
-
идёт с пустым значением, а пусто здесь означает локалхост — со всеми отладочными
|
|
153
|
-
умолчаниями, которые он разрешает. Умолчание образа задаётся в самом образе.
|
|
154
|
-
- **Образы выкатываются по sha коммита, а не по метке «последний».** Метка в реестре отстаёт
|
|
155
|
-
от главной ветки, и прод молча возвращается к прежней версии, продолжая отвечать.
|
|
156
|
-
- **Выкатка убирает за собой старые образы, оставляя три последних sha.** Помеченный sha образ
|
|
157
|
-
висячим не бывает никогда, и чистка висячего его не касается: за полгода они съедают диск
|
|
158
|
-
сервера целиком. Три sha — это глубина отката, и меньше брать нельзя: поломка, замеченная
|
|
159
|
-
через две выкатки, откатывается уже некуда.
|
|
160
|
-
- **Описание прода правится вместе с составом прода.** Устройство, путь запроса, гейты и
|
|
161
|
-
бэкапы описаны текстами вне слоёв правил, и ни линтер, ни сборка их не читают: расхождение
|
|
162
|
-
копится молча, а читают эти тексты как действующие. Пару стережёт гард документов.
|
|
163
|
-
- **Правка конвейера прогоняется до слияния ручным запуском.** Конвейер запускается на любой
|
|
164
|
-
ветке, а задание выкатки прибито условием к главной: прогон ради проверки доходит до сборок и
|
|
165
|
-
там кончается. Прогон команд задания на своей машине его не покрывает: он проверяет команды,
|
|
166
|
-
а не файл конвейера, — верность самого файла читается только по списку прогонов после пуша.
|
|
167
|
-
- **PR проверяется до слияния тем же конвейером, что и главная ветка.** Проверки и сборки
|
|
168
|
-
образов идут на конвейере проверки PR, выкатка — нет: её держит условие по главной ветке у
|
|
169
|
-
своего задания, а образ PR в реестр не уезжает.
|
|
170
|
-
- **Расхождение прода с главной веткой видно сверкой очереди работ.** Рабочий элемент уходит из
|
|
171
|
-
очереди слиянием, но слияние — ещё не прод: отказавшая выкатка не трогает ни элемент, ни его
|
|
172
|
-
состояние, и заметить её неоткуда. Сверка спрашивает последний прогон главной ветки и судит
|
|
173
|
-
только завершённый: идущий ещё может кончиться выкаткой.
|
|
174
|
-
- **Цепочка миграций прогоняется с пустого хранилища до слияния.** Порядок применения
|
|
175
|
-
лексикографический по имени каталога, а метку времени ставит момент создания: миграция из
|
|
176
|
-
ветки, начатой раньше, встаёт перед той, от которой зависит.
|
|
177
142
|
- **Документ едет в том же коммите, что и правка.** Обход — строка `Docs-skip: <причина>` в
|
|
178
143
|
теле коммита; пустая причина не принимается.
|
|
179
144
|
- **Заголовок коммита сверяется с форматом на месте.** Разобранный по типу и области
|
|
@@ -219,10 +184,6 @@ flowchart TD
|
|
|
219
184
|
репозитории сценария наследует общий конфиг: если включена подпись, git идёт в агент ключей,
|
|
220
185
|
а заблокированный агент роняет весь набор — со стороны это выглядит сломанным гардом. Автор,
|
|
221
186
|
почта и подпись передаются флагами `-c` прямо в команду.
|
|
222
|
-
- **Расхождение миграций со схемой меряется на теневом хранилище, а не на том, где работает
|
|
223
|
-
тот, кто пушит.** Оно законно несёт след любой недоделанной ветки, и сверка с ним держала бы
|
|
224
|
-
чужую правку. Гейт и выкатка зовут одну и ту же проверку — иначе «сошлось» станет значить в
|
|
225
|
-
двух местах разное.
|
|
226
187
|
|
|
227
188
|
## Чего из закона здесь нет
|
|
228
189
|
|
|
@@ -249,54 +210,7 @@ flowchart TD
|
|
|
249
210
|
|
|
250
211
|
## Паттерны
|
|
251
212
|
|
|
252
|
-
- `git-workflow-commit` — рабочий элемент, ветка,
|
|
213
|
+
- `git-workflow-commit` — рабочий элемент, ветка, коммит и пуш от учётной записи машинной работы.
|
|
214
|
+
- `git-workflow-pr` — открытие PR, черновик и его снятие, тело, ревьювер, привязка к элементу.
|
|
253
215
|
работы.
|
|
254
216
|
- `git-workflow-merge` — главная ветка влита в ветку задачи, конфликт разобран.
|
|
255
|
-
- `git-workflow-migration` — правка схемы хранилища и её миграций.
|
|
256
|
-
- `git-workflow-restart` — ручной перезапуск прода.
|
|
257
|
-
- `git-workflow-docker` — образы на своей машине: демон, реестр, сборка под платформу сервера.
|
|
258
|
-
- `git-workflow-secrets` — ключи внешних служб: где лежат, как заводятся, что говорит их состояние.
|
|
259
|
-
|
|
260
|
-
## Ловушки
|
|
261
|
-
|
|
262
|
-
- **Одна работа — одна задача, сколько бы файлов она ни задела.** Числа, за которым правка
|
|
263
|
-
становится вторым рабочим элементом, здесь нет: делится то, что придётся откатывать порознь.
|
|
264
|
-
Сплошная правка текстов дерева была заведена тремя задачами «по объёму» — пришлось стирать
|
|
265
|
-
два рабочих элемента, закрывать два PR и переносить коммиты по одному с двумя конфликтами.
|
|
266
|
-
Одна из трёх не дала коммита вовсе: правка тел уже заведённых задач веткой не бывает и задачей
|
|
267
|
-
под ветку тоже.
|
|
268
|
-
- **Рабочий элемент заводится командой, а не вызовами подряд.** Доска показывает элементы своей
|
|
269
|
-
области и итерации, и заведённый мимо них в очереди работ не виден: со стороны это выглядит
|
|
270
|
-
так же, как незаведённый. Команда заведения ставит все поля разом — род, состояние,
|
|
271
|
-
исполнителя, область и итерацию, — и печатает готовую строку заведения ветки. Замеченный по
|
|
272
|
-
ходу дефект проходит тот же путь.
|
|
273
|
-
- **Ветка заводится вторым вызовом, а не тем же.** Гард главной ветки отклоняет составную
|
|
274
|
-
«создать ветку и сразу коммитить» целиком: ветки в момент разбора ещё нет.
|
|
275
|
-
- **Сторона конфликта бывает удалением, и «сохранить обе стороны» заводит второе объявление.**
|
|
276
|
-
Главная ветка снимает объявление, потому что символ переехал, — в конфликте это выглядит как
|
|
277
|
-
сторона, которая ничего не дописала. Разбирается чтением версии главной ветки целиком, а не по
|
|
278
|
-
хунку, и сверяется проверкой повторов: обе копии сами по себе исправны, сборка и линт зелёные.
|
|
279
|
-
- **Учётная запись для пуша и автор PR выбираются отдельно.** Если пушить пришлось из-под другой
|
|
280
|
-
записи, на следующий вызов это не переносится: PR открывают токеном учётной записи машинной
|
|
281
|
-
работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
|
|
282
|
-
смена записи ради пуша утекла в публикацию — PR вышел от владельца.
|
|
283
|
-
- **Невалидный файл конвейера виден прогоном нулевой длительности сразу после пуша.** Прогон
|
|
284
|
-
заводится и кончается на разборе файла, не начав ни одного задания: в списке он стоит
|
|
285
|
-
отказом, а внутри нет ни задания, ни лога — читается только длительность. Поэтому список
|
|
286
|
-
прогонов ветки смотрится тем же движением, что и пуш: `az pipelines runs list` по своей
|
|
287
|
-
ветке.
|
|
288
|
-
- **`online` у агента на своей машине означает запущенный процесс, а не работающий конвейер.**
|
|
289
|
-
Две стороны сходятся отдельно: требования заданий и возможности самого агента в его пуле.
|
|
290
|
-
Пока пересечения нет, агент стоит `online` и не берёт ничего, а задания ждут размещённого
|
|
291
|
-
пула — по состоянию это выглядит настроенным. Владельцу называют выполненное задание с его
|
|
292
|
-
номером, а не строку состояния.
|
|
293
|
-
- **Вход в реестр образов из агента, запущенного службой, отказывает молча.** Служба идёт без
|
|
294
|
-
сеанса пользователя, а клиент реестра уходит в системный помощник хранения ключей и получает
|
|
295
|
-
отказ во взаимодействии — задание падает до сборки. Свой каталог настроек с пустым помощником
|
|
296
|
-
не спасает: клиент переписывает пустое значение обратно сам. Готовые команды — паттерн
|
|
297
|
-
`git-workflow-docker`.
|
|
298
|
-
- **Новое рабочее дерево получает только то, что лежит в индексе.** `git worktree add`
|
|
299
|
-
разворачивает коммит, а настройки, ключи, локальные разрешения и зависимости в коммит не
|
|
300
|
-
входят: свежее дерево выглядит готовым и упирается в нехватку не сразу, а на первом гарде,
|
|
301
|
-
которому нужен ключ. Что именно переносится руками, названо списком в компаньоне правила, и
|
|
302
|
-
список пополняется тем же движением, которым заводится новый файл вне индекса.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: git-workflow
|
|
3
3
|
kind: rule
|
|
4
4
|
law: delivery
|
|
5
|
-
description: Правило под «Закон о поставке» для дерева на GitHub. Брать на заведение задачи, ветки, коммит, пуш, создание PR, мерж, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет задачу на борде как начало работы, колонку задачи как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав PR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-
|
|
5
|
+
description: Правило под «Закон о поставке» для дерева на GitHub. Брать на заведение задачи, ветки, коммит, пуш, создание PR, мерж, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет задачу на борде как начало работы, колонку задачи как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав PR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-pr, git-workflow-merge. Выкатка, образы и миграции — правило deploy-flow.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Поставка — как это устроено здесь
|
|
@@ -12,6 +12,9 @@ description: Правило под «Закон о поставке» для д
|
|
|
12
12
|
учётная запись машинной работы и области коммита — при этом дереве, в `implementation.md`
|
|
13
13
|
рядом: их не угадать, и общими они не бывают.
|
|
14
14
|
|
|
15
|
+
**Холодная часть:** `pitfalls.md` рядом — ловушки, грабли, на которые уже наступали.
|
|
16
|
+
Грузится по требованию, а не вместе с правилом.
|
|
17
|
+
|
|
15
18
|
## Как это называется здесь
|
|
16
19
|
|
|
17
20
|
| В законе | Здесь |
|
|
@@ -24,9 +27,6 @@ description: Правило под «Закон о поставке» для д
|
|
|
24
27
|
| состояние задачи в очереди работ | колонка борды — поле «Status»: заведённая, взятая в работу, ждущая разбора. Имена колонок — в `implementation.md`; закрытая задача уходит из очереди мержем, а не переводом в последнюю колонку |
|
|
25
28
|
| PR о задаче | заголовок PR `[<КЛЮЧ>-<номер>] <Что сделано>` — тот же номер, что у задачи, и её название, переведённое в сделанное; тип и область коммита сюда не идут |
|
|
26
29
|
| обсуждение правки | разбор PR: ревьювер — владелец репозитория, исполнитель — учётная запись машинной работы, метки — те же, что у задачи |
|
|
27
|
-
| попадание правки в главную ветку | мерж PR; он же запускает выкатку — `.github/workflows/deploy.yml` |
|
|
28
|
-
| образ того коммита | `IMAGE_TAG=<sha>` в командах `docker compose` на сервере |
|
|
29
|
-
| изменение хранилища | миграция в `prisma/migrations/<метка>_<имя>/` |
|
|
30
30
|
| запись о правке | коммит формата `type(scope): description` — типы `feat`, `fix`, `refactor`, `docs`, `style`, `test`, `chore`, `perf`; области — в `implementation.md` |
|
|
31
31
|
| автор машинной работы | отдельная учётная запись; её имя и место токена — в `implementation.md`. Токен лежит вне репозитория |
|
|
32
32
|
|
|
@@ -123,11 +123,6 @@ flowchart TD
|
|
|
123
123
|
под неё нет, из очереди она не уходит и остаётся в ней после слияния навсегда. Заводится она
|
|
124
124
|
либо встроенным правилом борды, либо рукой; и то и другое выключается, а накопившееся
|
|
125
125
|
снимается. Находит их сверка очереди — строкой на каждую.
|
|
126
|
-
- **Конвейер судит по составу правки, а не гоняет всё подряд.** Шаги, которым нечего проверять,
|
|
127
|
-
пропускаются по признаку, посчитанному от главной ветки: ветка, не тронувшая ни строки кода,
|
|
128
|
-
не поднимает стенда, не снимает кадров и не собирает образов. Признак считается один раз и
|
|
129
|
-
объявляется выводом шага, а не переспрашивается в каждом условии. Пропущенный шаг виден в
|
|
130
|
-
прогоне пропущенным — молча выпавший читается как пройденный.
|
|
131
126
|
- **Отставшая колонка находится сверкой очереди, а не глазами.** Сверка судит колонку по
|
|
132
127
|
PR в обе стороны: открытый PR при задаче не в разборе и разбор без открытого PR — оба
|
|
133
128
|
расхождения. Момента, когда задачу берут в работу, ей не видно: ветки на борде нет.
|
|
@@ -139,36 +134,6 @@ flowchart TD
|
|
|
139
134
|
исполнитель открывает карточку раньше, чем замысел эпика, а планирует по замыслу. Одна пометка без
|
|
140
135
|
другой лжёт молча, поэтому сверка очереди судит пару в обе стороны. Помечается только то, что
|
|
141
136
|
законно не делится: пометка объёма правом делить не становится.
|
|
142
|
-
- **Мерж в главную ветку выкатывает прод.** Исключения по путям покрывают только документы,
|
|
143
|
-
поэтому переменные окружения, секреты и записи имён ставятся до мержа, а не после.
|
|
144
|
-
- **Признак режима объявлен в образе, а не только в составе прода.** Значение, заданное
|
|
145
|
-
составом, действует лишь на контейнер, поднятый этим составом; ручной прогон того же образа
|
|
146
|
-
идёт с пустым значением, а пусто здесь означает локалхост — со всеми отладочными
|
|
147
|
-
умолчаниями, которые он разрешает. Умолчание образа задаётся в самом образе.
|
|
148
|
-
- **Образы выкатываются по sha коммита, а не по метке «последний».** Метка в реестре отстаёт
|
|
149
|
-
от главной ветки, и прод молча возвращается к прежней версии, продолжая отвечать.
|
|
150
|
-
- **Убирает за собой и та машина, которая образы собирает.** Отбор у обеих один — своё имя
|
|
151
|
-
реестра, три последних sha, поднятые контейнеры остаются, — и зовётся он одним сценарием:
|
|
152
|
-
разойдясь, две чистки начали бы оставлять разное, а заметить это нечем. Отличаются они
|
|
153
|
-
хвостом: сервер снимает следом висячие слои и кэш сборки, машина сборки оставляет их себе,
|
|
154
|
-
иначе каждая сборка идёт как первая. Чистка на сборке не ждёт мержа: образ ветки занимает
|
|
155
|
-
столько же места, в реестр не уезжает вовсе и точкой отката не бывает.
|
|
156
|
-
- **Выкатка убирает за собой старые образы, оставляя три последних sha.** Помеченный sha образ
|
|
157
|
-
висячим не бывает никогда, и чистка висячего его не касается: за полгода они съедают диск
|
|
158
|
-
сервера целиком. Три sha — это глубина отката, и меньше брать нельзя: поломка, замеченная
|
|
159
|
-
через две выкатки, откатывается уже некуда.
|
|
160
|
-
- **Описание прода правится вместе с составом прода.** Устройство, путь запроса, гейты и
|
|
161
|
-
бэкапы описаны текстами вне слоёв правил, и ни линтер, ни сборка их не читают: расхождение
|
|
162
|
-
копится молча, а читают эти тексты как действующие. Пару стережёт гард документов.
|
|
163
|
-
- **Правка конвейера прогоняется до мержа ручным запуском.** `workflow_dispatch` у выкатки
|
|
164
|
-
запускает её на любой ветке, а сама выкатка прибита условием к главной: прогон ради проверки
|
|
165
|
-
доходит до сборок и там кончается. Триггер регистрируется по главной ветке, поэтому правку,
|
|
166
|
-
которая его заводит или переносит, ручной запуск не покрывает. Прогон команд задания на своей
|
|
167
|
-
машине не покрывает её тоже: он проверяет команды, а не файл конвейера, — верность самого
|
|
168
|
-
файла читается только по списку прогонов после пуша.
|
|
169
|
-
- **PR проверяется до мержа тем же конвейером, что и главная ветка.** Проверки и сборки
|
|
170
|
-
образов идут на событии `pull_request`, выкатка — нет: её держит условие по главной ветке у
|
|
171
|
-
своего задания, а образ PR в реестр не уезжает.
|
|
172
137
|
- **Вершина открытого PR без прогона видна сверкой очереди работ.** Страница PR без прогона
|
|
173
138
|
выглядит так же, как страница с зелёным: цвета у неё нет ни там, ни там, — и вершину, за
|
|
174
139
|
которой прогон не встал, замечали только тем, что открывали список прогонов руками. Сверка
|
|
@@ -177,7 +142,12 @@ flowchart TD
|
|
|
177
142
|
- **Черновик при зелёном прогоне на вершине — расхождение сверки.** У черновика кнопка слияния
|
|
178
143
|
заблокирована самим хостингом: зелёная страница PR владельцу ничего не разрешает, а список, в
|
|
179
144
|
котором всё серое, читается как «работа не сделана». Гард снятия черновика сюда не достаёт —
|
|
180
|
-
он судит один
|
|
145
|
+
он судит один ход, а PR стоит в очереди днями.
|
|
146
|
+
- **Открытие PR отбивается, пока ветка везёт папку своей задачи.** Уборка стоит до открытия, а
|
|
147
|
+
не после одобрения: кнопку слияния нажимает человек на странице хостинга, где гардов нет
|
|
148
|
+
вовсе, и вливает он, как только видит зелёное. Отказ на слиянии остаётся вторым рубежом — он
|
|
149
|
+
ловит слияние, идущее командой, — но первым спрашивается открытие: это последняя точка, где
|
|
150
|
+
отказ ещё виден тому, кто может его выполнить.
|
|
181
151
|
- **Конфликтующий открытый PR — расхождение сверки очереди работ.** Конфликт приезжает в
|
|
182
152
|
отданный PR чужим слиянием, без единого действия автора: основание, проверенное на открытии,
|
|
183
153
|
устаревает в ту минуту, когда владелец влил соседнюю работу. Гард снятия черновика сюда не
|
|
@@ -185,13 +155,6 @@ flowchart TD
|
|
|
185
155
|
метку хостинг показывает только внутри самого PR. Непосчитанная сливаемость расхождением не
|
|
186
156
|
считается: хостинг считает её заново после каждой правки главной ветки, и строка на
|
|
187
157
|
«ещё не посчитано» краснела бы на каждой свежей вершине.
|
|
188
|
-
- **Расхождение прода с главной веткой видно сверкой очереди работ.** Задача уходит из очереди
|
|
189
|
-
мержем, но мерж — ещё не прод: отказавшая выкатка не трогает ни задачу, ни её колонку, и
|
|
190
|
-
заметить её неоткуда. Сверка спрашивает последний прогон главной ветки и судит только
|
|
191
|
-
завершённый: идущий ещё может кончиться выкаткой.
|
|
192
|
-
- **Цепочка миграций прогоняется с пустого хранилища до мержа.** Порядок применения
|
|
193
|
-
лексикографический по имени каталога, а метку времени ставит момент создания: миграция из
|
|
194
|
-
ветки, начатой раньше, встаёт перед той, от которой зависит.
|
|
195
158
|
- **Документ едет в том же коммите, что и правка.** Обход — строка `Docs-skip: <причина>` в
|
|
196
159
|
теле коммита; пустая причина не принимается.
|
|
197
160
|
- **Заголовок коммита сверяется с форматом на месте.** Разобранный по типу и области
|
|
@@ -269,6 +232,14 @@ flowchart TD
|
|
|
269
232
|
на них один. Исполнитель сливает свой PR только тогда, когда человек сказал это прямо и про
|
|
270
233
|
этот PR; сказанное об одном PR на следующий не переносится, а молчание разрешением не
|
|
271
234
|
бывает. Работа кончается PR, с которого снят черновик, и в ответе называется его номер.
|
|
235
|
+
- **Личность вызова, открывающего заявку, стережёт гард поставки, а не память исполнителя.**
|
|
236
|
+
Она приходит окружением, и из текста команды видна только явной подстановкой токена — её гард
|
|
237
|
+
и требует, называя переменную и готовую строку; дерево, не назвавшее машинной записи,
|
|
238
|
+
требования не получает. Ответ хостинга об авторе он спрашивает позже, на снятии черновика:
|
|
239
|
+
это последний ход, где промах ещё исправим — влитую заявку не переоткрыть, а автора у неё не
|
|
240
|
+
сменить. Прежде обе стороны держались статьёй и разбором происшествия, и промах повторился на
|
|
241
|
+
третий день.
|
|
242
|
+
|
|
272
243
|
- **Автор PR не может быть его ревьювером.** Запрос разбора на самого себя GitHub принимает и
|
|
273
244
|
молча не создаёт — разбор при этом выглядит запрошенным. Поэтому в разборе считаются только
|
|
274
245
|
запрос и отзыв не от автора: гард снятия черновика читает состояние PR именно так.
|
|
@@ -291,10 +262,6 @@ flowchart TD
|
|
|
291
262
|
репозитории сценария наследует общий конфиг: если включена подпись, git идёт в агент ключей,
|
|
292
263
|
а заблокированный агент роняет весь набор — со стороны это выглядит сломанным гардом. Автор,
|
|
293
264
|
почта и подпись передаются флагами `-c` прямо в команду.
|
|
294
|
-
- **Расхождение миграций со схемой меряется на теневом хранилище, а не на том, где работает
|
|
295
|
-
тот, кто пушит.** Оно законно несёт след любой недоделанной ветки, и сверка с ним держала бы
|
|
296
|
-
чужую правку. Гейт и выкатка зовут одну и ту же проверку — иначе «сошлось» станет значить в
|
|
297
|
-
двух местах разное.
|
|
298
265
|
|
|
299
266
|
## Чего из закона здесь нет
|
|
300
267
|
|
|
@@ -317,81 +284,6 @@ flowchart TD
|
|
|
317
284
|
|
|
318
285
|
## Паттерны
|
|
319
286
|
|
|
320
|
-
- `git-workflow-commit` — задача, ветка,
|
|
287
|
+
- `git-workflow-commit` — задача, ветка, коммит и пуш от учётной записи машинной работы.
|
|
288
|
+
- `git-workflow-pr` — открытие PR, черновик и его снятие, тело, ревьювер, метки, состояние.
|
|
321
289
|
- `git-workflow-merge` — главная ветка влита в ветку задачи, конфликт разобран.
|
|
322
|
-
- `git-workflow-migration` — правка схемы хранилища и её миграций.
|
|
323
|
-
- `git-workflow-restart` — ручной перезапуск прода.
|
|
324
|
-
- `git-workflow-docker` — образы на своей машине: демон, реестр, сборка под платформу сервера.
|
|
325
|
-
- `git-workflow-secrets` — ключи внешних служб: где лежат, как заводятся, что говорит их состояние.
|
|
326
|
-
|
|
327
|
-
## Ловушки
|
|
328
|
-
|
|
329
|
-
- **Одна работа — одна задача, сколько бы файлов она ни задела.** Числа, за которым правка
|
|
330
|
-
становится второй задачей, здесь нет: делится то, что придётся откатывать порознь. Сплошная
|
|
331
|
-
правка текстов дерева была заведена тремя задачами «по объёму» — пришлось стирать две,
|
|
332
|
-
закрывать два PR и переносить коммиты по одному с двумя конфликтами. Одна из трёх не дала
|
|
333
|
-
коммита вовсе: правка тел уже заведённых задач веткой не бывает и задачей под ветку тоже.
|
|
334
|
-
- **Задача заводится командой, а не четырьмя вызовами подряд.** Борда к репозиторию не
|
|
335
|
-
привязана, и задача попадает на неё только явным добавлением: две задачи так и простояли вне
|
|
336
|
-
очереди работ, потому что шаг переписывали руками. Команда заведения делает все четыре — issue,
|
|
337
|
-
номер в его заголовке, добавление на борду, начальную колонку, — и печатает готовую строку
|
|
338
|
-
заведения ветки. Замеченный по ходу дефект проходит тот же путь.
|
|
339
|
-
- **Ветка заводится вторым вызовом, а не тем же.** Гард главной ветки отклоняет составную
|
|
340
|
-
«создать ветку и сразу коммитить» целиком: ветки в момент разбора ещё нет.
|
|
341
|
-
- **Сторона конфликта бывает удалением, и «сохранить обе стороны» заводит второе объявление.**
|
|
342
|
-
Главная ветка снимает объявление, потому что символ переехал, — в конфликте это выглядит как
|
|
343
|
-
сторона, которая ничего не дописала. Разбирается чтением версии главной ветки целиком, а не по
|
|
344
|
-
хунку, и сверяется проверкой повторов: обе копии сами по себе исправны, сборка и линт зелёные.
|
|
345
|
-
- **Учётная запись для пуша и автор PR выбираются отдельно.** Если пушить пришлось из-под другой
|
|
346
|
-
записи, на следующий вызов это не переносится: PR открывают токеном учётной записи машинной
|
|
347
|
-
работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
|
|
348
|
-
смена записи ради пуша утекла в публикацию — PR вышел от владельца. Разница между читающим и
|
|
349
|
-
пишущим вызовом в самом тексте команды не видна: личность приходит окружением, поэтому у
|
|
350
|
-
вызова на запись токен называется явно, а открытая заявка проверяется ответом хостинга о её
|
|
351
|
-
авторе — напечатанная ссылка говорит, что заявка создана, и молчит о том, кем. Чинится это
|
|
352
|
-
только переоткрытием: автора у заявки не сменить.
|
|
353
|
-
- **Невалидный файл конвейера виден прогоном нулевой длительности сразу после пуша.** GitHub
|
|
354
|
-
заводит такой прогон и на ветке, на которую ни один триггер не подписан: в списке он стоит
|
|
355
|
-
отказом, а внутри у него нет ни задания, ни лога — читается только длительность. Поэтому
|
|
356
|
-
список прогонов ветки смотрится тем же движением, что и пуш — `gh run list --branch <ветка>`.
|
|
357
|
-
Один такой отказ простоял в списке до мержа, и на него никто не посмотрел: выкатка после
|
|
358
|
-
мержа отказала ровно тем же.
|
|
359
|
-
- **Прогон, не вставший на пуш, возвращается повтором события, а не разбором ветки.** Замером
|
|
360
|
-
проверены обе законные дороги: и открытие PR, и пуш в уже открытый PR прогон заводят —
|
|
361
|
-
текстовый коммит и учётная запись, которой пушат, тут ни при чём. Пропавшие события пришлись
|
|
362
|
-
на час, когда хостинг отвечал `429` на загрузке действия и `503` на API, а списком прогонов
|
|
363
|
-
«не завёлся» от «не создан» не отличить. Поэтому вершину без прогона называет сверка очереди
|
|
364
|
-
работ, а событие возвращается новым коммитом либо перезакрытием PR.
|
|
365
|
-
- **Красное на шаге подготовки задания — отказ хостинга, а не дефект ветки.** Раннер не смог
|
|
366
|
-
скачать действие чекаута и получил `429 Too Many Requests`; до кода прогон при этом не дошёл
|
|
367
|
-
вовсе. Лечится перезапуском прогона, и от красного по существу отличается тем, на каком шаге
|
|
368
|
-
оно встало: три прогона одного дня упали именно так.
|
|
369
|
-
- **Контекст `runner` в `env` задания отбивает весь файл конвейера.** Там доступны только
|
|
370
|
-
`github`, `needs`, `strategy`, `matrix`, `vars`, `secrets` и `inputs`; `runner` появляется на
|
|
371
|
-
уровне шага, где то же значение приходит переменной окружения. Такой файл не принимается
|
|
372
|
-
вовсе: прогон кончается за ноль секунд, не начав ни одного задания. Разбор YAML этого не
|
|
373
|
-
ловит — синтаксис верный, а доступность контекстов синтаксисом не является.
|
|
374
|
-
- **`online` у раннера на своей машине означает запущенный процесс, а не работающий
|
|
375
|
-
конвейер.** Две стороны сходятся отдельно: `runs-on` у заданий и метки самого раннера. Пока
|
|
376
|
-
пересечения нет, раннер стоит `online` и не берёт ничего, а задания уходят в облако — по
|
|
377
|
-
состоянию это выглядит настроенным. Владельцу называют выполненное задание с его номером, а
|
|
378
|
-
не строку состояния.
|
|
379
|
-
- **Раннер на своей машине делает прогон общим ресурсом, и стенд у прогонов один.** Порт,
|
|
380
|
-
имя базы и каталог сборки зашиты в дереве одним значением на всех: два прогона разом
|
|
381
|
-
поднимают два стенда на один порт, и второй падает целиком. Дороже всего не падение, а его
|
|
382
|
-
вид — в отчёте оно выглядит десятком красных спек про экраны, то есть дефектом правки,
|
|
383
|
-
которого нет; три прогона подряд так и упали на трёх ветках, не тронувших кода. Лечится с
|
|
384
|
-
двух сторон сразу: конвейеру объявляется группа очереди на всё дерево, а имена стенда
|
|
385
|
-
читаются из окружения с нынешними значениями в умолчании — иначе прогон и гейт пуша, зовущий
|
|
386
|
-
ту же команду, столкнутся и при очереди. Одной очереди мало, одних имён — тоже: прогоны делят
|
|
387
|
-
ещё диск, кэш сборщика и демон образов.
|
|
388
|
-
- **Вход в реестр образов из раннера, запущенного службой, отказывает молча.** Служба идёт без
|
|
389
|
-
сеанса пользователя, а клиент реестра уходит в системный помощник хранения ключей и получает
|
|
390
|
-
отказ во взаимодействии — задание падает до сборки. Свой каталог настроек с пустым помощником
|
|
391
|
-
не спасает: клиент переписывает пустое значение обратно сам. Готовые команды — паттерн
|
|
392
|
-
`git-workflow-docker`.
|
|
393
|
-
- **Новое рабочее дерево получает только то, что лежит в индексе.** `git worktree add`
|
|
394
|
-
разворачивает коммит, а настройки, ключи, локальные разрешения и зависимости в коммит не
|
|
395
|
-
входят: свежее дерево выглядит готовым и упирается в нехватку не сразу, а на первом гарде,
|
|
396
|
-
которому нужен ключ. Что именно переносится руками, названо списком в компаньоне правила, и
|
|
397
|
-
список пополняется тем же движением, которым заводится новый файл вне индекса.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: git-workflow
|
|
3
3
|
kind: rule
|
|
4
4
|
law: delivery
|
|
5
|
-
description: Правило под «Закон о поставке» для дерева на GitLab. Брать на заведение задачи, ветки, коммит, пуш, создание MR, слияние, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет задачу на борде как начало работы, колонку задачи как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав MR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-
|
|
5
|
+
description: Правило под «Закон о поставке» для дерева на GitLab. Брать на заведение задачи, ветки, коммит, пуш, создание MR, слияние, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет задачу на борде как начало работы, колонку задачи как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав MR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-pr, git-workflow-merge. Выкатка, образы и миграции — правило deploy-flow.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Поставка — как это устроено здесь
|
|
@@ -12,6 +12,9 @@ description: Правило под «Закон о поставке» для д
|
|
|
12
12
|
учётная запись машинной работы и области коммита — при этом дереве, в `implementation.md`
|
|
13
13
|
рядом: их не угадать, и общими они не бывают.
|
|
14
14
|
|
|
15
|
+
**Холодная часть:** `pitfalls.md` рядом — ловушки, грабли, на которые уже наступали.
|
|
16
|
+
Грузится по требованию, а не вместе с правилом.
|
|
17
|
+
|
|
15
18
|
## Как это называется здесь
|
|
16
19
|
|
|
17
20
|
| В законе | Здесь |
|
|
@@ -23,9 +26,6 @@ description: Правило под «Закон о поставке» для д
|
|
|
23
26
|
| состояние задачи в очереди работ | список доски, за которым стоит метка: заведённая, взятая в работу, ждущая разбора. Имена меток — в `implementation.md`; закрытая задача уходит из очереди слиянием, а не переносом в последний список |
|
|
24
27
|
| PR о задаче | заголовок MR `[<КЛЮЧ>-<номер>] <Что сделано>` — тот же номер, что у задачи, и её название, переведённое в сделанное; тип и область коммита сюда не идут |
|
|
25
28
|
| обсуждение правки | разбор MR: ревьювер — владелец проекта, исполнитель — учётная запись машинной работы, метки — те же, что у задачи |
|
|
26
|
-
| попадание правки в главную ветку | слияние MR; оно же запускает выкатку — `.gitlab-ci.yml` |
|
|
27
|
-
| образ того коммита | `IMAGE_TAG=<sha>` в командах `docker compose` на сервере |
|
|
28
|
-
| изменение хранилища | миграция в `prisma/migrations/<метка>_<имя>/` |
|
|
29
29
|
| запись о правке | коммит формата `type(scope): description` — типы `feat`, `fix`, `refactor`, `docs`, `style`, `test`, `chore`, `perf`; области — в `implementation.md` |
|
|
30
30
|
| автор машинной работы | отдельная учётная запись; её имя и место токена — в `implementation.md`. Токен лежит вне репозитория |
|
|
31
31
|
|
|
@@ -130,12 +130,6 @@ flowchart TD
|
|
|
130
130
|
остаётся в ней после слияния навсегда. Здесь она заводится проще, чем где-либо: доска
|
|
131
131
|
собирается по меткам, и метка списка, поставленная на MR, тут же делает его карточкой.
|
|
132
132
|
Находит такие сверка очереди — строкой на каждую.
|
|
133
|
-
- **Конвейер судит по составу правки, а не гоняет всё подряд.** Шаги, которым нечего проверять,
|
|
134
|
-
пропускаются по признаку, посчитанному от главной ветки: ветка, не тронувшая ни строки кода,
|
|
135
|
-
не поднимает стенда, не снимает кадров и не собирает образов. Правила `rules:changes` считают
|
|
136
|
-
это сами, но по путям, а не по составу правки — совпадение пути ещё не значит, что задета
|
|
137
|
-
сборка, поэтому признак объявляется явно и один раз. Пропущенный шаг виден в прогоне
|
|
138
|
-
пропущенным — молча выпавший читается как пройденный.
|
|
139
133
|
- **Отставший список находится сверкой очереди, а не глазами.** Сверка судит список по PR
|
|
140
134
|
в обе стороны: открытый MR при задаче не в разборе и разбор без открытого MR — оба
|
|
141
135
|
расхождения. Момента, когда задачу берут в работу, ей не видно: ветки на доске нет.
|
|
@@ -147,37 +141,6 @@ flowchart TD
|
|
|
147
141
|
исполнитель открывает карточку раньше, чем замысел эпика, а планирует по замыслу. Одна пометка без
|
|
148
142
|
другой лжёт молча, поэтому сверка очереди судит пару в обе стороны. Помечается только то, что
|
|
149
143
|
законно не делится: пометка объёма правом делить не становится.
|
|
150
|
-
- **Слияние в главную ветку выкатывает прод.** Правила `only`/`rules` конвейера покрывают
|
|
151
|
-
документы отдельно, поэтому переменные окружения, секреты и записи имён ставятся до слияния,
|
|
152
|
-
а не после.
|
|
153
|
-
- **Признак режима объявлен в образе, а не только в составе прода.** Значение, заданное
|
|
154
|
-
составом, действует лишь на контейнер, поднятый этим составом; ручной прогон того же образа
|
|
155
|
-
идёт с пустым значением, а пусто здесь означает локалхост — со всеми отладочными
|
|
156
|
-
умолчаниями, которые он разрешает. Умолчание образа задаётся в самом образе.
|
|
157
|
-
- **Образы выкатываются по sha коммита, а не по метке «последний».** Метка в реестре отстаёт
|
|
158
|
-
от главной ветки, и прод молча возвращается к прежней версии, продолжая отвечать.
|
|
159
|
-
- **Выкатка убирает за собой старые образы, оставляя три последних sha.** Помеченный sha образ
|
|
160
|
-
висячим не бывает никогда, и чистка висячего его не касается: за полгода они съедают диск
|
|
161
|
-
сервера целиком. Три sha — это глубина отката, и меньше брать нельзя: поломка, замеченная
|
|
162
|
-
через две выкатки, откатывается уже некуда.
|
|
163
|
-
- **Описание прода правится вместе с составом прода.** Устройство, путь запроса, гейты и
|
|
164
|
-
бэкапы описаны текстами вне слоёв правил, и ни линтер, ни сборка их не читают: расхождение
|
|
165
|
-
копится молча, а читают эти тексты как действующие. Пару стережёт гард документов.
|
|
166
|
-
- **Правка конвейера прогоняется до слияния ручным запуском.** Конвейер запускается на любой
|
|
167
|
-
ветке, а задание выкатки прибито правилом к главной: прогон ради проверки доходит до сборок и
|
|
168
|
-
там кончается. Прогон команд задания на своей машине его не покрывает: он проверяет команды,
|
|
169
|
-
а не файл конвейера, — верность самого файла читается только по списку конвейеров после
|
|
170
|
-
пуша, и синтаксис отдельно судит проверка `.gitlab-ci.yml` в проекте.
|
|
171
|
-
- **PR проверяется до слияния тем же конвейером, что и главная ветка.** Проверки и сборки
|
|
172
|
-
образов идут на конвейере запроса слияния, выкатка — нет: её держит правило по главной ветке
|
|
173
|
-
у своего задания, а образ PR в реестр не уезжает.
|
|
174
|
-
- **Расхождение прода с главной веткой видно сверкой очереди работ.** Задача уходит из очереди
|
|
175
|
-
слиянием, но слияние — ещё не прод: отказавшая выкатка не трогает ни задачу, ни её список, и
|
|
176
|
-
заметить её неоткуда. Сверка спрашивает последний конвейер главной ветки и судит только
|
|
177
|
-
завершённый: идущий ещё может кончиться выкаткой.
|
|
178
|
-
- **Цепочка миграций прогоняется с пустого хранилища до слияния.** Порядок применения
|
|
179
|
-
лексикографический по имени каталога, а метку времени ставит момент создания: миграция из
|
|
180
|
-
ветки, начатой раньше, встаёт перед той, от которой зависит.
|
|
181
144
|
- **Документ едет в том же коммите, что и правка.** Обход — строка `Docs-skip: <причина>` в
|
|
182
145
|
теле коммита; пустая причина не принимается.
|
|
183
146
|
- **Заголовок коммита сверяется с форматом на месте.** Разобранный по типу и области
|
|
@@ -222,10 +185,6 @@ flowchart TD
|
|
|
222
185
|
репозитории сценария наследует общий конфиг: если включена подпись, git идёт в агент ключей,
|
|
223
186
|
а заблокированный агент роняет весь набор — со стороны это выглядит сломанным гардом. Автор,
|
|
224
187
|
почта и подпись передаются флагами `-c` прямо в команду.
|
|
225
|
-
- **Расхождение миграций со схемой меряется на теневом хранилище, а не на том, где работает
|
|
226
|
-
тот, кто пушит.** Оно законно несёт след любой недоделанной ветки, и сверка с ним держала бы
|
|
227
|
-
чужую правку. Гейт и выкатка зовут одну и ту же проверку — иначе «сошлось» станет значить в
|
|
228
|
-
двух местах разное.
|
|
229
188
|
|
|
230
189
|
## Чего из закона здесь нет
|
|
231
190
|
|
|
@@ -248,52 +207,6 @@ flowchart TD
|
|
|
248
207
|
|
|
249
208
|
## Паттерны
|
|
250
209
|
|
|
251
|
-
- `git-workflow-commit` — задача, ветка,
|
|
210
|
+
- `git-workflow-commit` — задача, ветка, коммит и пуш от учётной записи машинной работы.
|
|
211
|
+
- `git-workflow-pr` — открытие MR, черновик и его снятие, описание, ревьювер, метки, состояние.
|
|
252
212
|
- `git-workflow-merge` — главная ветка влита в ветку задачи, конфликт разобран.
|
|
253
|
-
- `git-workflow-migration` — правка схемы хранилища и её миграций.
|
|
254
|
-
- `git-workflow-restart` — ручной перезапуск прода.
|
|
255
|
-
- `git-workflow-docker` — образы на своей машине: демон, реестр, сборка под платформу сервера.
|
|
256
|
-
- `git-workflow-secrets` — ключи внешних служб: где лежат, как заводятся, что говорит их состояние.
|
|
257
|
-
|
|
258
|
-
## Ловушки
|
|
259
|
-
|
|
260
|
-
- **Одна работа — одна задача, сколько бы файлов она ни задела.** Числа, за которым правка
|
|
261
|
-
становится второй задачей, здесь нет: делится то, что придётся откатывать порознь. Сплошная
|
|
262
|
-
правка текстов дерева была заведена тремя задачами «по объёму» — пришлось стирать две,
|
|
263
|
-
закрывать два MR и переносить коммиты по одному с двумя конфликтами. Одна из трёх не дала
|
|
264
|
-
коммита вовсе: правка тел уже заведённых задач веткой не бывает и задачей под ветку тоже.
|
|
265
|
-
- **Задача заводится командой, а не вызовами подряд.** Доска показывает те issue, чью метку
|
|
266
|
-
знает, и задача без метки списка в очереди работ не видна: со стороны это выглядит так же, как
|
|
267
|
-
незаведённая. Команда заведения ставит всё разом — issue, номер в его заголовке, метку списка,
|
|
268
|
-
исполнителя, — и печатает готовую строку заведения ветки. Замеченный по ходу дефект проходит
|
|
269
|
-
тот же путь.
|
|
270
|
-
- **Ветка заводится вторым вызовом, а не тем же.** Гард главной ветки отклоняет составную
|
|
271
|
-
«создать ветку и сразу коммитить» целиком: ветки в момент разбора ещё нет.
|
|
272
|
-
- **Сторона конфликта бывает удалением, и «сохранить обе стороны» заводит второе объявление.**
|
|
273
|
-
Главная ветка снимает объявление, потому что символ переехал, — в конфликте это выглядит как
|
|
274
|
-
сторона, которая ничего не дописала. Разбирается чтением версии главной ветки целиком, а не по
|
|
275
|
-
хунку, и сверяется проверкой повторов: обе копии сами по себе исправны, сборка и линт зелёные.
|
|
276
|
-
- **Учётная запись для пуша и автор MR выбираются отдельно.** Если пушить пришлось из-под другой
|
|
277
|
-
записи, на следующий вызов это не переносится: MR открывают токеном учётной записи машинной
|
|
278
|
-
работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
|
|
279
|
-
смена записи ради пуша утекла в публикацию — PR вышел от владельца.
|
|
280
|
-
- **Невалидный файл конвейера виден отказом сразу после пуша, а не упавшим заданием.** Конвейер
|
|
281
|
-
на такой файл не заводится вовсе: в списке стоит запись об ошибке разбора, а внутри нет ни
|
|
282
|
-
задания, ни лога. Поэтому список конвейеров ветки смотрится тем же движением, что и пуш —
|
|
283
|
-
`glab ci list --branch <ветка>`, — а сам файл до пуша судит проверка `.gitlab-ci.yml` в
|
|
284
|
-
проекте.
|
|
285
|
-
- **`online` у раннера на своей машине означает запущенный процесс, а не работающий
|
|
286
|
-
конвейер.** Две стороны сходятся отдельно: `tags` у заданий и теги самого раннера. Пока
|
|
287
|
-
пересечения нет, раннер стоит `online` и не берёт ничего, а задания ждут общего раннера — по
|
|
288
|
-
состоянию это выглядит настроенным. Владельцу называют выполненное задание с его номером, а
|
|
289
|
-
не строку состояния.
|
|
290
|
-
- **Вход в реестр образов из раннера, запущенного службой, отказывает молча.** Служба идёт без
|
|
291
|
-
сеанса пользователя, а клиент реестра уходит в системный помощник хранения ключей и получает
|
|
292
|
-
отказ во взаимодействии — задание падает до сборки. Свой каталог настроек с пустым помощником
|
|
293
|
-
не спасает: клиент переписывает пустое значение обратно сам. Готовые команды — паттерн
|
|
294
|
-
`git-workflow-docker`.
|
|
295
|
-
- **Новое рабочее дерево получает только то, что лежит в индексе.** `git worktree add`
|
|
296
|
-
разворачивает коммит, а настройки, ключи, локальные разрешения и зависимости в коммит не
|
|
297
|
-
входят: свежее дерево выглядит готовым и упирается в нехватку не сразу, а на первом гарде,
|
|
298
|
-
которому нужен ключ. Что именно переносится руками, названо списком в компаньоне правила, и
|
|
299
|
-
список пополняется тем же движением, которым заводится новый файл вне индекса.
|