spectrum-cli 3.1.1 → 4.0.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/CHANGELOG.md +34 -0
- package/README.md +81 -29
- package/index.js +6 -158
- package/package.json +4 -4
- package/src/changelog/commands.js +44 -0
- package/src/changelog/format.js +51 -0
- package/src/{changelog.js → changelog/fragments.js} +3 -136
- package/src/{hotfix-changelog.js → changelog/hotfix.js} +13 -18
- package/src/changelog/index.js +7 -0
- package/src/{open-release.js → changelog/open-release.js} +6 -6
- package/src/changelog/release-block.js +80 -0
- package/src/chart/deploy.js +216 -0
- package/src/chart/helmrelease.js +90 -0
- package/src/chart/index.js +30 -0
- package/src/chart/metadata.js +114 -0
- package/src/chart/registry.js +139 -0
- package/src/chart/routes.js +244 -0
- package/src/chart/start.js +98 -0
- package/src/chart/verify.js +166 -0
- package/src/cli/command-executor.js +181 -0
- package/src/cli/commands.js +136 -0
- package/src/{development.js → cli/development.js} +1 -1
- package/src/cli/help.js +55 -0
- package/src/cli/run-action.js +28 -0
- package/src/cli/update-check.js +51 -0
- package/src/{git.js → git/index.js} +4 -3
- package/src/hotfix/checks.js +144 -0
- package/src/hotfix/close.js +46 -0
- package/src/hotfix/deploy.js +37 -0
- package/src/hotfix/git.js +35 -0
- package/src/hotfix/index.js +5 -0
- package/src/hotfix/start.js +57 -0
- package/src/integrations/gitlab-url.js +16 -0
- package/src/preflight/changelog.js +130 -0
- package/src/preflight/chart.js +57 -0
- package/src/preflight/git.js +133 -0
- package/src/preflight/helmrelease.js +201 -0
- package/src/preflight/index.js +10 -0
- package/src/preflight/result.js +18 -0
- package/src/preflight/source.js +95 -0
- package/src/preflight/tags.js +139 -0
- package/src/release/close.js +39 -0
- package/src/release/index.js +7 -0
- package/src/{stable-tags.js → release/stable-tags.js} +1 -1
- package/src/release/start.js +51 -0
- package/src/release/steps.js +83 -0
- package/src/release/version.js +20 -0
- package/src/token/config.js +163 -0
- package/src/token/gitlab-api.js +59 -0
- package/src/token/index.js +6 -0
- package/src/token/rotate.js +157 -0
- package/src/chart.js +0 -1071
- package/src/command-executor.js +0 -70
- package/src/hotfix.js +0 -223
- package/src/preflight.js +0 -796
- package/src/release.js +0 -207
- package/src/token.js +0 -399
- /package/src/{changelog-config.js → changelog/config.js} +0 -0
- /package/src/{utils.js → common/utils.js} +0 -0
- /package/src/{version.js → common/version.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
This is the changelog of the `spectrum-cli` npm package. Its version comes from
|
|
9
|
+
`package.json`; the release commands use Git tags and `CHANGELOG.md` in the
|
|
10
|
+
**target project** and do not update that project's `package.json`.
|
|
11
|
+
|
|
12
|
+
## 🚀 [4.0.0] - 2026-10-01
|
|
13
|
+
|
|
14
|
+
### 💥 Breaking change
|
|
15
|
+
|
|
16
|
+
- `spectrum chart create <version>` заменена на `spectrum chart start`: версия берётся из верхнего заголовка `charts/<chart-name>/CHANGELOG.md` и больше не передаётся аргументом.
|
|
17
|
+
- `chart start` по умолчанию ждёт публикации чарта в Helm-registry. Прежний `--wait` заменён на `-n, --no-wait` для запуска без ожидания.
|
|
18
|
+
- Исходные модули перемещены из файлов `src/*.js` в каталоги с `index.js`; прямые импорты файлов со старыми путями требуют обновления.
|
|
19
|
+
|
|
20
|
+
### 🆕 Added
|
|
21
|
+
|
|
22
|
+
- Все команды с действием поддерживают `-d, --dry` для запуска только предпроверок и `-s, --silence` для скрытия сообщений об успешно пройденных проверках. Для всех флагов доступны короткие формы.
|
|
23
|
+
- Перед созданием chart-тега проверяется, что версия из changelog ещё не существует среди локальных и удалённых Git-тегов и в Helm-registry.
|
|
24
|
+
|
|
25
|
+
### 🛠 Changed
|
|
26
|
+
|
|
27
|
+
- Предпроверки сообщают, что именно проверено, выполняются все доступные проверки и завершают команду с ошибкой, если хотя бы одна не прошла; имя запущенной команды из сообщений убрано.
|
|
28
|
+
- Код CLI и тесты распределены по тематическим модулям; документация по установке, релизам и безопасности приведена в соответствие с текущим кодом.
|
|
29
|
+
|
|
30
|
+
## 🚀 [3.2.0] - 2026-10-01
|
|
31
|
+
|
|
32
|
+
### 🆕 Added
|
|
33
|
+
|
|
34
|
+
- Добавлена команда `spectrum changelog write`: выравнивает заголовки релизов и хотфиксов и форматирует `CHANGELOG.md` через Prettier.
|
|
35
|
+
- Добавлена команда `spectrum upgrade` для глобального обновления CLI через npm.
|
|
36
|
+
- Перед выполнением команд с действием CLI проверяет наличие новой версии в npm с таймаутом 200 мс и выводит версии и команду обновления; ошибка проверки не прерывает команду. `--help` и `--version` проверку не запускают.
|
|
37
|
+
|
|
38
|
+
### 🪲 Fixed
|
|
39
|
+
|
|
40
|
+
- `spectrum hotfix start` собирает все текущие фрагменты из `.changelog/` независимо от истории Git.
|
|
41
|
+
|
|
8
42
|
## 🚀 [3.1.1] - 2026-09-24
|
|
9
43
|
|
|
10
44
|
### 🪲 Fixed
|
package/README.md
CHANGED
|
@@ -14,6 +14,12 @@ npm install -g spectrum-cli
|
|
|
14
14
|
spectrum --help
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
Перед выполнением каждой команды CLI проверяет опубликованную версию `spectrum-cli`
|
|
18
|
+
в npm Registry. Если доступна новая версия, показывает текущую и новую версии и
|
|
19
|
+
команду `spectrum upgrade`. Она запускает `npm install -g spectrum-cli`.
|
|
20
|
+
Проверка ограничена 200 мс; недоступность Registry не влияет на выполнение
|
|
21
|
+
команды и не выводит ошибку.
|
|
22
|
+
|
|
17
23
|
### 🔧 Из исходников
|
|
18
24
|
|
|
19
25
|
```bash
|
|
@@ -34,7 +40,7 @@ npm install
|
|
|
34
40
|
# Показать справку
|
|
35
41
|
spectrum --help
|
|
36
42
|
# Показать текущую версию CLI
|
|
37
|
-
spectrum -v
|
|
43
|
+
spectrum -v # или spectrum --version
|
|
38
44
|
|
|
39
45
|
# 🚀 Управление релизами
|
|
40
46
|
spectrum release start # Схлопнуть fragments и атомарно отправить release commit в dev и main/master
|
|
@@ -47,9 +53,9 @@ spectrum hotfix deploy # После merge MR: stable-тег на
|
|
|
47
53
|
spectrum hotfix close # После stable pipeline: main/master → dev
|
|
48
54
|
|
|
49
55
|
# 📈 Теги chart
|
|
50
|
-
spectrum chart
|
|
51
|
-
spectrum chart
|
|
52
|
-
spectrum chart
|
|
56
|
+
spectrum chart start # Создать тег по CHANGELOG.md чарта и дождаться публикации в Helm-registry
|
|
57
|
+
spectrum chart start -n # Не ждать публикации после отправки тега
|
|
58
|
+
spectrum chart start --force # Разрешить версию не выше последнего remote-тега, если ее еще нет в registry и Git
|
|
53
59
|
spectrum chart deploy # Обновить helmrelease.yaml до последнего chart-тега и запушить
|
|
54
60
|
spectrum chart deploy --instances sd,cbch # Обновить только выбранные инстансы instances/<name>
|
|
55
61
|
spectrum chart verify ~/repo # Сравнить ingress paths AS IS vs TO BE для Next.js исходников
|
|
@@ -57,11 +63,37 @@ spectrum chart verify ~/repo # Сравнить ingress paths AS IS vs TO BE д
|
|
|
57
63
|
# 📝 Управление changelog
|
|
58
64
|
spectrum changelog append "Сообщение" # Создать fragment в .changelog/
|
|
59
65
|
spectrum changelog check # Проверить CHANGELOG.md и все fragments
|
|
66
|
+
spectrum changelog write # Выравнять заголовки CHANGELOG.md и запустить Prettier
|
|
60
67
|
|
|
61
68
|
# 🔑 GitLab токены
|
|
62
69
|
spectrum token rotate # Пролить GITLAB_PRIVATE_TOKEN в CI variables
|
|
63
70
|
```
|
|
64
71
|
|
|
72
|
+
Все команды с действием показывают, какая предпроверка успешно пройдена;
|
|
73
|
+
при ошибке выводят её имя и причину. Независимые предпроверки продолжают
|
|
74
|
+
выполняться после ошибки; зависимые проверки без нужных данных помечаются как
|
|
75
|
+
невыполненные. Шаги команды запускаются, только если все проверки прошли.
|
|
76
|
+
`-s, --silence` скрывает сообщения об успешно пройденных предпроверках.
|
|
77
|
+
Ошибки проверок и итоговое сообщение команды остаются видны; флаг можно
|
|
78
|
+
совмещать с `-d, --dry`.
|
|
79
|
+
`-d, --dry` выполняет все предпроверки,
|
|
80
|
+
показывает их результаты и не запускает шаги записи, создания тегов,
|
|
81
|
+
публикации или деплоя. Предпроверки могут обращаться к `origin`, registry и
|
|
82
|
+
GitLab; `token rotate -d` запрашивает токены и проверяет доступ к целям, но не
|
|
83
|
+
изменяет CI variables. Если конфиг токенов отсутствует, `--dry` завершится
|
|
84
|
+
ошибкой и не создаст его. Для `upgrade -d` предпроверок нет: команда сообщает
|
|
85
|
+
об успехе, не запуская npm.
|
|
86
|
+
|
|
87
|
+
| Короткий флаг | Полный флаг | Где действует |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| `-d` | `--dry` | Все команды с действием: только предпроверки |
|
|
90
|
+
| `-s` | `--silence` | Все команды с действием: скрыть успешные предпроверки |
|
|
91
|
+
| `-f` | `--force` | `chart start`: разрешить версию не больше последнего тега на `origin`; проверки Git-тега и Helm-registry обязательны |
|
|
92
|
+
| `-n` | `--no-wait` | `chart start`: не ждать появления версии в Helm-registry после push; по умолчанию команда ждёт |
|
|
93
|
+
| `-i <names>` | `--instances <names>` | `chart deploy`: выбрать инстансы через запятую |
|
|
94
|
+
| `-h` | `--help` | Справка CLI и команд |
|
|
95
|
+
| `-v` | `--version` | Версия CLI |
|
|
96
|
+
|
|
65
97
|
### Справка по командам:
|
|
66
98
|
|
|
67
99
|
```bash
|
|
@@ -96,24 +128,29 @@ spectrum token --help
|
|
|
96
128
|
|
|
97
129
|
```
|
|
98
130
|
spectrum-cli/
|
|
99
|
-
├── index.js
|
|
100
|
-
├── .changelog/
|
|
101
|
-
├── src/
|
|
102
|
-
│ ├──
|
|
103
|
-
│ ├──
|
|
104
|
-
│ ├──
|
|
105
|
-
│ ├──
|
|
106
|
-
│ ├── changelog
|
|
107
|
-
│ ├── chart
|
|
108
|
-
│ ├──
|
|
109
|
-
│ ├──
|
|
110
|
-
│
|
|
111
|
-
├──
|
|
112
|
-
├──
|
|
113
|
-
├──
|
|
114
|
-
|
|
131
|
+
├── index.js # Точка входа CLI
|
|
132
|
+
├── .changelog/ # Записи для следующего релиза
|
|
133
|
+
├── src/
|
|
134
|
+
│ ├── cli/ # Команды, справка и запуск действий
|
|
135
|
+
│ ├── common/ # Общие утилиты и версии
|
|
136
|
+
│ ├── git/ # Git операции
|
|
137
|
+
│ ├── preflight/ # Независимые предпроверки по областям
|
|
138
|
+
│ ├── changelog/ # Fragments, конфиг и релизные разделы
|
|
139
|
+
│ ├── chart/ # Метаданные, теги, registry, verify и deploy
|
|
140
|
+
│ ├── release/ # Версии и этапы обычного релиза
|
|
141
|
+
│ ├── hotfix/ # Проверки и этапы hotfix
|
|
142
|
+
│ ├── token/ # Конфиг, GitLab API и ротация
|
|
143
|
+
│ ├── integrations/ # Общие функции внешних сервисов
|
|
144
|
+
├── __tests__/ # Модульные и интеграционные тесты
|
|
145
|
+
├── package.json
|
|
146
|
+
├── install.sh
|
|
147
|
+
├── INSTALL.md
|
|
148
|
+
└── README.md
|
|
115
149
|
```
|
|
116
150
|
|
|
151
|
+
Входы модулей находятся в `index.js` соответствующих каталогов. Например,
|
|
152
|
+
`require('./src/chart')` загружает `src/chart/index.js`; в корне `src` файлов нет.
|
|
153
|
+
|
|
117
154
|
### Команды
|
|
118
155
|
|
|
119
156
|
| Команда | Описание |
|
|
@@ -123,7 +160,7 @@ spectrum-cli/
|
|
|
123
160
|
| `spectrum release close` | Закрыть релиз |
|
|
124
161
|
| `spectrum changelog append` | Создать changelog fragment |
|
|
125
162
|
| `spectrum changelog check` | Проверить changelog и fragments |
|
|
126
|
-
| `spectrum chart
|
|
163
|
+
| `spectrum chart start` | Создать и запушить chart тег |
|
|
127
164
|
| `spectrum chart deploy` | Обновить chart версию в helmrelease |
|
|
128
165
|
| `spectrum chart verify` | Проверить ingress paths chart |
|
|
129
166
|
| `spectrum token rotate` | Пролить GITLAB_PRIVATE_TOKEN в CI |
|
|
@@ -135,7 +172,7 @@ spectrum-cli/
|
|
|
135
172
|
- `spectrum release close`: чистая и актуальная main/master, версия из верхнего заголовка `CHANGELOG.md` и remote stable-тег поддерживаемой формы, указывающий на текущий commit.
|
|
136
173
|
- `spectrum changelog append <message>`: `git-repo`, `changelog-exists`, валидные ID задачи, git identity и тип fragment. Команда не изменяет общий `CHANGELOG.md`.
|
|
137
174
|
- `spectrum changelog check`: `git-repo`, `changelog-exists`, `changelog-prettier-check`, наличие и формат всех changelog fragments.
|
|
138
|
-
- `spectrum chart
|
|
175
|
+
- `spectrum chart start`: `git-repo`, `clean-working-tree`, `on-main-branch`, `single-chart` (ровно один `charts/<chart-name>/Chart.yaml`), валидный верхний SemVer-заголовок в `charts/<chart-name>/CHANGELOG.md`, отсутствие тега `chart-<name>-<version>` локально и на `origin`, отсутствие этой версии чарта в Helm-registry. Для запроса registry нужен `GITLAB_PRIVATE_TOKEN`; ошибка доступа блокирует команду. `-f, --force` обходит только проверку повышения версии относительно последнего remote-тега. После push команда по умолчанию ждёт версию в registry; `-n, --no-wait` отключает ожидание.
|
|
139
176
|
- `spectrum chart deploy`: `git-repo`, `clean-working-tree`, `on-main-branch` (текущая ветка `main`), `remote-origin` (настроен `origin`), `remote-reachable` (доступен `origin`), `single-chart`, `helmrelease-files` (найдены `helmrelease.yaml`).
|
|
140
177
|
- `spectrum chart verify <source_path>`: `git-repo`, `single-values-yaml` (ровно один `charts/**/values.yaml`), `values-ingress-sections` (есть `ingress.paths.api/pages/assets`), `source-path-directory`, `next-project`, `build-command-support`.
|
|
141
178
|
- `spectrum token rotate`: `load-config` (есть валидный `~/.config/spectrum-cli/config.yaml`), `ask-tokens` (owner PAT и `GITLAB_PRIVATE_TOKEN` только в памяти), `check-access` (все группы и проекты доступны owner PAT).
|
|
@@ -197,6 +234,12 @@ spectrum-cli/
|
|
|
197
234
|
|
|
198
235
|
1. **`spectrum hotfix start`** обновляет сведения об origin и выбирает опубликованный
|
|
199
236
|
stable-тег, достижимый из production. Цель — этот stable плюс один patch.
|
|
237
|
+
Как и `release start`, команда читает все файлы текущей `.changelog/` независимо
|
|
238
|
+
от того, когда они попали в Git. Проверяет их общими правилами changelog и
|
|
239
|
+
допускает только patch-типы; файлы `added` и `breaking` требуют обычного релиза.
|
|
240
|
+
Формат CHANGELOG.md проверяется только в текущей ветке. История может отличаться
|
|
241
|
+
от stable-тега: её исправления не блокируют хотфикс. Снимок production используется
|
|
242
|
+
для сохранения записей уже подготовленного хотфикса, без строгой проверки старых заголовков.
|
|
200
243
|
Команда формирует верхний раздел `## 🩹 [X.Y.Z] - YYYY-MM-DD` и удаляет только
|
|
201
244
|
собранные fragments. Она не делает commit, staging, push, merge или tag,
|
|
202
245
|
не меняет файлы версий и сохраняет посторонние локальные изменения.
|
|
@@ -206,7 +249,7 @@ spectrum-cli/
|
|
|
206
249
|
читаются без переписывания опубликованной истории. Без новых fragments подготовленный раздел
|
|
207
250
|
остаётся без изменений. Например, от `v6.35.0` первый и повторные запуски
|
|
208
251
|
готовят `6.35.1`; только после публикации `hotfix/6.35.1` следующий хотфикс получит
|
|
209
|
-
`6.35.2`.
|
|
252
|
+
`6.35.2`.
|
|
210
253
|
3. Проверьте diff, закоммитьте и отправьте исправление по правилам проекта.
|
|
211
254
|
**В MR из hotfix в production уже должны быть верхний patch-раздел и удаления
|
|
212
255
|
использованных fragments.** Merge выполняется отдельно после ревью. Если
|
|
@@ -215,7 +258,7 @@ spectrum-cli/
|
|
|
215
258
|
4. После доставки подготовленного исправления в production через MR или
|
|
216
259
|
разрешённый проектом push и проверки RC выполните **`spectrum hotfix deploy`** на чистом
|
|
217
260
|
`main/master`, точно совпадающем с origin. Команда проверяет следующий patch,
|
|
218
|
-
|
|
261
|
+
отсутствие несобранных hotfix fragments,
|
|
219
262
|
создаёт `hotfix/X.Y.Z` на проверенном SHA и отправляет **только этот тег**.
|
|
220
263
|
Повтор после ошибки push допускает существующий локальный тег лишь на том же
|
|
221
264
|
SHA; опубликованный тег не перемещается. Ветки не сливаются.
|
|
@@ -253,14 +296,14 @@ pipeline и фактического выката выполняется отд
|
|
|
253
296
|
revision обязательных образов и копирует точные RC digest без пересборки. Эту
|
|
254
297
|
CI-часть реализует подключенный release component, а не Spectrum CLI.
|
|
255
298
|
|
|
256
|
-
### `spectrum chart
|
|
299
|
+
### `spectrum chart start`
|
|
257
300
|
|
|
258
301
|
1. Ищет `Chart.yaml` в `charts/<chart-name>/Chart.yaml` и читает поле `name`
|
|
259
302
|
2. Проверяет, что текущая ветка — `main`
|
|
260
|
-
3.
|
|
303
|
+
3. Читает версию из верхнего заголовка `charts/<chart-name>/CHANGELOG.md` и проверяет SemVer
|
|
261
304
|
4. Собирает тег `chart-<name>-<version>`
|
|
262
|
-
5. Проверяет, что такого тега еще нет
|
|
263
|
-
6. Создает тег и пушит его в `origin`
|
|
305
|
+
5. Проверяет, что такого тега еще нет локально и на `origin`, а версия отсутствует в Helm-registry
|
|
306
|
+
6. Создает тег и пушит его в `origin`, затем ждёт появления версии в registry; `-n, --no-wait` отключает ожидание
|
|
264
307
|
|
|
265
308
|
### `spectrum chart deploy`
|
|
266
309
|
|
|
@@ -367,9 +410,18 @@ Fragment должен содержать только непустые Markdown-
|
|
|
367
410
|
> Совет: Приведите файл к нужному формату командой:
|
|
368
411
|
>
|
|
369
412
|
> ```bash
|
|
370
|
-
>
|
|
413
|
+
> spectrum changelog write
|
|
371
414
|
> ```
|
|
372
415
|
|
|
416
|
+
### `spectrum changelog write`
|
|
417
|
+
|
|
418
|
+
Команда приводит все релизные заголовки `CHANGELOG.md` к виду `## 🚀 [X.Y.Z]`,
|
|
419
|
+
`## 🩹 [X.Y.Z]` или `## [X.Y.Z]` с необязательной датой, затем запускает Prettier.
|
|
420
|
+
Старые даты через точки и текст записей сохраняются. Неверный заголовок, включая
|
|
421
|
+
`Unreleased`, останавливает команду без удаления записей. При ошибке Prettier
|
|
422
|
+
исходный `CHANGELOG.md` восстанавливается. Файлы `.changelog/` команда не меняет;
|
|
423
|
+
commit и push не выполняет.
|
|
424
|
+
|
|
373
425
|
## 🎯 Философия
|
|
374
426
|
|
|
375
427
|
- **Простота** - минимум команд, максимум функциональности
|
package/index.js
CHANGED
|
@@ -1,161 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const { Command } = require(
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
const git = require("./src/git");
|
|
6
|
-
const release = require("./src/release");
|
|
7
|
-
const hotfix = require("./src/hotfix");
|
|
8
|
-
const changelog = require("./src/changelog");
|
|
9
|
-
const chart = require("./src/chart");
|
|
10
|
-
const token = require("./src/token");
|
|
11
|
-
const { version: pkgVersion } = require("./package.json");
|
|
12
|
-
|
|
13
|
-
async function runAction(action, ...args) {
|
|
14
|
-
try {
|
|
15
|
-
const result = await action(...args);
|
|
16
|
-
if (!result) {
|
|
17
|
-
process.exit(1);
|
|
18
|
-
}
|
|
19
|
-
} catch (error) {
|
|
20
|
-
console.error(`❌ Ошибка: ${error.message}`);
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
program
|
|
26
|
-
.name("spectrum")
|
|
27
|
-
.description("🚀 Spectrum CLI для процесса разработки")
|
|
28
|
-
.version(pkgVersion, "-v, --version");
|
|
29
|
-
|
|
30
|
-
// Команды релиза
|
|
31
|
-
const releaseCmd = program
|
|
32
|
-
.command("release")
|
|
33
|
-
.description("Команды управления релизом");
|
|
34
|
-
|
|
35
|
-
releaseCmd
|
|
36
|
-
.command("start")
|
|
37
|
-
.description("Схлопнуть fragments и атомарно отправить release commit в dev и main/master")
|
|
38
|
-
.action(() => runAction(release.releaseStart));
|
|
39
|
-
|
|
40
|
-
releaseCmd
|
|
41
|
-
.command("close")
|
|
42
|
-
.description("Свести стабильный релиз из main/master в dev")
|
|
43
|
-
.action(() => runAction(release.releaseClose));
|
|
44
|
-
|
|
45
|
-
releaseCmd
|
|
46
|
-
.command("deploy")
|
|
47
|
-
.description("Создать и отправить только стабильный тег release/X.Y.Z")
|
|
48
|
-
.action(() => runAction(git.gitCreateTagAndPush));
|
|
49
|
-
|
|
50
|
-
const hotfixCmd = program.command("hotfix").description("Изолированный цикл срочного patch-релиза");
|
|
51
|
-
|
|
52
|
-
hotfixCmd.command("start")
|
|
53
|
-
.description("Подготовить 🩹 CHANGELOG на hotfix/* или main/master, без commit, push и merge")
|
|
54
|
-
.action(() => runAction(hotfix.hotfixStart));
|
|
55
|
-
hotfixCmd.command("deploy")
|
|
56
|
-
.description("После merge хотфикса отправить stable-тег с main/master")
|
|
57
|
-
.action(() => runAction(hotfix.hotfixDeploy));
|
|
58
|
-
hotfixCmd.command("close")
|
|
59
|
-
.description("После stable pipeline свести production в dev")
|
|
60
|
-
.action(() => runAction(hotfix.hotfixClose));
|
|
61
|
-
|
|
62
|
-
// Команды changelog
|
|
63
|
-
const changelogCmd = program
|
|
64
|
-
.command("changelog")
|
|
65
|
-
.description("Команды управления changelog fragments");
|
|
66
|
-
|
|
67
|
-
changelogCmd
|
|
68
|
-
.command("append <message>")
|
|
69
|
-
.description("Создать changelog fragment с номером задачи из ветки")
|
|
70
|
-
.action((message) => runAction(() => changelog.changelogAppend(message)));
|
|
71
|
-
|
|
72
|
-
changelogCmd
|
|
73
|
-
.command("check")
|
|
74
|
-
.description("Проверить CHANGELOG.md и changelog fragments")
|
|
75
|
-
.action(() => runAction(changelog.changelogCheck));
|
|
76
|
-
|
|
77
|
-
// Команды chart
|
|
78
|
-
const chartCmd = program
|
|
79
|
-
.command("chart")
|
|
80
|
-
.description("Команды управления тегами chart");
|
|
81
|
-
|
|
82
|
-
chartCmd
|
|
83
|
-
.command("create <version>")
|
|
84
|
-
.description("Создать и отправить chart-тег (chart-<name>-<version>)")
|
|
85
|
-
.option("--force", "Разрешить версию не больше последней опубликованной")
|
|
86
|
-
.option("--wait", "Дождаться публикации версии чарта в Helm-registry")
|
|
87
|
-
.action((version, options) => runAction(() => chart.chartCreateTag(version, options)));
|
|
88
|
-
|
|
89
|
-
chartCmd
|
|
90
|
-
.command("verify <source_path>")
|
|
91
|
-
.description("Проверить пути ingress chart относительно исходников Next.js")
|
|
92
|
-
.action((sourcePath) => runAction(() => chart.chartVerify(sourcePath)));
|
|
93
|
-
|
|
94
|
-
chartCmd
|
|
95
|
-
.command("deploy")
|
|
96
|
-
.description("Задеплоить последнюю версию chart в файлы helmrelease")
|
|
97
|
-
.option("--instances <names>", "Список инстансов через запятую (по умолчанию все)")
|
|
98
|
-
.action((options) => runAction(() => chart.chartDeploy(options)));
|
|
99
|
-
|
|
100
|
-
const tokenCmd = program
|
|
101
|
-
.command("token")
|
|
102
|
-
.description("Команды управления GitLab токенами");
|
|
103
|
-
|
|
104
|
-
tokenCmd
|
|
105
|
-
.command("rotate")
|
|
106
|
-
.description("Пролить GITLAB_PRIVATE_TOKEN в CI variables через owner PAT")
|
|
107
|
-
.action(() => runAction(token.tokenRotate));
|
|
108
|
-
|
|
109
|
-
// Переопределяем help, чтобы показать кастомный формат с алиасами
|
|
110
|
-
program.configureHelp({
|
|
111
|
-
formatHelp: (cmd, helper) => {
|
|
112
|
-
const cmdUsage = helper.commandUsage(cmd);
|
|
113
|
-
const cmdDescription = helper.commandDescription(cmd);
|
|
114
|
-
const options = helper.visibleOptions(cmd);
|
|
115
|
-
const commands = helper.visibleCommands(cmd);
|
|
116
|
-
|
|
117
|
-
let output = "";
|
|
118
|
-
|
|
119
|
-
// Использование
|
|
120
|
-
if (cmdUsage) {
|
|
121
|
-
output += `Использование: ${cmdUsage}\n\n`;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Описание
|
|
125
|
-
if (cmdDescription) {
|
|
126
|
-
output += `${cmdDescription}\n\n`;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Команды с алиасами
|
|
130
|
-
if (commands.length > 0) {
|
|
131
|
-
output += "Команды:\n";
|
|
132
|
-
commands.forEach((cmd) => {
|
|
133
|
-
const nameAndArgs = cmd.name() + cmd.usage().replace(/^[^\s]+\s*/, " ");
|
|
134
|
-
const aliases = cmd.aliases();
|
|
135
|
-
const description = cmd.description();
|
|
136
|
-
|
|
137
|
-
let cmdLine = ` ${nameAndArgs}`;
|
|
138
|
-
if (aliases.length > 0) {
|
|
139
|
-
cmdLine = cmdLine.padEnd(25) + `[${aliases.join(", ")}]`;
|
|
140
|
-
}
|
|
141
|
-
cmdLine = cmdLine.padEnd(40) + description;
|
|
142
|
-
output += cmdLine + "\n";
|
|
143
|
-
});
|
|
144
|
-
output += "\n";
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Опции
|
|
148
|
-
if (options.length > 0) {
|
|
149
|
-
output += "Опции:\n";
|
|
150
|
-
options.forEach((option) => {
|
|
151
|
-
const flags = helper.optionTerm(option);
|
|
152
|
-
const description = helper.optionDescription(option);
|
|
153
|
-
output += ` ${flags.padEnd(25)} ${description}\n`;
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return output;
|
|
158
|
-
},
|
|
159
|
-
});
|
|
2
|
+
const { Command } = require('commander');
|
|
3
|
+
const { registerCommands } = require('./src/cli/commands');
|
|
4
|
+
const { configureHelp } = require('./src/cli/help');
|
|
160
5
|
|
|
6
|
+
const program = new Command();
|
|
7
|
+
registerCommands(program);
|
|
8
|
+
configureHelp(program);
|
|
161
9
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectrum-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "🚀 Modern CLI for development workflow automation - release management, versioning, and changelog generation",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
"testEnvironment": "node",
|
|
72
72
|
"collectCoverageFrom": [
|
|
73
73
|
"index.js",
|
|
74
|
-
"src/command-executor.js",
|
|
75
|
-
"src/development.js",
|
|
76
|
-
"src/utils.js"
|
|
74
|
+
"src/cli/command-executor.js",
|
|
75
|
+
"src/cli/development.js",
|
|
76
|
+
"src/common/utils.js"
|
|
77
77
|
],
|
|
78
78
|
"testMatch": [
|
|
79
79
|
"**/__tests__/**/*.js",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const { runCommand } = require('../cli/command-executor');
|
|
2
|
+
const { requireGitRepo, requireFileExists, requirePrettierAvailable, requireChangelogFormatted, requireChangelogFragments } = require('../preflight');
|
|
3
|
+
const { CHANGELOG_FILE } = require('./config');
|
|
4
|
+
const { prepareChangelogEntry, appendPreparedChangelogEntry } = require('./fragments');
|
|
5
|
+
const { writeCurrentChangelog } = require('./format');
|
|
6
|
+
function changelogAppend(message) {
|
|
7
|
+
return runCommand({
|
|
8
|
+
name: 'changelog append',
|
|
9
|
+
checks: [
|
|
10
|
+
{ name: 'git-repo', run: requireGitRepo },
|
|
11
|
+
{ name: 'changelog-exists', run: () => requireFileExists(CHANGELOG_FILE) },
|
|
12
|
+
{ name: 'prepare-fragment', dependsOn: ['git-repo', 'changelog-exists'], run: () => prepareChangelogEntry(message) }
|
|
13
|
+
],
|
|
14
|
+
steps: [
|
|
15
|
+
{ name: 'write-fragment', run: appendPreparedChangelogEntry }
|
|
16
|
+
]
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function changelogCheck() {
|
|
21
|
+
return runCommand({
|
|
22
|
+
name: 'changelog check',
|
|
23
|
+
checks: [
|
|
24
|
+
{ name: 'git-repo', run: requireGitRepo },
|
|
25
|
+
{ name: 'changelog-exists', run: () => requireFileExists(CHANGELOG_FILE) },
|
|
26
|
+
{ name: 'changelog-prettier-check', run: requireChangelogFormatted },
|
|
27
|
+
{ name: 'changelog-fragments', run: requireChangelogFragments }
|
|
28
|
+
]
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function changelogWrite() {
|
|
33
|
+
return runCommand({
|
|
34
|
+
name: 'changelog write',
|
|
35
|
+
checks: [
|
|
36
|
+
{ name: 'git-repo', run: requireGitRepo },
|
|
37
|
+
{ name: 'changelog-exists', run: () => requireFileExists(CHANGELOG_FILE) },
|
|
38
|
+
{ name: 'prettier-available', run: requirePrettierAvailable }
|
|
39
|
+
],
|
|
40
|
+
steps: [{ name: 'write-changelog', run: writeCurrentChangelog }]
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { changelogAppend, changelogCheck, changelogWrite };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const { logError, execCommand } = require('../common/utils');
|
|
3
|
+
const { CHANGELOG_FILE } = require('./config');
|
|
4
|
+
function normalizeChangelogHeadings(text) {
|
|
5
|
+
const version = '(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)';
|
|
6
|
+
const date = '(\\d{4}-\\d{2}-\\d{2}|\\d{4}\\.\\d{2}\\.\\d{2}|\\d{2}\\.\\d{2}\\.\\d{4})';
|
|
7
|
+
const releaseHeading = new RegExp(`^##[ \\t]*(?:(🚀|🩹)[ \\t]*)?\\[${version}\\](?:[ \\t]+-[ \\t]+${date})?[ \\t]*\\r?$`);
|
|
8
|
+
return text.replace(/^##(?!#)[^\n]*$/gm, (heading) => {
|
|
9
|
+
const match = releaseHeading.exec(heading);
|
|
10
|
+
if (!match) throw new Error(`Некорректный заголовок ${CHANGELOG_FILE}: ${heading.trimEnd()}`);
|
|
11
|
+
const marker = match[1] ? `${match[1]} ` : '';
|
|
12
|
+
const releaseVersion = `${match[2]}.${match[3]}.${match[4]}`;
|
|
13
|
+
const releaseDate = match[5] ? ` - ${match[5]}` : '';
|
|
14
|
+
return `## ${marker}[${releaseVersion}]${releaseDate}${heading.endsWith('\r') ? '\r' : ''}`;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function writeCurrentChangelog(context) {
|
|
19
|
+
let original;
|
|
20
|
+
let mayHaveChanged = false;
|
|
21
|
+
try {
|
|
22
|
+
original = fs.readFileSync(CHANGELOG_FILE, 'utf8');
|
|
23
|
+
const normalized = normalizeChangelogHeadings(original);
|
|
24
|
+
if (normalized !== original) {
|
|
25
|
+
mayHaveChanged = true;
|
|
26
|
+
fs.writeFileSync(CHANGELOG_FILE, normalized);
|
|
27
|
+
}
|
|
28
|
+
mayHaveChanged = true;
|
|
29
|
+
if (!execCommand(`${context.prettierRunner} --write ${CHANGELOG_FILE}`) ||
|
|
30
|
+
!execCommand(`${context.prettierRunner} --check ${CHANGELOG_FILE}`)) {
|
|
31
|
+
throw new Error('Prettier не смог отформатировать CHANGELOG.md.');
|
|
32
|
+
}
|
|
33
|
+
const formatted = fs.readFileSync(CHANGELOG_FILE, 'utf8');
|
|
34
|
+
if (normalizeChangelogHeadings(formatted) !== formatted) {
|
|
35
|
+
throw new Error('После Prettier заголовки CHANGELOG.md не соответствуют формату релизов.');
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (mayHaveChanged && original !== undefined) {
|
|
40
|
+
try {
|
|
41
|
+
fs.writeFileSync(CHANGELOG_FILE, original);
|
|
42
|
+
} catch (restoreError) {
|
|
43
|
+
logError('❌', 'Не удалось восстановить %s: %s', CHANGELOG_FILE, restoreError.message);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
logError('❌', 'Не удалось отформатировать %s: %s', CHANGELOG_FILE, error.message);
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = { normalizeChangelogHeadings, writeCurrentChangelog };
|