java.lang.RuntimeException: wXb6Vnl31u :: Ошибка для HTML= 001 003 004 005 006 007 008 009
010

Ведение версий

011 012

Платформа MyBPM состоит из двух разрабатываемых компонентов:

013 014
    015
  1. MyBPM WEB
  2. 016 017
  3. MyBPM API
  4. 018
019 020

Каждый из этих компонентов имеет свой репозиторий в 021 корпоративном хранилище. Ведение веток разработки у обоих этих 022 компонентов одинаковое. Имеется следующий набор веток:

023 024
    025
  1. dev - главная ветка разработки.
  2. 026 027
  3. dev-freeze - ветка фиксации текущего 028 разработанного функционала - этап-альфа тестирования.
  4. 029 030
  5. stage - стабильная тестовая версия - этап 031 бета-тестирования.
  6. 032 033
  7. release - ветка стабильных релизов.
  8. 034
035 036

Процесс разработки

037 038

Вся разработка ведётся на ветке dev. Тут внедряются 039 все новые функции, тестируются и исправляются ошибки. Мелкие 040 функции вводятся напрямую, а функции по больше разрабатываются в 041 отдельных ветках, ответвлённых от dev. После 042 разработки и локального тестирования, ветки сливается в 043 dev.

044 045

Например: разработчику по имени "Marat" получили сделать новую 046 функцию, которую кратко можно назвать "zoo-to-settings". Он создаёт 047 копию ветки dev и называет её:

048 049
050  dev-marat-zoo-to-settings
051  
052  
053  
054  
055 056

Далее он разрабатывает эту функцию в этой ветке. В процессе 057 разработки он должен сливать изменения сделанные другими 058 разработчиками из ветки dev в свою ветку 059 dev-marat-zoo-to-settings.

060 061

После того как он разработал и протестировал новый функционал в 062 этой ветке он сливает данную ветку в ветку dev. Если у 063 него нет доступа на push в ветку dev, то он делает 064 запрос на слияние merge-request. Обращается к старшему 065 разработчику с целью проверки разработки, и, если всё нормально, 066 старший разработчик применяет merge-request и новая 067 функция попадает в ветку dev. Если у старшего 068 разработчика есть замечания, то нужно эти замечания исправить и 069 подойти снова за слиянием в общую ветку dev. После 070 слияния в dev ветку 071 dev-marat-zoo-to-settings необходимо удалить как 072 локально, так и в репозитории.

073 074

Процесс формирования релиза

075 076

После того как в ветку dev слили весь новый 077 функционал текущего этапа разработки, ветка dev 078 фиксируется тем, что она сливается в ветку dev-freeze. 079 Процесс фиксации может затянуться из-за обилия ошибок, и в этот 080 момент могут быть завершены новые функции, назначены на следующий 081 этап, поэтому нужна новая ветка фиксации разработки. После того как 082 функционал на ветке dev-freeze проверен и, в случае 083 необходимости, исправлен, то ветка dev-freeze 084 сливается в ветку stage. На этой ветке платформа 085 начинает распространяться на тестовые среды клиентов. И, если на 086 этом этапе выявляются ошибки, то они исправляются прямо в ветке 087 stage - подобные действия называются hot-fix-ами.

088 089

Когда ветка stage окончательно стабилизирована и 090 проверена на всех тестовых средах, то её сливают в ветку 091 release.

092 093

Процесс формирования версий

094 095

Версии системы состоят из четырёх чисел (на ветке 096 dev-freeze - пять чисел), разделённых точкой, 097 например:

098 099
100  4.11.3.117
101  
102  
103  
104  
105 106

Первое число (4) обозначает главную версию самой платформы. 107 Главная версия платформы увеличивается не чаще одного раза в 108 год.

109 110

Второе число (11) обозначает либо релиз системы, либо состояние 111 тестирования. Если это число НЕЧЁТНОЕ, то данное число обозначает 112 этап тестирования или разработки (stage, 113 dev-freeze, dev). Если это число ЧЁТНОЕ, 114 до это - РЕЛИЗ.

115 116

Третье число (3) обозначает уровень тестирования. Если оно 117 НЕЧЁТНОЕ, то это альфа-тестирование или разработки (ветка 118 dev или dev-freeze). Если ЧЁТНОЕ, то это 119 бета-тестирование (ветка stage).

120 121

Четвёртое число (117) это номер текущего коммита. После каждого 122 коммита, это число увеличивается на 1.

123 124

На ветке dev-freeze имеется ПЯТЬ уровней ведения 125 версий. Первые четыре - это копия той версии с ветки 126 dev которая замораживается. А последняя - это счёт 127 фиксов в ветке для заморозки.

128 129

Первые числа нужно менять вручную. А последнее число 130 увеличивается на 1 автоматически системой CI/CD, а уменьшается 131 всегда до нуля в ручную.

132 133

Пример состояния версий на ветках:

134 135
    136
  1. dev - 4.11.7.118
  2. 137 138
  3. dev-freeze - 4.11.5.121.3 - здесь видно какая прежняя версия в 139 ветки dev была заморожена
  4. 140 141
  5. stage - 4.11.6.3
  6. 142 143
  7. release - 4.10.0.2
  8. 144
145 146

Во время разработки, изменения сбрасываются в ветку 147 dev и последнее число автоматически увеличивается на 148 единицу системой CI/CD.

149 150

Исправления на ветке dev

151 152

Ветка dev является основной веткой разработки, 153 поэтому любые изменения в ней не должны приводить к дальнейшим 154 слияниям. После появления коммита на ветке dev 155 автоматически запускается система CI/CD, и если нет ни каких ошибок 156 в модульных тестах, и проходит нормально сборка, то последнее число 157 версии (четвёртое) увеличивается на единицу.

158 159

Исправления на ветке 160 dev-freeze

161 162

Если исправляется ошибка на ветке dev-freeze, то 163 она вносится на эту ветку коммитом, и пятое число увеличивается 164 автоматически системой CI/CD на единицу.

165 166

После внесения коммита на ветку dev-freeze 167 разработчик ОБЯЗАН слить изменения по схеме:

168 169
170  dev-freeze -> dev
171  
172  
173  
174  
175 176

ВНИМАНИЕ: При таком слиянии на ветках ВЕРСИИ 177 МЕНЯТЬ НЕЛЬЗЯ - нужно оставлять такими, какие они были.

178 179

Например: если версии веток были следующие:

180 181
182  dev=4.11.7.118
183  dev-freeze=4.11.5.121.3
184  
185  
186  
187  
188 189

То сразу же после слияния dev-freeze -> dev они 190 должны остаться такими же

191 192
193  dev=4.11.7.118
194  dev-freeze=4.11.5.121.3
195  
196  
197  
198  
199 200

После чего на ветке dev запуститься CI/CD и через 201 некоторое время версия на dev увеличиться на единицу 202 так:

203 204
205  dev=4.11.7.119
206  dev-freeze=4.11.5.121.3
207  
208  
209  
210  
211 212

Хот-фиксы, или исправления на ветке 213 stage

214 215

Если исправляется ошибка на ветке stage (это 216 называется хот-фикс), то четвёрная цифра версии на ветке 217 stage автоматически увеличивается на единицу. После 218 этого разработчик ОБЯЗАН слить изменения по схеме:

219 220
221  stage -> dev-freeze
222  dev-freeze -> dev
223  
224  
225  
226  
227 228

При этих слияниях версии на ветках НУЖНО оставить 229 неизменными.

230 231

После этих слияний запуститься CI/CD на обеих ветках, и 232 последние числа версий на ветках dev и 233 dev-freeze увеличиться на единицу.

234 235

Супер-хот-фиксы, или исправления на ветке 236 release

237 238

Если исправляется ошибка на ветке release (это 239 называется супер-хот-фикс), то четвёрная цифра версии на ветке 240 release автоматически увеличивается на единицу. После 241 этого разработчик ОБЯЗАН слить изменения по схеме:

242 243
244  release -> stage
245  stage -> dev-freeze
246  dev-freeze -> dev
247  
248  
249  
250  
251 252

При этих слияниях версии на ветках НУЖНО оставить 253 неизменными.

254 255

После этого запуститься CI/CD. По окончанию работы CI/CD 256 последнее число версий на ветках dev, 257 dev-freeze и stage увеличатся на 258 единицу.

259 260

Пример ведения версий

261 262

Изменения в ветке dev должны быть проверены и 263 протестированы. При этом не должен остановиться процесс разработки 264 новых функций на платформе. Для этого предусмотрен следующий 265 механизм ведения версий:

266 267

Заморозка ветки dev

268 269

Когда в ветке dev весь необходимый на данном этапе 270 функционал реализован, то нужно его заморозить. Для этого 271 необходимо все изменения в ветке dev слить в ветку 272 dev-freeze вместе с самой версией.

273 274

Например, имеется состояние версий:

275 276
    277
  1. dev - 4.11.7.118
  2. 278 279
  3. dev-freeze - 4.11.5.34.40
  4. 280 281
  5. stage - 4.11.6.3
  6. 282 283
  7. release - 4.10.0.2
  8. 284
285 286

Поступила команда от руководителя проекта на заморозку ветки 287 dev, то изменения сливаем из dev в 288 dev-freeze и в ручную устанавливаем следующие 289 версии:

290 291
    292
  1. dev - 4.11.7.118
  2. 293 294
  3. dev-freeze - 295 4.11.7.118.0
  4. 296 297
  5. stage - 4.11.6.3
  6. 298 299
  7. release - 4.10.0.2
  8. 300
301 302

Т.е. на ветку dev-freeze ПРОСТО копируем версию с 303 ветки dev и добавляем ПЯТОЕ число равное нулю.

304 305

Дальне система CI/CD отрабатывает и увеличивает пятое число до 306 единицы, как показано ниже:

307 308
    309
  1. dev - 4.11.7.118
  2. 310 311
  3. dev-freeze - 4.11.7.118.1
  4. 312 313
  5. stage - 4.11.6.3
  6. 314 315
  7. release - 4.10.0.2
  8. 316
317 318

Дальше на dev-freeze-е могут быть найдены ошибки и исправлены 319 прямо на этой ветке. Их может быть несколько. После нескольких 320 исправлений может возникнуть следующая картина:

321 322
    323
  1. dev - 4.11.7.231
  2. 324 325
  3. dev-freeze - 4.11.7.118.18
  4. 326 327
  5. stage - 4.11.6.3
  6. 328 329
  7. release - 4.10.0.2
  8. 330
331 332

Т.е. было как минимум 18 коммитов в ветку 333 dev-freeze о чём свидетельствует пятая цифра в 334 версии.

335 336

Так же заметьте, что у ветки dev, тоже увеличилась 337 четвёртая цифра, так как в неё влили все изменения из ветки 338 dev-freeze, да и ещё в ней могли появиться новые 339 функции, предназначенные для следующего релиза.

340 341

Стабилизация нового функционала: обновление ветки 342 stage

343 344

После того как ветка dev-freeze стабилизирована, 345 поступает команда от руководителя проекта залить её в ветку 346 stage. Исполнив эту команду, должны быть следующие 347 изменения в версиях:

348 349

Было:

350 351
    352
  1. dev - 4.11.7.231
  2. 353 354
  3. dev-freeze - 4.11.7.118.18
  4. 355 356
  5. stage - 4.11.6.3
  6. 357 358
  7. release - 4.10.0.2
  8. 359
360 361

Стало:

362 363
    364
  1. dev - 4.11.9.0
  2. 365 366
  3. dev-freeze - 4.11.7.118.18
  4. 367 368
  5. stage - 4.11.8.0
  6. 369 370
  7. release - 4.10.0.2
  8. 371
372 373

Здесь показано, что в ветке stage увеличилась 374 третье число на два (с 6 до 8 - должны быть ЧЁТНЫМИ), а четвёртое 375 занулили.

376 377

Так же изменили версию в ветке dev - тоже увеличили 378 третье число на два (с 7 до 9 - должны быть НЕЧЁТНЫМИ)

379 380

После этих коммитов запуститься CI/CD на ветках dev 381 и stage и последние версии увеличатся на единицу:

382 383
    384
  1. dev - 4.11.9.1
  2. 385 386
  3. dev-freeze - 4.11.7.118.18
  4. 387 388
  5. stage - 4.11.8.1
  6. 389 390
  7. release - 4.10.0.2
  8. 391
392 393

А после нескольких исправлений может быть следующая картина:

394 395
    396
  1. dev - 4.11.9.17
  2. 397 398
  3. dev-freeze - 4.11.7.118.18
  4. 399 400
  5. stage - 4.11.8.6
  6. 401 402
  7. release - 4.10.0.2
  8. 403
404 405

Ветка dev-freeze уже не трогается и она не 406 меняется, а хот-фиксы изменяют последнее число в версии ветки 407 stage. При последующем сливании этих хот-фиксов в 408 ветку dev последнее число на этой ветке тоже 409 увеличивается на единицу. Если кто-то сольёт изменения в ветку 410 dev-freeze, то на ней тоже последнее число увеличиться 411 на единицу - это делать не обязательно, но не возбраняется.

412 413

Выпуск релиза: обновление ветки 414 release

415 416

После того как ветка stage стабилизирована и 417 хорошенько оттестирована, то от руководителя проекта поступает 418 команда на переход изменений в ветке stage в ветку 419 release. Должно быть сделано следующее:

420 421

Было:

422 423
    424
  1. dev - 4.11.9.2071
  2. 425 426
  3. dev-freeze - 4.11.7.118.31
  4. 427 428
  5. stage - 4.11.8.11
  6. 429 430
  7. release - 4.10.0.2
  8. 431
432 433

Стало:

434 435
    436
  1. dev - 4.13.1.0
  2. 437 438
  3. dev-freeze - 4.11.7.118.31
  4. 439 440
  5. stage - 4.13.2.0
  6. 441 442
  7. release - 4.12.0.0
  8. 443
444 445

Т.е. вышел новый релиз - 4.12.0.0!!!

446 447

Тут увеличилось второе число на ветке release на 448 два (с 10 до 12 - должно быть ЧЁТНЫМ) - остальные были сброшены до 449 0.

450 451

На ветках dev и stage второе число 452 было установлено на единицу БОЛЬШЕ релиза (13 - НЕЧЁТНОЕ).

453 454

Третье число на ветке dev стало единицей 455 (нечётным), а на ветке stage стало двойкой 456 (чётное).

457 458

Четвёрное число на ветках dev и stage 459 обнулили.

460 461

На ветке dev-freeze ни каких изменений НЕТ - там 462 лишь указывается какая ветка была когда-то заморожено. Так будет до 463 тех пор, пока опять не заморозят ветку dev.

464 465

После этих изменений на всех ветках запуститься CI/CD, и когда 466 он везде отработает, то будут такие изменения в версиях:

467 468
    469
  1. dev - 4.13.1.1
  2. 470 471
  3. dev-freeze - 4.11.7.118.31
  4. 472 473
  5. stage - 4.13.2.1
  6. 474 475
  7. release - 4.12.0.1
  8. 476
477 478

Инварианты

479 480

Инварианты - это условия, которые не должны соблюдаться при 481 каждой операции push.

482 483

Терминология ведения версий

484 485

Версия на ветке представляет собой набор чисел разделённых 486 точкой. Первое число - это первый уровень, второе - второй, и так 487 далее.

488 489

Базовые инварианты

490 491
    492
  1. 493

    Чётное число - это более стабильная версия чем нечётное число на 494 своём уровне ведения версий. Исключение первый уровень и 495 последний.

    496
  2. 497 498
  3. 499

    Нестабильные ветки всегда больше по версии чем стабильные - так 500 как они впереди разработки.

    501
  4. 502
503 504

Основные инварианты

505 506
    507
  1. На ветках dev, stage, 508 release - четыре уровня версии.
  2. 509 510
  3. На ветке dev-freeze - пять уровней версии.
  4. 511 512
  5. На ветке release второй уровень всегда 513 чётный.
  6. 514 515
  7. На остальных ветках второй уровень всегда нечётный.
  8. 516 517
  9. На ветке release второй уровень всегда на 1 518 меньше, чем на остальных (исключение dev-freeze).
  10. 519 520
  11. На ветке release третий уровень всегда равен 521 нулю.
  12. 522 523
  13. На ветке stage всегда третий уровень чётный.
  14. 524 525
  15. На ветке dev всегда третий уровень нечётный.
  16. 526 527
  17. На ветке dev всегда третий уровень на 1 больше, 528 чем на ветке stage.
  18. 529 530
  19. На ветке dev-freeze всегда пять уровней. Первые 531 четыре - это точная копия некого старого dev-а.
  20. 532
533
534 535 at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:80) at kz.greetgo.md_reader.core.MdConverter.prepareHtmlFileFrom(MdConverter.java:136) at kz.greetgo.md_reader.core.MdConverter.convert(MdConverter.java:208) at kz.greetgo.md_reader.controller.RenderController.downloadToc(RenderController.java:360) at kz.greetgo.md_reader.controller.RenderController.request(RenderController.java:108) at jdk.internal.reflect.GeneratedMethodAccessor3.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at kz.greetgo.md_reader.interceptors.TextReplaceFilter.doFilter(TextReplaceFilter.java:36) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.io.IOException: Server returned HTTP response code: 429 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:2000) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1589) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:677) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1397) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1333) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.startPE(XMLDTDScannerImpl.java:732) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.skipSeparator(XMLDTDScannerImpl.java:2101) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDecls(XMLDTDScannerImpl.java:2064) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.scanDTDExternalSubset(XMLDTDScannerImpl.java:299) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1165) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1040) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:943) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605) at java.xml/com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:542) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:889) at java.xml/com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:825) at java.xml/com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:247) at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:342) at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:122) at kz.greetgo.md_reader.util.MdUtil.xmlTextToDoc(MdUtil.java:71) ... 48 more