@k2works/claude-code-booster 4.17.0 → 5.1.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.
Files changed (759) hide show
  1. package/lib/assets/.claude/skills/apply-docs-structure/SKILL.md +88 -0
  2. package/lib/assets/.claude/skills/apply-docs-structure/evals/evals.json +40 -0
  3. package/lib/assets/.claude/skills/apply-docs-structure/scripts/docs_structure.py +207 -0
  4. package/lib/assets/.claude/skills/apply-okf/SKILL.md +88 -0
  5. package/lib/assets/.claude/skills/apply-okf/evals/evals.json +8 -0
  6. package/lib/assets/.claude/skills/apply-okf/scripts/__pycache__/okf_apply.cpython-314.pyc +0 -0
  7. package/lib/assets/.claude/skills/apply-okf/scripts/okf_apply.py +397 -0
  8. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/benchmark.json +20 -0
  9. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/benchmark.md +13 -0
  10. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/eval_metadata.json +14 -0
  11. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/grading.json +39 -0
  12. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/adr/001-db.md +12 -0
  13. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/adr/002-cache-strategy.md +20 -0
  14. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/adr/index.md +4 -0
  15. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/design/data-model.md +12 -0
  16. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/design/index.md +3 -0
  17. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/index.md +10 -0
  18. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/log.md +7 -0
  19. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/operation/deploy-old.md +12 -0
  20. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/operation/deploy.md +12 -0
  21. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/operation/index.md +4 -0
  22. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/docs_after/reference/OKF/345/260/216/345/205/245/343/202/254/343/202/244/343/203/211_V0.2.md +965 -0
  23. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/with_skill/outputs/report.md +76 -0
  24. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/grading.json +39 -0
  25. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/adr/001-db.md +12 -0
  26. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/adr/002-cache-strategy.md +20 -0
  27. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/adr/index.md +4 -0
  28. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/design/data-model.md +12 -0
  29. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/design/index.md +3 -0
  30. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/index.md +10 -0
  31. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/log.md +7 -0
  32. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/operation/deploy-old.md +12 -0
  33. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/operation/deploy.md +12 -0
  34. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/operation/index.md +4 -0
  35. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/docs_after/reference/OKF/345/260/216/345/205/245/343/202/254/343/202/244/343/203/211_V0.2.md +965 -0
  36. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-1-register-new-adr/without_skill/outputs/report.md +22 -0
  37. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/eval_metadata.json +13 -0
  38. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/grading.json +34 -0
  39. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/adr/001-db.md +12 -0
  40. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/adr/002-cache-strategy.md +11 -0
  41. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/adr/index.md +3 -0
  42. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/design/data-model.md +14 -0
  43. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/design/index.md +3 -0
  44. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/index.md +10 -0
  45. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/log.md +7 -0
  46. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/operation/deploy-old.md +12 -0
  47. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/operation/deploy.md +12 -0
  48. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/operation/index.md +4 -0
  49. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/docs_after/reference/OKF/345/260/216/345/205/245/343/202/254/343/202/244/343/203/211_V0.2.md +965 -0
  50. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/with_skill/outputs/report.md +61 -0
  51. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/grading.json +34 -0
  52. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/adr/001-db.md +12 -0
  53. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/adr/002-cache-strategy.md +11 -0
  54. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/adr/index.md +3 -0
  55. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/design/data-model.md +13 -0
  56. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/design/index.md +3 -0
  57. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/index.md +10 -0
  58. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/log.md +7 -0
  59. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/operation/deploy-old.md +12 -0
  60. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/operation/deploy.md +12 -0
  61. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/operation/index.md +4 -0
  62. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/docs_after/reference/OKF/345/260/216/345/205/245/343/202/254/343/202/244/343/203/211_V0.2.md +965 -0
  63. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-2-verify-reviewed-doc/without_skill/outputs/report.md +18 -0
  64. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/eval_metadata.json +13 -0
  65. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/grading.json +34 -0
  66. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/adr/001-db.md +12 -0
  67. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/adr/002-cache-strategy.md +11 -0
  68. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/adr/index.md +3 -0
  69. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/design/data-model.md +12 -0
  70. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/design/index.md +3 -0
  71. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/index.md +10 -0
  72. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/log.md +7 -0
  73. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/operation/deploy-old.md +13 -0
  74. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/operation/deploy.md +12 -0
  75. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/operation/index.md +7 -0
  76. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/docs_after/reference/OKF/345/260/216/345/205/245/343/202/254/343/202/244/343/203/211_V0.2.md +965 -0
  77. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/with_skill/outputs/report.md +83 -0
  78. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/grading.json +34 -0
  79. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/adr/001-db.md +12 -0
  80. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/adr/002-cache-strategy.md +11 -0
  81. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/adr/index.md +3 -0
  82. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/design/data-model.md +12 -0
  83. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/design/index.md +3 -0
  84. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/index.md +10 -0
  85. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/log.md +7 -0
  86. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/operation/deploy-old.md +14 -0
  87. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/operation/deploy.md +12 -0
  88. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/operation/index.md +4 -0
  89. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/docs_after/reference/OKF/345/260/216/345/205/245/343/202/254/343/202/244/343/203/211_V0.2.md +965 -0
  90. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/eval-3-deprecate-replaced-doc/without_skill/outputs/report.md +15 -0
  91. package/lib/assets/.claude/skills/apply-okf-workspace/iteration-1/review.html +1325 -0
  92. package/lib/assets/.claude/skills/closing-iteration/SKILL.md +16 -0
  93. package/lib/assets/.claude/skills/creating-adr/SKILL.md +4 -0
  94. package/lib/assets/.claude/skills/creating-journal/SKILL.md +12 -1
  95. package/lib/assets/.claude/skills/migrating-okf/SKILL.md +149 -0
  96. package/lib/assets/.claude/skills/migrating-okf/evals/evals.json +23 -0
  97. package/lib/assets/.claude/skills/migrating-okf/scripts/__pycache__/okf_check.cpython-314.pyc +0 -0
  98. package/lib/assets/.claude/skills/migrating-okf/scripts/okf_check.py +468 -0
  99. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/benchmark.json +20 -0
  100. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/benchmark.md +13 -0
  101. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/eval_metadata.json +15 -0
  102. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/grading.json +44 -0
  103. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/outputs/docs_after/adr/index.md +10 -0
  104. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/outputs/docs_after/index.md +15 -0
  105. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/outputs/docs_after/log.md +5 -0
  106. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/outputs/docs_after/reference/OKF/345/260/216/345/205/245/343/202/254/343/202/244/343/203/211_V0.2.md +966 -0
  107. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/outputs/docs_after/reference/index.md +6 -0
  108. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/outputs/docs_after/reference//343/202/210/343/201/204/343/202/275/343/203/225/343/203/210/343/202/246/343/202/247/343/202/242/343/201/250/343/201/257.md +261 -0
  109. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/outputs/docs_after/reference//343/203/252/343/203/252/343/203/274/343/202/271/343/202/254/343/202/244/343/203/211.md +480 -0
  110. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/outputs/docs_after/reference//347/222/260/345/242/203/345/244/211/346/225/260/347/256/241/347/220/206/343/202/254/343/202/244/343/203/211.md +681 -0
  111. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/with_skill/outputs/report.md +85 -0
  112. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/grading.json +44 -0
  113. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/outputs/docs_after/adr/index.md +8 -0
  114. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/outputs/docs_after/index.md +11 -0
  115. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/outputs/docs_after/log.md +7 -0
  116. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/outputs/docs_after/reference/OKF/345/260/216/345/205/245/343/202/254/343/202/244/343/203/211_V0.2.md +964 -0
  117. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/outputs/docs_after/reference/index.md +9 -0
  118. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/outputs/docs_after/reference//343/202/210/343/201/204/343/202/275/343/203/225/343/203/210/343/202/246/343/202/247/343/202/242/343/201/250/343/201/257.md +250 -0
  119. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/outputs/docs_after/reference//343/203/252/343/203/252/343/203/274/343/202/271/343/202/254/343/202/244/343/203/211.md +469 -0
  120. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/outputs/docs_after/reference//347/222/260/345/242/203/345/244/211/346/225/260/347/256/241/347/220/206/343/202/254/343/202/244/343/203/211.md +677 -0
  121. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-1-migrate-docs/without_skill/outputs/report.md +49 -0
  122. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-2-upgrade-v01-to-v02/eval_metadata.json +13 -0
  123. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-2-upgrade-v01-to-v02/with_skill/grading.json +34 -0
  124. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-2-upgrade-v01-to-v02/with_skill/outputs/knowledge_after/index.md +7 -0
  125. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-2-upgrade-v01-to-v02/with_skill/outputs/knowledge_after/log.md +7 -0
  126. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-2-upgrade-v01-to-v02/with_skill/outputs/knowledge_after/metrics/churn.md +9 -0
  127. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-2-upgrade-v01-to-v02/with_skill/outputs/knowledge_after/metrics/income-statement.md +15 -0
  128. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/eval-2-upgrade-v01-to-v02/with_skill/outputs/report.md +147 -0
  129. package/lib/assets/.claude/skills/migrating-okf-workspace/iteration-1/review.html +1325 -0
  130. package/lib/assets/.claude/skills/opening-iteration/SKILL.md +15 -0
  131. package/lib/assets/.claude/skills/orchestrating-analysis/SKILL.md +7 -1
  132. package/lib/assets/.claude/skills/orchestrating-development/SKILL.md +4 -0
  133. package/lib/assets/.claude/skills/orchestrating-operation/SKILL.md +5 -2
  134. package/lib/assets/.claude/skills/orchestrating-project/SKILL.md +6 -1
  135. package/lib/assets/.claude/skills/planning-releases/SKILL.md +2 -0
  136. package/lib/assets/.env.example +9 -0
  137. package/lib/assets/CLAUDE.md +219 -216
  138. package/lib/assets/docs/article/functional-desgin-ppp/all/01-immutability-and-data-transformation.md +9 -0
  139. package/lib/assets/docs/article/functional-desgin-ppp/all/02-function-composition.md +9 -0
  140. package/lib/assets/docs/article/functional-desgin-ppp/all/03-polymorphism.md +9 -0
  141. package/lib/assets/docs/article/functional-desgin-ppp/all/04-data-validation.md +9 -0
  142. package/lib/assets/docs/article/functional-desgin-ppp/all/05-property-based-testing.md +9 -0
  143. package/lib/assets/docs/article/functional-desgin-ppp/all/06-tdd-and-functional.md +9 -0
  144. package/lib/assets/docs/article/functional-desgin-ppp/all/07-composite-pattern.md +9 -0
  145. package/lib/assets/docs/article/functional-desgin-ppp/all/08-decorator-pattern.md +10 -1
  146. package/lib/assets/docs/article/functional-desgin-ppp/all/09-adapter-pattern.md +9 -0
  147. package/lib/assets/docs/article/functional-desgin-ppp/all/10-strategy-pattern.md +9 -0
  148. package/lib/assets/docs/article/functional-desgin-ppp/all/11-command-pattern.md +9 -0
  149. package/lib/assets/docs/article/functional-desgin-ppp/all/12-visitor-pattern.md +9 -0
  150. package/lib/assets/docs/article/functional-desgin-ppp/all/13-abstract-factory-pattern.md +9 -0
  151. package/lib/assets/docs/article/functional-desgin-ppp/all/14-abstract-server-pattern.md +9 -0
  152. package/lib/assets/docs/article/functional-desgin-ppp/all/15-gossiping-bus-drivers.md +9 -0
  153. package/lib/assets/docs/article/functional-desgin-ppp/all/16-payroll-system.md +9 -0
  154. package/lib/assets/docs/article/functional-desgin-ppp/all/17-video-rental-system.md +9 -0
  155. package/lib/assets/docs/article/functional-desgin-ppp/all/18-concurrency-system.md +9 -0
  156. package/lib/assets/docs/article/functional-desgin-ppp/all/19-wa-tor-simulation.md +10 -1
  157. package/lib/assets/docs/article/functional-desgin-ppp/all/20-pattern-interactions.md +9 -0
  158. package/lib/assets/docs/article/functional-desgin-ppp/all/21-best-practices.md +9 -0
  159. package/lib/assets/docs/article/functional-desgin-ppp/all/22-oo-to-fp-migration.md +9 -0
  160. package/lib/assets/docs/article/functional-desgin-ppp/clojure/01-immutability-and-data-transformation.md +9 -0
  161. package/lib/assets/docs/article/functional-desgin-ppp/clojure/02-function-composition.md +9 -0
  162. package/lib/assets/docs/article/functional-desgin-ppp/clojure/03-polymorphism.md +9 -0
  163. package/lib/assets/docs/article/functional-desgin-ppp/clojure/04-clojure-spec.md +9 -0
  164. package/lib/assets/docs/article/functional-desgin-ppp/clojure/05-property-based-testing.md +9 -0
  165. package/lib/assets/docs/article/functional-desgin-ppp/clojure/06-tdd-in-functional.md +9 -0
  166. package/lib/assets/docs/article/functional-desgin-ppp/clojure/07-composite-pattern.md +9 -0
  167. package/lib/assets/docs/article/functional-desgin-ppp/clojure/08-decorator-pattern.md +9 -0
  168. package/lib/assets/docs/article/functional-desgin-ppp/clojure/09-adapter-pattern.md +9 -0
  169. package/lib/assets/docs/article/functional-desgin-ppp/clojure/10-strategy-pattern.md +9 -0
  170. package/lib/assets/docs/article/functional-desgin-ppp/clojure/11-command-pattern.md +9 -0
  171. package/lib/assets/docs/article/functional-desgin-ppp/clojure/12-visitor-pattern.md +9 -0
  172. package/lib/assets/docs/article/functional-desgin-ppp/clojure/13-abstract-factory-pattern.md +9 -0
  173. package/lib/assets/docs/article/functional-desgin-ppp/clojure/14-abstract-server-pattern.md +9 -0
  174. package/lib/assets/docs/article/functional-desgin-ppp/clojure/15-gossiping-bus-drivers.md +9 -0
  175. package/lib/assets/docs/article/functional-desgin-ppp/clojure/16-payroll-system.md +9 -0
  176. package/lib/assets/docs/article/functional-desgin-ppp/clojure/17-video-rental-system.md +9 -0
  177. package/lib/assets/docs/article/functional-desgin-ppp/clojure/18-concurrency-system.md +9 -0
  178. package/lib/assets/docs/article/functional-desgin-ppp/clojure/19-wator-simulation.md +9 -0
  179. package/lib/assets/docs/article/functional-desgin-ppp/clojure/20-pattern-interactions.md +9 -0
  180. package/lib/assets/docs/article/functional-desgin-ppp/clojure/21-best-practices.md +9 -0
  181. package/lib/assets/docs/article/functional-desgin-ppp/clojure/22-oo-to-fp-migration.md +9 -0
  182. package/lib/assets/docs/article/functional-desgin-ppp/clojure/index.md +3 -3
  183. package/lib/assets/docs/article/functional-desgin-ppp/elixir/01-immutability-and-data-transformation.md +9 -0
  184. package/lib/assets/docs/article/functional-desgin-ppp/elixir/02-function-composition.md +9 -0
  185. package/lib/assets/docs/article/functional-desgin-ppp/elixir/03-polymorphism.md +9 -0
  186. package/lib/assets/docs/article/functional-desgin-ppp/elixir/04-data-validation.md +9 -0
  187. package/lib/assets/docs/article/functional-desgin-ppp/elixir/05-property-based-testing.md +9 -0
  188. package/lib/assets/docs/article/functional-desgin-ppp/elixir/06-tdd-and-fp.md +9 -0
  189. package/lib/assets/docs/article/functional-desgin-ppp/elixir/07-effects-and-pure-functions.md +9 -0
  190. package/lib/assets/docs/article/functional-desgin-ppp/elixir/08-error-handling-strategies.md +9 -0
  191. package/lib/assets/docs/article/functional-desgin-ppp/elixir/09-io-and-external-systems.md +9 -0
  192. package/lib/assets/docs/article/functional-desgin-ppp/elixir/10-concurrency-patterns.md +9 -0
  193. package/lib/assets/docs/article/functional-desgin-ppp/elixir/11-command-pattern.md +9 -0
  194. package/lib/assets/docs/article/functional-desgin-ppp/elixir/12-visitor-pattern.md +9 -0
  195. package/lib/assets/docs/article/functional-desgin-ppp/elixir/13-abstract-factory-pattern.md +9 -0
  196. package/lib/assets/docs/article/functional-desgin-ppp/elixir/14-abstract-server-pattern.md +9 -0
  197. package/lib/assets/docs/article/functional-desgin-ppp/elixir/15-gossiping-bus-drivers.md +9 -0
  198. package/lib/assets/docs/article/functional-desgin-ppp/elixir/16-payroll-system.md +9 -0
  199. package/lib/assets/docs/article/functional-desgin-ppp/elixir/17-video-rental-system.md +9 -0
  200. package/lib/assets/docs/article/functional-desgin-ppp/elixir/18-concurrency-system.md +9 -0
  201. package/lib/assets/docs/article/functional-desgin-ppp/elixir/19-wator-simulation.md +9 -0
  202. package/lib/assets/docs/article/functional-desgin-ppp/elixir/20-pattern-interactions.md +9 -0
  203. package/lib/assets/docs/article/functional-desgin-ppp/elixir/21-best-practices.md +9 -0
  204. package/lib/assets/docs/article/functional-desgin-ppp/elixir/22-oo-to-fp-migration.md +9 -0
  205. package/lib/assets/docs/article/functional-desgin-ppp/elixir/index.md +22 -22
  206. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/01-immutability-and-data-transformation.md +9 -0
  207. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/02-function-composition.md +9 -0
  208. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/03-polymorphism.md +9 -0
  209. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/04-data-validation.md +9 -0
  210. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/05-property-based-testing.md +9 -0
  211. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/06-tdd-functional.md +9 -0
  212. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/07-composite-pattern.md +9 -0
  213. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/08-decorator-pattern.md +9 -0
  214. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/09-adapter-pattern.md +9 -0
  215. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/10-strategy-pattern.md +9 -0
  216. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/11-command-pattern.md +9 -0
  217. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/12-visitor-pattern.md +9 -0
  218. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/13-abstract-factory-pattern.md +9 -0
  219. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/14-abstract-server-pattern.md +9 -0
  220. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/15-gossiping-bus-drivers.md +9 -0
  221. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/16-payroll-system.md +9 -0
  222. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/17-video-rental-system.md +9 -0
  223. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/18-concurrency-system.md +9 -0
  224. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/19-wator-simulation.md +9 -0
  225. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/20-pattern-interactions.md +9 -0
  226. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/21-best-practices.md +9 -0
  227. package/lib/assets/docs/article/functional-desgin-ppp/fsharp/22-oo-to-fp-migration.md +9 -0
  228. package/lib/assets/docs/article/functional-desgin-ppp/haskell/01-immutability-and-data-transformation.md +9 -0
  229. package/lib/assets/docs/article/functional-desgin-ppp/haskell/02-function-composition.md +9 -0
  230. package/lib/assets/docs/article/functional-desgin-ppp/haskell/03-polymorphism.md +9 -0
  231. package/lib/assets/docs/article/functional-desgin-ppp/haskell/04-data-validation.md +9 -0
  232. package/lib/assets/docs/article/functional-desgin-ppp/haskell/05-property-based-testing.md +9 -0
  233. package/lib/assets/docs/article/functional-desgin-ppp/haskell/06-tdd-functional.md +9 -0
  234. package/lib/assets/docs/article/functional-desgin-ppp/haskell/07-composite-pattern.md +9 -0
  235. package/lib/assets/docs/article/functional-desgin-ppp/haskell/08-decorator-pattern.md +9 -0
  236. package/lib/assets/docs/article/functional-desgin-ppp/haskell/09-adapter-pattern.md +9 -0
  237. package/lib/assets/docs/article/functional-desgin-ppp/haskell/10-strategy-pattern.md +9 -0
  238. package/lib/assets/docs/article/functional-desgin-ppp/haskell/11-command-pattern.md +9 -0
  239. package/lib/assets/docs/article/functional-desgin-ppp/haskell/12-visitor-pattern.md +9 -0
  240. package/lib/assets/docs/article/functional-desgin-ppp/haskell/13-abstract-factory-pattern.md +9 -0
  241. package/lib/assets/docs/article/functional-desgin-ppp/haskell/14-abstract-server-pattern.md +9 -0
  242. package/lib/assets/docs/article/functional-desgin-ppp/haskell/15-gossiping-bus-drivers.md +9 -0
  243. package/lib/assets/docs/article/functional-desgin-ppp/haskell/16-payroll-system.md +9 -0
  244. package/lib/assets/docs/article/functional-desgin-ppp/haskell/17-video-rental-system.md +9 -0
  245. package/lib/assets/docs/article/functional-desgin-ppp/haskell/18-concurrency-system.md +9 -0
  246. package/lib/assets/docs/article/functional-desgin-ppp/haskell/19-wator-simulation.md +9 -0
  247. package/lib/assets/docs/article/functional-desgin-ppp/haskell/20-pattern-interactions.md +9 -0
  248. package/lib/assets/docs/article/functional-desgin-ppp/haskell/21-best-practices.md +9 -0
  249. package/lib/assets/docs/article/functional-desgin-ppp/haskell/22-oo-to-fp-migration.md +9 -0
  250. package/lib/assets/docs/article/functional-desgin-ppp/rust/01-immutability-and-data-transformation.md +9 -0
  251. package/lib/assets/docs/article/functional-desgin-ppp/rust/02-function-composition.md +9 -0
  252. package/lib/assets/docs/article/functional-desgin-ppp/rust/03-polymorphism.md +9 -0
  253. package/lib/assets/docs/article/functional-desgin-ppp/rust/04-data-validation.md +9 -0
  254. package/lib/assets/docs/article/functional-desgin-ppp/rust/05-property-based-testing.md +9 -0
  255. package/lib/assets/docs/article/functional-desgin-ppp/rust/06-tdd-and-functional.md +9 -0
  256. package/lib/assets/docs/article/functional-desgin-ppp/rust/07-composite-pattern.md +9 -0
  257. package/lib/assets/docs/article/functional-desgin-ppp/rust/08-decorator-pattern.md +9 -0
  258. package/lib/assets/docs/article/functional-desgin-ppp/rust/09-adapter-pattern.md +9 -0
  259. package/lib/assets/docs/article/functional-desgin-ppp/rust/10-strategy-pattern.md +9 -0
  260. package/lib/assets/docs/article/functional-desgin-ppp/rust/11-command-pattern.md +9 -0
  261. package/lib/assets/docs/article/functional-desgin-ppp/rust/12-visitor-pattern.md +9 -0
  262. package/lib/assets/docs/article/functional-desgin-ppp/rust/13-abstract-factory-pattern.md +9 -0
  263. package/lib/assets/docs/article/functional-desgin-ppp/rust/14-abstract-server-pattern.md +9 -0
  264. package/lib/assets/docs/article/functional-desgin-ppp/rust/15-gossiping-bus-drivers.md +9 -0
  265. package/lib/assets/docs/article/functional-desgin-ppp/rust/16-payroll-system.md +9 -0
  266. package/lib/assets/docs/article/functional-desgin-ppp/rust/17-video-rental-system.md +9 -0
  267. package/lib/assets/docs/article/functional-desgin-ppp/rust/18-concurrency-system.md +9 -0
  268. package/lib/assets/docs/article/functional-desgin-ppp/rust/19-wator-simulation.md +9 -0
  269. package/lib/assets/docs/article/functional-desgin-ppp/rust/20-pattern-interactions.md +9 -0
  270. package/lib/assets/docs/article/functional-desgin-ppp/rust/21-best-practices.md +9 -0
  271. package/lib/assets/docs/article/functional-desgin-ppp/rust/22-oo-to-fp-migration.md +9 -0
  272. package/lib/assets/docs/article/functional-desgin-ppp/scala/01-immutability-and-data-transformation.md +9 -0
  273. package/lib/assets/docs/article/functional-desgin-ppp/scala/02-function-composition.md +9 -0
  274. package/lib/assets/docs/article/functional-desgin-ppp/scala/03-polymorphism.md +9 -0
  275. package/lib/assets/docs/article/functional-desgin-ppp/scala/04-data-validation.md +9 -0
  276. package/lib/assets/docs/article/functional-desgin-ppp/scala/05-property-based-testing.md +9 -0
  277. package/lib/assets/docs/article/functional-desgin-ppp/scala/06-tdd-functional.md +9 -0
  278. package/lib/assets/docs/article/functional-desgin-ppp/scala/07-composite-pattern.md +9 -0
  279. package/lib/assets/docs/article/functional-desgin-ppp/scala/08-decorator-pattern.md +9 -0
  280. package/lib/assets/docs/article/functional-desgin-ppp/scala/09-adapter-pattern.md +9 -0
  281. package/lib/assets/docs/article/functional-desgin-ppp/scala/10-strategy-pattern.md +9 -0
  282. package/lib/assets/docs/article/functional-desgin-ppp/scala/11-command-pattern.md +9 -0
  283. package/lib/assets/docs/article/functional-desgin-ppp/scala/12-visitor-pattern.md +9 -0
  284. package/lib/assets/docs/article/functional-desgin-ppp/scala/13-abstract-factory-pattern.md +9 -0
  285. package/lib/assets/docs/article/functional-desgin-ppp/scala/14-abstract-server-pattern.md +9 -0
  286. package/lib/assets/docs/article/functional-desgin-ppp/scala/15-gossiping-bus-drivers.md +9 -0
  287. package/lib/assets/docs/article/functional-desgin-ppp/scala/16-payroll-system.md +9 -0
  288. package/lib/assets/docs/article/functional-desgin-ppp/scala/17-video-rental-system.md +9 -0
  289. package/lib/assets/docs/article/functional-desgin-ppp/scala/18-concurrency-system.md +9 -0
  290. package/lib/assets/docs/article/functional-desgin-ppp/scala/19-wator-simulation.md +9 -0
  291. package/lib/assets/docs/article/functional-desgin-ppp/scala/20-pattern-interactions.md +9 -0
  292. package/lib/assets/docs/article/functional-desgin-ppp/scala/21-best-practices.md +9 -0
  293. package/lib/assets/docs/article/functional-desgin-ppp/scala/22-oo-to-fp-migration.md +9 -0
  294. package/lib/assets/docs/article/getting-start-docker-kubernetes/01-container-and-docker-basics.md +341 -332
  295. package/lib/assets/docs/article/getting-start-docker-kubernetes/02-container-deployment.md +785 -776
  296. package/lib/assets/docs/article/getting-start-docker-kubernetes/03-practical-container-build-deploy.md +466 -457
  297. package/lib/assets/docs/article/getting-start-docker-kubernetes/04-multi-container-application.md +878 -869
  298. package/lib/assets/docs/article/getting-start-docker-kubernetes/05-kubernetes-introduction.md +585 -576
  299. package/lib/assets/docs/article/getting-start-docker-kubernetes/06-kubernetes-deploy-cluster.md +620 -611
  300. package/lib/assets/docs/article/getting-start-docker-kubernetes/07-kubernetes-advanced.md +621 -612
  301. package/lib/assets/docs/article/getting-start-docker-kubernetes/08-kubernetes-packaging.md +518 -509
  302. package/lib/assets/docs/article/getting-start-docker-kubernetes/09-container-operations.md +546 -537
  303. package/lib/assets/docs/article/getting-start-docker-kubernetes/10-optimal-container-image.md +640 -631
  304. package/lib/assets/docs/article/getting-start-docker-kubernetes/11-continuous-delivery.md +607 -598
  305. package/lib/assets/docs/article/getting-start-docker-kubernetes/12-container-use-cases.md +463 -454
  306. package/lib/assets/docs/article/getting-start-docker-kubernetes/13-case-monolith-compose-vs-kustomize.md +346 -337
  307. package/lib/assets/docs/article/getting-start-docker-kubernetes/14-case-event-driven-kustomize-vs-helm.md +324 -315
  308. package/lib/assets/docs/article/getting-start-docker-kubernetes/15-case-escqrs-axon-kustomize-vs-helm.md +297 -288
  309. package/lib/assets/docs/article/getting-start-docker-kubernetes/16-case-escqrs-kafka-kustomize-vs-helm.md +256 -247
  310. package/lib/assets/docs/article/getting-start-docker-kubernetes/17-case-comparison-summary.md +141 -132
  311. package/lib/assets/docs/article/getting-start-docker-kubernetes/18-case-load-testing.md +303 -294
  312. package/lib/assets/docs/article/getting-start-docker-kubernetes/appendix-a-dev-tools-setup.md +274 -265
  313. package/lib/assets/docs/article/getting-start-docker-kubernetes/appendix-b-orchestration-environments.md +530 -521
  314. package/lib/assets/docs/article/getting-start-docker-kubernetes/appendix-c-tips.md +519 -510
  315. package/lib/assets/docs/article/getting-start-docker-kubernetes/outline.md +220 -211
  316. package/lib/assets/docs/article/getting-start-tdd/clojure/01-todo-list-and-first-test.md +9 -0
  317. package/lib/assets/docs/article/getting-start-tdd/clojure/02-fake-it-and-triangulation.md +9 -0
  318. package/lib/assets/docs/article/getting-start-tdd/clojure/03-obvious-implementation-and-refactoring.md +9 -0
  319. package/lib/assets/docs/article/getting-start-tdd/clojure/04-version-control-and-conventional-commits.md +9 -0
  320. package/lib/assets/docs/article/getting-start-tdd/clojure/05-package-management-and-static-analysis.md +9 -0
  321. package/lib/assets/docs/article/getting-start-tdd/clojure/06-task-runner-and-ci-cd.md +9 -0
  322. package/lib/assets/docs/article/getting-start-tdd/clojure/07-protocols-and-records.md +9 -0
  323. package/lib/assets/docs/article/getting-start-tdd/clojure/08-multimethods-and-design-patterns.md +9 -0
  324. package/lib/assets/docs/article/getting-start-tdd/clojure/09-namespaces-and-module-design.md +9 -0
  325. package/lib/assets/docs/article/getting-start-tdd/clojure/10-higher-order-functions-and-composition.md +9 -0
  326. package/lib/assets/docs/article/getting-start-tdd/clojure/11-persistent-data-and-pipeline.md +9 -0
  327. package/lib/assets/docs/article/getting-start-tdd/clojure/12-error-handling-and-spec.md +9 -0
  328. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter01.md +9 -0
  329. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter02.md +9 -0
  330. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter03.md +9 -0
  331. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter04.md +9 -0
  332. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter05.md +9 -0
  333. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter06.md +9 -0
  334. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter07.md +9 -0
  335. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter08.md +9 -0
  336. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter09.md +9 -0
  337. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter10.md +9 -0
  338. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter11.md +9 -0
  339. package/lib/assets/docs/article/getting-start-tdd/csharp/chapter12.md +9 -0
  340. package/lib/assets/docs/article/getting-start-tdd/elixir/01-todo-list-and-first-test.md +9 -0
  341. package/lib/assets/docs/article/getting-start-tdd/elixir/02-fake-it-and-triangulation.md +9 -0
  342. package/lib/assets/docs/article/getting-start-tdd/elixir/03-obvious-implementation-and-refactoring.md +9 -0
  343. package/lib/assets/docs/article/getting-start-tdd/elixir/04-version-control-and-conventional-commits.md +9 -0
  344. package/lib/assets/docs/article/getting-start-tdd/elixir/05-package-management-and-static-analysis.md +9 -0
  345. package/lib/assets/docs/article/getting-start-tdd/elixir/06-task-runner-and-ci-cd.md +9 -0
  346. package/lib/assets/docs/article/getting-start-tdd/elixir/07-structs-and-protocols.md +9 -0
  347. package/lib/assets/docs/article/getting-start-tdd/elixir/08-pattern-matching-and-guards.md +9 -0
  348. package/lib/assets/docs/article/getting-start-tdd/elixir/09-module-design-and-behaviours.md +9 -0
  349. package/lib/assets/docs/article/getting-start-tdd/elixir/10-higher-order-functions-and-pipeline.md +9 -0
  350. package/lib/assets/docs/article/getting-start-tdd/elixir/11-stream-and-lazy-evaluation.md +9 -0
  351. package/lib/assets/docs/article/getting-start-tdd/elixir/12-error-handling-and-with.md +9 -0
  352. package/lib/assets/docs/article/getting-start-tdd/elixir/index.md +2 -2
  353. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter01.md +9 -0
  354. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter02.md +9 -0
  355. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter03.md +9 -0
  356. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter04.md +9 -0
  357. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter05.md +9 -0
  358. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter06.md +9 -0
  359. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter07.md +9 -0
  360. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter08.md +9 -0
  361. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter09.md +9 -0
  362. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter10.md +9 -0
  363. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter11.md +9 -0
  364. package/lib/assets/docs/article/getting-start-tdd/fsharp/chapter12.md +9 -0
  365. package/lib/assets/docs/article/getting-start-tdd/go/01-todo-list-and-first-test.md +9 -0
  366. package/lib/assets/docs/article/getting-start-tdd/go/02-fake-it-and-triangulation.md +9 -0
  367. package/lib/assets/docs/article/getting-start-tdd/go/03-obvious-implementation-and-refactoring.md +9 -0
  368. package/lib/assets/docs/article/getting-start-tdd/go/04-version-control-and-conventional-commits.md +9 -0
  369. package/lib/assets/docs/article/getting-start-tdd/go/05-package-management-and-static-analysis.md +9 -0
  370. package/lib/assets/docs/article/getting-start-tdd/go/06-task-runner-and-ci-cd.md +9 -0
  371. package/lib/assets/docs/article/getting-start-tdd/go/07-encapsulation-and-polymorphism.md +8 -0
  372. package/lib/assets/docs/article/getting-start-tdd/go/08-design-patterns.md +8 -0
  373. package/lib/assets/docs/article/getting-start-tdd/go/09-solid-principles-and-module-design.md +8 -0
  374. package/lib/assets/docs/article/getting-start-tdd/go/10-higher-order-functions-and-composition.md +8 -0
  375. package/lib/assets/docs/article/getting-start-tdd/go/11-immutable-data-and-pipeline.md +8 -0
  376. package/lib/assets/docs/article/getting-start-tdd/go/12-error-handling-and-type-safety.md +8 -0
  377. package/lib/assets/docs/article/getting-start-tdd/haskell/01-todo-list-and-first-test.md +9 -0
  378. package/lib/assets/docs/article/getting-start-tdd/haskell/02-fake-it-and-triangulation.md +9 -0
  379. package/lib/assets/docs/article/getting-start-tdd/haskell/03-obvious-implementation-and-refactoring.md +9 -0
  380. package/lib/assets/docs/article/getting-start-tdd/haskell/04-version-control-and-conventional-commits.md +9 -0
  381. package/lib/assets/docs/article/getting-start-tdd/haskell/05-package-management-and-static-analysis.md +9 -0
  382. package/lib/assets/docs/article/getting-start-tdd/haskell/06-task-runner-and-ci-cd.md +9 -0
  383. package/lib/assets/docs/article/getting-start-tdd/haskell/07-algebraic-data-types-and-type-classes.md +9 -0
  384. package/lib/assets/docs/article/getting-start-tdd/haskell/08-pattern-matching-and-guards.md +9 -0
  385. package/lib/assets/docs/article/getting-start-tdd/haskell/09-module-design-and-smart-constructors.md +9 -0
  386. package/lib/assets/docs/article/getting-start-tdd/haskell/10-higher-order-functions-and-currying.md +9 -0
  387. package/lib/assets/docs/article/getting-start-tdd/haskell/11-function-composition-and-point-free.md +9 -0
  388. package/lib/assets/docs/article/getting-start-tdd/haskell/12-monad-and-error-handling.md +9 -0
  389. package/lib/assets/docs/article/getting-start-tdd/integration/01-language-overview.md +9 -0
  390. package/lib/assets/docs/article/getting-start-tdd/integration/02-test-framework-comparison.md +9 -0
  391. package/lib/assets/docs/article/getting-start-tdd/integration/03-tdd-pattern-comparison.md +9 -0
  392. package/lib/assets/docs/article/getting-start-tdd/integration/04-type-system-comparison.md +9 -0
  393. package/lib/assets/docs/article/getting-start-tdd/integration/05-dev-environment-comparison.md +9 -0
  394. package/lib/assets/docs/article/getting-start-tdd/integration/06-learning-roadmap.md +9 -0
  395. package/lib/assets/docs/article/getting-start-tdd/java/01-todo-list-and-first-test.md +9 -0
  396. package/lib/assets/docs/article/getting-start-tdd/java/02-fake-it-and-triangulation.md +9 -0
  397. package/lib/assets/docs/article/getting-start-tdd/java/03-obvious-implementation-and-refactoring.md +9 -0
  398. package/lib/assets/docs/article/getting-start-tdd/java/04-version-control-and-conventional-commits.md +9 -0
  399. package/lib/assets/docs/article/getting-start-tdd/java/05-package-management-and-static-analysis.md +9 -0
  400. package/lib/assets/docs/article/getting-start-tdd/java/06-task-runner-and-ci-cd.md +9 -0
  401. package/lib/assets/docs/article/getting-start-tdd/java/07-encapsulation-and-polymorphism.md +9 -0
  402. package/lib/assets/docs/article/getting-start-tdd/java/08-design-patterns.md +9 -0
  403. package/lib/assets/docs/article/getting-start-tdd/java/09-solid-principles-and-module-design.md +9 -0
  404. package/lib/assets/docs/article/getting-start-tdd/java/10-higher-order-functions-and-composition.md +9 -0
  405. package/lib/assets/docs/article/getting-start-tdd/java/11-immutable-data-and-pipeline.md +9 -0
  406. package/lib/assets/docs/article/getting-start-tdd/java/12-error-handling-and-type-safety.md +9 -0
  407. package/lib/assets/docs/article/getting-start-tdd/node/01-todo-list-and-first-test.md +9 -0
  408. package/lib/assets/docs/article/getting-start-tdd/node/02-fake-it-and-triangulation.md +9 -0
  409. package/lib/assets/docs/article/getting-start-tdd/node/03-obvious-implementation-and-refactoring.md +9 -0
  410. package/lib/assets/docs/article/getting-start-tdd/node/04-version-control-and-conventional-commits.md +9 -0
  411. package/lib/assets/docs/article/getting-start-tdd/node/05-package-management-and-static-analysis.md +9 -0
  412. package/lib/assets/docs/article/getting-start-tdd/node/06-task-runner-and-ci-cd.md +9 -0
  413. package/lib/assets/docs/article/getting-start-tdd/node/07-encapsulation-and-polymorphism.md +9 -0
  414. package/lib/assets/docs/article/getting-start-tdd/node/08-design-patterns.md +9 -0
  415. package/lib/assets/docs/article/getting-start-tdd/node/09-solid-principles-and-module-design.md +9 -0
  416. package/lib/assets/docs/article/getting-start-tdd/node/10-higher-order-functions-and-composition.md +9 -0
  417. package/lib/assets/docs/article/getting-start-tdd/node/11-immutable-data-and-pipeline.md +9 -0
  418. package/lib/assets/docs/article/getting-start-tdd/node/12-error-handling-and-type-safety.md +9 -0
  419. package/lib/assets/docs/article/getting-start-tdd/php/01-todo-list-and-first-test.md +9 -0
  420. package/lib/assets/docs/article/getting-start-tdd/php/02-fake-it-and-triangulation.md +9 -0
  421. package/lib/assets/docs/article/getting-start-tdd/php/03-obvious-implementation-and-refactoring.md +9 -0
  422. package/lib/assets/docs/article/getting-start-tdd/php/04-version-control-and-conventional-commits.md +9 -0
  423. package/lib/assets/docs/article/getting-start-tdd/php/05-package-management-and-static-analysis.md +9 -0
  424. package/lib/assets/docs/article/getting-start-tdd/php/06-task-runner-and-ci-cd.md +9 -0
  425. package/lib/assets/docs/article/getting-start-tdd/php/07-encapsulation-and-polymorphism.md +8 -0
  426. package/lib/assets/docs/article/getting-start-tdd/php/08-design-patterns.md +8 -0
  427. package/lib/assets/docs/article/getting-start-tdd/php/09-solid-principles-and-module-design.md +8 -0
  428. package/lib/assets/docs/article/getting-start-tdd/php/10-higher-order-functions-and-composition.md +8 -0
  429. package/lib/assets/docs/article/getting-start-tdd/php/11-immutable-data-and-pipeline.md +8 -0
  430. package/lib/assets/docs/article/getting-start-tdd/php/12-error-handling-and-type-safety.md +8 -0
  431. package/lib/assets/docs/article/getting-start-tdd/python/01-todo-list-and-first-test.md +9 -0
  432. package/lib/assets/docs/article/getting-start-tdd/python/02-fake-it-and-triangulation.md +9 -0
  433. package/lib/assets/docs/article/getting-start-tdd/python/03-obvious-implementation-and-refactoring.md +9 -0
  434. package/lib/assets/docs/article/getting-start-tdd/python/04-version-control-and-conventional-commits.md +9 -0
  435. package/lib/assets/docs/article/getting-start-tdd/python/05-package-management-and-static-analysis.md +9 -0
  436. package/lib/assets/docs/article/getting-start-tdd/python/06-task-runner-and-ci-cd.md +9 -0
  437. package/lib/assets/docs/article/getting-start-tdd/python/07-encapsulation-and-polymorphism.md +9 -0
  438. package/lib/assets/docs/article/getting-start-tdd/python/08-design-patterns.md +9 -0
  439. package/lib/assets/docs/article/getting-start-tdd/python/09-solid-principles-and-module-design.md +9 -0
  440. package/lib/assets/docs/article/getting-start-tdd/python/10-higher-order-functions-and-composition.md +9 -0
  441. package/lib/assets/docs/article/getting-start-tdd/python/11-immutable-data-and-pipeline.md +9 -0
  442. package/lib/assets/docs/article/getting-start-tdd/python/12-error-handling-and-type-safety.md +9 -0
  443. package/lib/assets/docs/article/getting-start-tdd/ruby/01-todo-list-and-first-test.md +9 -0
  444. package/lib/assets/docs/article/getting-start-tdd/ruby/02-fake-it-and-triangulation.md +9 -0
  445. package/lib/assets/docs/article/getting-start-tdd/ruby/03-obvious-implementation-and-refactoring.md +9 -0
  446. package/lib/assets/docs/article/getting-start-tdd/ruby/04-version-control-and-conventional-commits.md +9 -0
  447. package/lib/assets/docs/article/getting-start-tdd/ruby/05-package-management-and-static-analysis.md +9 -0
  448. package/lib/assets/docs/article/getting-start-tdd/ruby/06-task-runner-and-ci-cd.md +9 -0
  449. package/lib/assets/docs/article/getting-start-tdd/ruby/07-encapsulation-and-polymorphism.md +9 -0
  450. package/lib/assets/docs/article/getting-start-tdd/ruby/08-design-patterns.md +9 -0
  451. package/lib/assets/docs/article/getting-start-tdd/ruby/09-solid-principles-and-module-design.md +9 -0
  452. package/lib/assets/docs/article/getting-start-tdd/ruby/10-higher-order-functions-and-composition.md +9 -0
  453. package/lib/assets/docs/article/getting-start-tdd/ruby/11-immutable-data-and-pipeline.md +9 -0
  454. package/lib/assets/docs/article/getting-start-tdd/ruby/12-error-handling-and-type-safety.md +9 -0
  455. package/lib/assets/docs/article/getting-start-tdd/rust/01-todo-list-and-first-test.md +9 -0
  456. package/lib/assets/docs/article/getting-start-tdd/rust/02-fake-it-and-triangulation.md +9 -0
  457. package/lib/assets/docs/article/getting-start-tdd/rust/03-obvious-implementation-and-refactoring.md +9 -0
  458. package/lib/assets/docs/article/getting-start-tdd/rust/04-version-control-and-conventional-commits.md +9 -0
  459. package/lib/assets/docs/article/getting-start-tdd/rust/05-package-management-and-static-analysis.md +9 -0
  460. package/lib/assets/docs/article/getting-start-tdd/rust/06-task-runner-and-ci-cd.md +9 -0
  461. package/lib/assets/docs/article/getting-start-tdd/rust/07-encapsulation-and-polymorphism.md +9 -0
  462. package/lib/assets/docs/article/getting-start-tdd/rust/08-design-patterns.md +9 -0
  463. package/lib/assets/docs/article/getting-start-tdd/rust/09-solid-principles-and-module-design.md +9 -0
  464. package/lib/assets/docs/article/getting-start-tdd/rust/10-higher-order-functions-and-composition.md +9 -0
  465. package/lib/assets/docs/article/getting-start-tdd/rust/11-immutable-data-and-pipeline.md +9 -0
  466. package/lib/assets/docs/article/getting-start-tdd/rust/12-error-handling-and-type-safety.md +9 -0
  467. package/lib/assets/docs/article/getting-start-tdd/scala/01-todo-list-and-first-test.md +9 -0
  468. package/lib/assets/docs/article/getting-start-tdd/scala/02-fake-it-and-triangulation.md +9 -0
  469. package/lib/assets/docs/article/getting-start-tdd/scala/03-obvious-implementation-and-refactoring.md +9 -0
  470. package/lib/assets/docs/article/getting-start-tdd/scala/04-version-control-and-conventional-commits.md +9 -0
  471. package/lib/assets/docs/article/getting-start-tdd/scala/05-package-management-and-static-analysis.md +9 -0
  472. package/lib/assets/docs/article/getting-start-tdd/scala/06-task-runner-and-ci-cd.md +9 -0
  473. package/lib/assets/docs/article/getting-start-tdd/scala/07-case-classes-and-traits.md +9 -0
  474. package/lib/assets/docs/article/getting-start-tdd/scala/08-pattern-matching-and-sealed-traits.md +9 -0
  475. package/lib/assets/docs/article/getting-start-tdd/scala/09-packages-and-module-design.md +9 -0
  476. package/lib/assets/docs/article/getting-start-tdd/scala/10-higher-order-functions-and-composition.md +9 -0
  477. package/lib/assets/docs/article/getting-start-tdd/scala/11-collections-and-lazy-evaluation.md +9 -0
  478. package/lib/assets/docs/article/getting-start-tdd/scala/12-error-handling-and-type-safety.md +9 -0
  479. package/lib/assets/docs/article/grokking-concurrency/all/index.md +0 -1
  480. package/lib/assets/docs/article/grokking-concurrency/all/part-1-ch02-sequential.md +9 -0
  481. package/lib/assets/docs/article/grokking-concurrency/all/part-2-ch04-05-threads.md +9 -0
  482. package/lib/assets/docs/article/grokking-concurrency/all/part-3-ch06-multitasking.md +9 -0
  483. package/lib/assets/docs/article/grokking-concurrency/all/part-4-ch07-parallel-patterns.md +9 -0
  484. package/lib/assets/docs/article/grokking-concurrency/all/part-5-ch08-09-synchronization.md +9 -0
  485. package/lib/assets/docs/article/grokking-concurrency/all/part-6-ch10-11-nonblocking-io.md +9 -0
  486. package/lib/assets/docs/article/grokking-concurrency/all/part-7-ch12-async.md +9 -0
  487. package/lib/assets/docs/article/grokking-concurrency/all/part-8-ch13-mapreduce.md +9 -0
  488. package/lib/assets/docs/article/grokking-concurrency/clojure/index.md +0 -10
  489. package/lib/assets/docs/article/grokking-concurrency/clojure/part-1.md +6 -7
  490. package/lib/assets/docs/article/grokking-concurrency/clojure/part-2.md +6 -7
  491. package/lib/assets/docs/article/grokking-concurrency/clojure/part-3.md +6 -7
  492. package/lib/assets/docs/article/grokking-concurrency/clojure/part-4.md +6 -7
  493. package/lib/assets/docs/article/grokking-concurrency/clojure/part-5.md +6 -7
  494. package/lib/assets/docs/article/grokking-concurrency/clojure/part-6.md +6 -7
  495. package/lib/assets/docs/article/grokking-concurrency/clojure/part-7.md +6 -7
  496. package/lib/assets/docs/article/grokking-concurrency/clojure/part-8.md +6 -7
  497. package/lib/assets/docs/article/grokking-concurrency/csharp/index.md +0 -10
  498. package/lib/assets/docs/article/grokking-concurrency/csharp/part-1.md +6 -7
  499. package/lib/assets/docs/article/grokking-concurrency/csharp/part-2.md +6 -7
  500. package/lib/assets/docs/article/grokking-concurrency/csharp/part-3.md +6 -7
  501. package/lib/assets/docs/article/grokking-concurrency/csharp/part-4.md +6 -7
  502. package/lib/assets/docs/article/grokking-concurrency/csharp/part-5.md +6 -7
  503. package/lib/assets/docs/article/grokking-concurrency/csharp/part-6.md +6 -7
  504. package/lib/assets/docs/article/grokking-concurrency/csharp/part-7.md +6 -7
  505. package/lib/assets/docs/article/grokking-concurrency/csharp/part-8.md +6 -7
  506. package/lib/assets/docs/article/grokking-concurrency/fsharp/index.md +0 -10
  507. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-1.md +6 -7
  508. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-2.md +6 -7
  509. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-3.md +6 -7
  510. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-4.md +6 -7
  511. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-5.md +6 -7
  512. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-6.md +6 -7
  513. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-7.md +6 -7
  514. package/lib/assets/docs/article/grokking-concurrency/fsharp/part-8.md +6 -7
  515. package/lib/assets/docs/article/grokking-concurrency/haskell/index.md +0 -10
  516. package/lib/assets/docs/article/grokking-concurrency/haskell/part-1.md +6 -7
  517. package/lib/assets/docs/article/grokking-concurrency/haskell/part-2.md +6 -7
  518. package/lib/assets/docs/article/grokking-concurrency/haskell/part-3.md +6 -7
  519. package/lib/assets/docs/article/grokking-concurrency/haskell/part-4.md +6 -7
  520. package/lib/assets/docs/article/grokking-concurrency/haskell/part-5.md +6 -7
  521. package/lib/assets/docs/article/grokking-concurrency/haskell/part-6.md +6 -7
  522. package/lib/assets/docs/article/grokking-concurrency/haskell/part-7.md +6 -7
  523. package/lib/assets/docs/article/grokking-concurrency/haskell/part-8.md +6 -7
  524. package/lib/assets/docs/article/grokking-concurrency/java/index.md +0 -10
  525. package/lib/assets/docs/article/grokking-concurrency/java/part-1.md +8 -9
  526. package/lib/assets/docs/article/grokking-concurrency/java/part-2.md +8 -9
  527. package/lib/assets/docs/article/grokking-concurrency/java/part-3.md +7 -8
  528. package/lib/assets/docs/article/grokking-concurrency/java/part-4.md +8 -9
  529. package/lib/assets/docs/article/grokking-concurrency/java/part-5.md +7 -8
  530. package/lib/assets/docs/article/grokking-concurrency/java/part-6.md +6 -7
  531. package/lib/assets/docs/article/grokking-concurrency/java/part-7.md +6 -7
  532. package/lib/assets/docs/article/grokking-concurrency/java/part-8.md +6 -7
  533. package/lib/assets/docs/article/grokking-concurrency/python/index.md +0 -10
  534. package/lib/assets/docs/article/grokking-concurrency/python/part-1.md +7 -8
  535. package/lib/assets/docs/article/grokking-concurrency/python/part-2.md +10 -11
  536. package/lib/assets/docs/article/grokking-concurrency/python/part-3.md +8 -9
  537. package/lib/assets/docs/article/grokking-concurrency/python/part-4.md +8 -9
  538. package/lib/assets/docs/article/grokking-concurrency/python/part-5.md +9 -10
  539. package/lib/assets/docs/article/grokking-concurrency/python/part-6.md +9 -10
  540. package/lib/assets/docs/article/grokking-concurrency/python/part-7.md +9 -10
  541. package/lib/assets/docs/article/grokking-concurrency/python/part-8.md +8 -9
  542. package/lib/assets/docs/article/grokking-concurrency/rust/index.md +0 -10
  543. package/lib/assets/docs/article/grokking-concurrency/rust/part-1.md +6 -7
  544. package/lib/assets/docs/article/grokking-concurrency/rust/part-2.md +6 -7
  545. package/lib/assets/docs/article/grokking-concurrency/rust/part-3.md +6 -7
  546. package/lib/assets/docs/article/grokking-concurrency/rust/part-4.md +6 -7
  547. package/lib/assets/docs/article/grokking-concurrency/rust/part-5.md +6 -7
  548. package/lib/assets/docs/article/grokking-concurrency/rust/part-6.md +6 -7
  549. package/lib/assets/docs/article/grokking-concurrency/rust/part-7.md +6 -7
  550. package/lib/assets/docs/article/grokking-concurrency/rust/part-8.md +6 -7
  551. package/lib/assets/docs/article/grokking-concurrency/scala/index.md +0 -10
  552. package/lib/assets/docs/article/grokking-concurrency/scala/part-1.md +6 -7
  553. package/lib/assets/docs/article/grokking-concurrency/scala/part-2.md +6 -7
  554. package/lib/assets/docs/article/grokking-concurrency/scala/part-3.md +6 -7
  555. package/lib/assets/docs/article/grokking-concurrency/scala/part-4.md +6 -7
  556. package/lib/assets/docs/article/grokking-concurrency/scala/part-5.md +6 -7
  557. package/lib/assets/docs/article/grokking-concurrency/scala/part-6.md +6 -7
  558. package/lib/assets/docs/article/grokking-concurrency/scala/part-7.md +6 -7
  559. package/lib/assets/docs/article/grokking-concurrency/scala/part-8.md +6 -7
  560. package/lib/assets/docs/article/grokkingfp/all/part-1-ch01-fp-introduction.md +9 -0
  561. package/lib/assets/docs/article/grokkingfp/all/part-1-ch02-pure-functions.md +9 -0
  562. package/lib/assets/docs/article/grokkingfp/all/part-2-ch03-immutable-data.md +9 -0
  563. package/lib/assets/docs/article/grokkingfp/all/part-2-ch04-higher-order-functions.md +9 -0
  564. package/lib/assets/docs/article/grokkingfp/all/part-2-ch05-flatmap.md +9 -0
  565. package/lib/assets/docs/article/grokkingfp/all/part-3-ch06-option.md +9 -0
  566. package/lib/assets/docs/article/grokkingfp/all/part-3-ch07-either-adt.md +9 -0
  567. package/lib/assets/docs/article/grokkingfp/all/part-4-ch08-io-monad.md +9 -0
  568. package/lib/assets/docs/article/grokkingfp/all/part-4-ch09-streams.md +9 -0
  569. package/lib/assets/docs/article/grokkingfp/all/part-5-ch10-concurrency.md +9 -0
  570. package/lib/assets/docs/article/grokkingfp/all/part-6-ch11-application.md +9 -0
  571. package/lib/assets/docs/article/grokkingfp/all/part-6-ch12-testing.md +9 -0
  572. package/lib/assets/docs/article/grokkingfp/all/writing-plan.md +9 -0
  573. package/lib/assets/docs/article/grokkingfp/clojure/part-1.md +9 -0
  574. package/lib/assets/docs/article/grokkingfp/clojure/part-2.md +9 -0
  575. package/lib/assets/docs/article/grokkingfp/clojure/part-3.md +9 -0
  576. package/lib/assets/docs/article/grokkingfp/clojure/part-4.md +9 -0
  577. package/lib/assets/docs/article/grokkingfp/clojure/part-5.md +9 -0
  578. package/lib/assets/docs/article/grokkingfp/clojure/part-6.md +9 -0
  579. package/lib/assets/docs/article/grokkingfp/csharp/part-1.md +9 -0
  580. package/lib/assets/docs/article/grokkingfp/csharp/part-2.md +9 -0
  581. package/lib/assets/docs/article/grokkingfp/csharp/part-3.md +9 -0
  582. package/lib/assets/docs/article/grokkingfp/csharp/part-4.md +9 -0
  583. package/lib/assets/docs/article/grokkingfp/csharp/part-5.md +9 -0
  584. package/lib/assets/docs/article/grokkingfp/csharp/part-6.md +9 -0
  585. package/lib/assets/docs/article/grokkingfp/elixir/part-1.md +9 -0
  586. package/lib/assets/docs/article/grokkingfp/elixir/part-2.md +9 -0
  587. package/lib/assets/docs/article/grokkingfp/elixir/part-3.md +9 -0
  588. package/lib/assets/docs/article/grokkingfp/elixir/part-4.md +9 -0
  589. package/lib/assets/docs/article/grokkingfp/elixir/part-5.md +9 -0
  590. package/lib/assets/docs/article/grokkingfp/elixir/part-6.md +9 -0
  591. package/lib/assets/docs/article/grokkingfp/fsharp/part-1.md +9 -0
  592. package/lib/assets/docs/article/grokkingfp/fsharp/part-2.md +9 -0
  593. package/lib/assets/docs/article/grokkingfp/fsharp/part-3.md +9 -0
  594. package/lib/assets/docs/article/grokkingfp/fsharp/part-4.md +9 -0
  595. package/lib/assets/docs/article/grokkingfp/fsharp/part-5.md +9 -0
  596. package/lib/assets/docs/article/grokkingfp/fsharp/part-6.md +9 -0
  597. package/lib/assets/docs/article/grokkingfp/haskell/part-1.md +9 -0
  598. package/lib/assets/docs/article/grokkingfp/haskell/part-2.md +9 -0
  599. package/lib/assets/docs/article/grokkingfp/haskell/part-3.md +9 -0
  600. package/lib/assets/docs/article/grokkingfp/haskell/part-4.md +9 -0
  601. package/lib/assets/docs/article/grokkingfp/haskell/part-5.md +9 -0
  602. package/lib/assets/docs/article/grokkingfp/haskell/part-6.md +9 -0
  603. package/lib/assets/docs/article/grokkingfp/java/part-1.md +9 -0
  604. package/lib/assets/docs/article/grokkingfp/java/part-2.md +9 -0
  605. package/lib/assets/docs/article/grokkingfp/java/part-3.md +9 -0
  606. package/lib/assets/docs/article/grokkingfp/java/part-4.md +9 -0
  607. package/lib/assets/docs/article/grokkingfp/java/part-5.md +9 -0
  608. package/lib/assets/docs/article/grokkingfp/java/part-6.md +9 -0
  609. package/lib/assets/docs/article/grokkingfp/python/part-1.md +9 -0
  610. package/lib/assets/docs/article/grokkingfp/python/part-2.md +9 -0
  611. package/lib/assets/docs/article/grokkingfp/python/part-3.md +9 -0
  612. package/lib/assets/docs/article/grokkingfp/python/part-4.md +9 -0
  613. package/lib/assets/docs/article/grokkingfp/python/part-5.md +9 -0
  614. package/lib/assets/docs/article/grokkingfp/python/part-6.md +9 -0
  615. package/lib/assets/docs/article/grokkingfp/ruby/part-1.md +9 -0
  616. package/lib/assets/docs/article/grokkingfp/ruby/part-2.md +9 -0
  617. package/lib/assets/docs/article/grokkingfp/ruby/part-3.md +9 -0
  618. package/lib/assets/docs/article/grokkingfp/ruby/part-4.md +9 -0
  619. package/lib/assets/docs/article/grokkingfp/ruby/part-5.md +9 -0
  620. package/lib/assets/docs/article/grokkingfp/ruby/part-6.md +9 -0
  621. package/lib/assets/docs/article/grokkingfp/rust/part-1.md +9 -0
  622. package/lib/assets/docs/article/grokkingfp/rust/part-2.md +9 -0
  623. package/lib/assets/docs/article/grokkingfp/rust/part-3.md +9 -0
  624. package/lib/assets/docs/article/grokkingfp/rust/part-4.md +9 -0
  625. package/lib/assets/docs/article/grokkingfp/rust/part-5.md +9 -0
  626. package/lib/assets/docs/article/grokkingfp/rust/part-6.md +9 -0
  627. package/lib/assets/docs/article/grokkingfp/scala/part-1.md +9 -0
  628. package/lib/assets/docs/article/grokkingfp/scala/part-2.md +9 -0
  629. package/lib/assets/docs/article/grokkingfp/scala/part-3.md +9 -0
  630. package/lib/assets/docs/article/grokkingfp/scala/part-4.md +9 -0
  631. package/lib/assets/docs/article/grokkingfp/scala/part-5.md +9 -0
  632. package/lib/assets/docs/article/grokkingfp/scala/part-6.md +9 -0
  633. package/lib/assets/docs/article/grokkingfp/typescript/part-1.md +9 -0
  634. package/lib/assets/docs/article/grokkingfp/typescript/part-2.md +9 -0
  635. package/lib/assets/docs/article/grokkingfp/typescript/part-3.md +9 -0
  636. package/lib/assets/docs/article/grokkingfp/typescript/part-4.md +9 -0
  637. package/lib/assets/docs/article/grokkingfp/typescript/part-5.md +9 -0
  638. package/lib/assets/docs/article/grokkingfp/typescript/part-6.md +9 -0
  639. package/lib/assets/docs/article/practical-database-design/part1/chapter01.md +9 -0
  640. package/lib/assets/docs/article/practical-database-design/part1/chapter02.md +9 -0
  641. package/lib/assets/docs/article/practical-database-design/part1/chapter03.md +9 -0
  642. package/lib/assets/docs/article/practical-database-design/part2/chapter04.md +9 -0
  643. package/lib/assets/docs/article/practical-database-design/part2/chapter05.md +9 -0
  644. package/lib/assets/docs/article/practical-database-design/part2/chapter06.md +9 -0
  645. package/lib/assets/docs/article/practical-database-design/part2/chapter07.md +9 -0
  646. package/lib/assets/docs/article/practical-database-design/part2/chapter08.md +9 -0
  647. package/lib/assets/docs/article/practical-database-design/part2/chapter09.md +9 -0
  648. package/lib/assets/docs/article/practical-database-design/part2/chapter10.md +9 -0
  649. package/lib/assets/docs/article/practical-database-design/part2/chapter11.md +9 -0
  650. package/lib/assets/docs/article/practical-database-design/part2/chapter12.md +9 -0
  651. package/lib/assets/docs/article/practical-database-design/part2/chapter13.md +9 -0
  652. package/lib/assets/docs/article/practical-database-design/part3/chapter14.md +9 -0
  653. package/lib/assets/docs/article/practical-database-design/part3/chapter15.md +9 -0
  654. package/lib/assets/docs/article/practical-database-design/part3/chapter16.md +9 -0
  655. package/lib/assets/docs/article/practical-database-design/part3/chapter17.md +9 -0
  656. package/lib/assets/docs/article/practical-database-design/part3/chapter18.md +9 -0
  657. package/lib/assets/docs/article/practical-database-design/part3/chapter19.md +9 -0
  658. package/lib/assets/docs/article/practical-database-design/part3/chapter20.md +9 -0
  659. package/lib/assets/docs/article/practical-database-design/part3/chapter21.md +9 -0
  660. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter14-orm.md +9 -0
  661. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter15-orm.md +9 -0
  662. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter16-orm.md +9 -0
  663. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter17-orm.md +9 -0
  664. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter18-orm.md +9 -0
  665. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter19-orm.md +9 -0
  666. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter20-orm.md +9 -0
  667. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter21-orm.md +9 -0
  668. package/lib/assets/docs/article/practical-database-design/part3-orm/chapter22-orm.md +9 -0
  669. package/lib/assets/docs/article/practical-database-design/part4/chapter22.md +9 -0
  670. package/lib/assets/docs/article/practical-database-design/part4/chapter23.md +9 -0
  671. package/lib/assets/docs/article/practical-database-design/part4/chapter24.md +9 -0
  672. package/lib/assets/docs/article/practical-database-design/part4/chapter25.md +9 -0
  673. package/lib/assets/docs/article/practical-database-design/part4/chapter26.md +9 -0
  674. package/lib/assets/docs/article/practical-database-design/part4/chapter27.md +9 -0
  675. package/lib/assets/docs/article/practical-database-design/part4/chapter28.md +9 -0
  676. package/lib/assets/docs/article/practical-database-design/part4/chapter29.md +8 -0
  677. package/lib/assets/docs/article/practical-database-design/part4/chapter30.md +8 -0
  678. package/lib/assets/docs/article/practical-database-design/part4/chapter31.md +8 -0
  679. package/lib/assets/docs/article/practical-database-design/part4/chapter32.md +8 -0
  680. package/lib/assets/docs/article/practical-database-design/part5/chapter33.md +9 -0
  681. package/lib/assets/docs/article/practical-database-design/part5/chapter34.md +9 -0
  682. package/lib/assets/docs/article/practical-database-design/part5/chapter35.md +9 -0
  683. package/lib/assets/docs/article/practical-database-design/part5/chapter36.md +9 -0
  684. package/lib/assets/docs/article/practical-database-design/part5/chapter37.md +9 -0
  685. package/lib/assets/docs/article/practical-database-design/part5/chapter38.md +9 -0
  686. package/lib/assets/docs/article/practical-database-design/part5/chapter39.md +9 -0
  687. package/lib/assets/docs/article/practical-database-design/study/study2-1.md +9 -0
  688. package/lib/assets/docs/article/practical-database-design/study/study2-2.md +9 -0
  689. package/lib/assets/docs/article/practical-database-design/study/study2-3.md +9 -0
  690. package/lib/assets/docs/article/practical-database-design/study/study2-4.md +9 -0
  691. package/lib/assets/docs/article/practical-database-design/study/study2-5.md +9 -0
  692. package/lib/assets/docs/article/practical-database-design/study/study3-1.md +9 -0
  693. package/lib/assets/docs/article/practical-database-design/study/study3-2.md +9 -0
  694. package/lib/assets/docs/article/practical-database-design/study/study3-3.md +9 -0
  695. package/lib/assets/docs/article/practical-database-design/study/study3-4.md +9 -0
  696. package/lib/assets/docs/article/practical-database-design/study/study3-5.md +9 -0
  697. package/lib/assets/docs/article/practical-database-design/study/study4-1.md +9 -0
  698. package/lib/assets/docs/article/practical-database-design/study/study4-2.md +9 -0
  699. package/lib/assets/docs/article/practical-database-design/study/study4-3.md +9 -0
  700. package/lib/assets/docs/article/practical-database-design/study/study4-4.md +9 -0
  701. package/lib/assets/docs/article/practical-database-design/study/study4-5.md +9 -0
  702. package/lib/assets/docs/index.md +5 -1
  703. package/lib/assets/docs/log.md +10 -0
  704. package/lib/assets/docs/operation/index.md +15 -1
  705. package/lib/assets/docs/reference/CodexCLIMCP/343/202/242/343/203/227/343/203/252/343/202/261/343/203/274/343/202/267/343/203/247/343/203/263/351/226/213/347/231/272/343/203/225/343/203/255/343/203/274.md +13 -4
  706. package/lib/assets/docs/reference/CodexCLIMCP/343/202/265/343/203/274/343/203/220/343/203/274/350/250/255/345/256/232/346/211/213/351/240/206.md +10 -0
  707. package/lib/assets/docs/reference/Java/343/202/242/343/203/227/343/203/252/343/202/261/343/203/274/343/202/267/343/203/247/343/203/263/347/222/260/345/242/203/346/247/213/347/257/211/343/202/254/343/202/244/343/203/211.md +11 -1
  708. package/lib/assets/docs/reference/OKF/345/260/216/345/205/245/343/202/254/343/202/244/343/203/211_V0.2.md +965 -0
  709. package/lib/assets/docs/reference/SonarQube/343/203/255/343/203/274/343/202/253/343/203/253/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +10 -0
  710. package/lib/assets/docs/reference/TypeScript/343/202/242/343/203/227/343/203/252/343/202/261/343/203/274/343/202/267/343/203/247/343/203/263/347/222/260/345/242/203/346/247/213/347/257/211/343/202/254/343/202/244/343/203/211.md +11 -1
  711. package/lib/assets/docs/reference/UI/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +10 -1
  712. package/lib/assets/docs/reference/Vim/346/223/215/344/275/234/343/203/236/343/203/213/343/203/245/343/202/242/343/203/253.md +177 -168
  713. package/lib/assets/docs/reference/index.md +55 -53
  714. package/lib/assets/docs/reference//343/202/210/343/201/204/343/202/275/343/203/225/343/203/210/343/202/246/343/202/247/343/202/242/343/201/250/343/201/257.md +7 -8
  715. package/lib/assets/docs/reference//343/202/242/343/203/274/343/202/255/343/203/206/343/202/257/343/203/201/343/203/243/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +10 -1
  716. package/lib/assets/docs/reference//343/202/244/343/203/263/343/203/225/343/203/251/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +10 -1
  717. package/lib/assets/docs/reference//343/202/250/343/202/257/343/202/271/343/203/210/343/203/252/343/203/274/343/203/240/343/203/227/343/203/255/343/202/260/343/203/251/343/203/237/343/203/263/343/202/260.md +6 -7
  718. package/lib/assets/docs/reference//343/202/263/343/203/274/343/203/207/343/202/243/343/203/263/343/202/260/343/201/250/343/203/206/343/202/271/343/203/210/343/202/254/343/202/244/343/203/211.md +10 -1
  719. package/lib/assets/docs/reference//343/203/206/343/202/271/343/203/210/346/210/246/347/225/245/343/202/254/343/202/244/343/203/211.md +10 -1
  720. package/lib/assets/docs/reference//343/203/207/343/203/274/343/202/277/343/203/242/343/203/207/343/203/253/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +10 -1
  721. package/lib/assets/docs/reference//343/203/211/343/202/255/343/203/245/343/203/241/343/203/263/343/203/210/346/247/213/346/210/220/343/202/254/343/202/244/343/203/211.md +143 -0
  722. package/lib/assets/docs/reference//343/203/211/343/203/241/343/202/244/343/203/263/343/203/242/343/203/207/343/203/253/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +10 -1
  723. package/lib/assets/docs/reference//343/203/223/343/202/270/343/203/215/343/202/271/343/202/242/343/203/274/343/202/255/343/203/206/343/202/257/343/203/201/343/203/243/345/210/206/346/236/220/343/202/254/343/202/244/343/203/211.md +9 -0
  724. package/lib/assets/docs/reference//343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271/344/275/234/346/210/220/343/202/254/343/202/244/343/203/211.md +10 -1
  725. package/lib/assets/docs/reference//343/203/252/343/203/252/343/203/274/343/202/271/343/202/254/343/202/244/343/203/211.md +9 -0
  726. package/lib/assets/docs/reference//343/203/252/343/203/252/343/203/274/343/202/271/343/203/273/343/202/244/343/203/206/343/203/254/343/203/274/343/202/267/343/203/247/343/203/263/350/250/210/347/224/273/343/202/254/343/202/244/343/203/211.md +7 -8
  727. package/lib/assets/docs/reference//343/203/255/343/202/270/343/202/253/343/203/253/343/202/267/343/203/263/343/202/255/343/203/263/343/202/260.md +9 -0
  728. package/lib/assets/docs/reference//344/274/201/346/245/255/347/265/214/345/226/266/350/253/226.md +10 -1
  729. package/lib/assets/docs/reference//347/222/260/345/242/203/345/244/211/346/225/260/347/256/241/347/220/206/343/202/254/343/202/244/343/203/211.md +10 -0
  730. package/lib/assets/docs/reference//347/265/214/345/226/266/346/210/246/347/225/245/345/210/206/346/236/220/343/202/254/343/202/244/343/203/211.md +9 -0
  731. package/lib/assets/docs/reference//350/246/201/344/273/266/345/256/232/347/276/251/343/202/254/343/202/244/343/203/211.md +10 -1
  732. package/lib/assets/docs/reference//350/250/200/350/252/236/345/210/245/351/226/213/347/231/272/343/202/254/343/202/244/343/203/211.md +9 -0
  733. package/lib/assets/docs/reference//351/201/213/345/226/266/347/256/241/347/220/206.md +10 -1
  734. package/lib/assets/docs/reference//351/201/213/347/224/250/343/202/271/343/202/257/343/203/252/343/203/227/343/203/210/344/275/234/346/210/220/343/202/254/343/202/244/343/203/211.md +9 -0
  735. package/lib/assets/docs/reference//351/201/213/347/224/250/350/246/201/344/273/266/345/256/232/347/276/251/343/202/254/343/202/244/343/203/211.md +10 -1
  736. package/lib/assets/docs/reference//351/226/213/347/231/272/343/202/254/343/202/244/343/203/211.md +9 -0
  737. package/lib/assets/docs/reference//351/235/236/346/251/237/350/203/275/350/246/201/344/273/266/345/256/232/347/276/251/343/202/254/343/202/244/343/203/211.md +10 -1
  738. package/lib/assets/docs/template/ADR.md +9 -0
  739. package/lib/assets/docs/template/AWS/343/202/271/343/203/206/343/203/274/343/202/270/343/203/263/343/202/260/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +9 -0
  740. package/lib/assets/docs/template/AWS/343/203/227/343/203/255/343/203/200/343/202/257/343/202/267/343/203/247/343/203/263/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +9 -0
  741. package/lib/assets/docs/template/README.md +9 -0
  742. package/lib/assets/docs/template//343/201/276/343/201/232/343/201/223/343/202/214/343/202/222/350/252/255/343/202/202/343/201/206/343/203/252/343/202/271/343/203/210.md +9 -0
  743. package/lib/assets/docs/template//343/202/242/343/203/227/343/203/252/343/202/261/343/203/274/343/202/267/343/203/247/343/203/263/351/226/213/347/231/272/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +9 -0
  744. package/lib/assets/docs/template//343/202/244/343/203/206/343/203/254/343/203/274/343/202/267/343/203/247/343/203/263/345/256/214/344/272/206/345/240/261/345/221/212/346/233/270.md +10 -1
  745. package/lib/assets/docs/template//343/202/244/343/203/206/343/203/254/343/203/274/343/202/267/343/203/247/343/203/263/350/250/210/347/224/273.md +11 -2
  746. package/lib/assets/docs/template//343/202/244/343/203/263/343/202/273/343/203/227/343/202/267/343/203/247/343/203/263/343/203/207/343/203/203/343/202/255.md +9 -0
  747. package/lib/assets/docs/template//343/203/223/343/202/270/343/203/215/343/202/271/343/202/242/343/203/274/343/202/255/343/203/206/343/202/257/343/203/201/343/203/243.md +9 -0
  748. package/lib/assets/docs/template//343/203/252/343/203/252/343/203/274/343/202/271/345/256/214/344/272/206/345/240/261/345/221/212/346/233/270.md +9 -0
  749. package/lib/assets/docs/template//343/203/252/343/203/252/343/203/274/343/202/271/350/250/210/347/224/273.md +289 -280
  750. package/lib/assets/docs/template//344/272/213/344/276/213/345/210/206/346/236/220.md +9 -0
  751. package/lib/assets/docs/template//344/274/201/346/245/255/345/210/206/346/236/220.md +9 -0
  752. package/lib/assets/docs/template//345/256/214/345/205/250/345/275/242/345/274/217/343/201/256/343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271.md +7 -8
  753. package/lib/assets/docs/template//350/246/201/344/273/266/345/256/232/347/276/251.md +7 -8
  754. package/lib/assets/docs/template//350/250/255/350/250/210.md +10 -1
  755. package/lib/assets/docs/template//351/226/213/347/231/272/347/222/260/345/242/203/343/202/273/343/203/203/343/203/210/343/202/242/343/203/203/343/203/227/346/211/213/351/240/206/346/233/270.md +9 -0
  756. package/lib/assets/gulpfile.js +4 -2
  757. package/lib/assets/ops/scripts/okf.js +272 -0
  758. package/lib/assets/package.json +2 -0
  759. package/package.json +1 -1
@@ -1,598 +1,607 @@
1
- # 第 11 章 コンテナにおける継続的デリバリー
2
-
3
- ![コンテナにおける継続的デリバリーを説明する 4 コマ漫画](images/chapter-11-comic.png)
4
-
5
- *コード変更からテスト、ビルド、イメージ公開、クラスタへの反映までを自動化します。*
6
-
7
- ## はじめに
8
-
9
- 前章では CI(継続的インテグレーション)について学び、コードの変更をきっかけにテストとイメージのビルド・push を自動化する仕組みを構築しました。しかし、イメージがレジストリに push されただけでは、ユーザーに価値が届いたことにはなりません。ビルドされたイメージを Kubernetes クラスタへ確実にデプロイし、はじめてソフトウェアは「役に立つ」状態になります。
10
-
11
- この章では、CI に続く工程である CD(継続的デリバリー)を扱います。特に、コンテナと Kubernetes の世界で標準的なアプローチとなった GitOps と、それを実現する代表的なツールである Flux、Argo CD、PipeCD を取り上げます。それぞれのツールが実際にどのようなマニフェストや設定ファイルで動くのかを、公開されているサンプルリポジトリの実コードを引用しながら確認していきます。
12
-
13
- 最後に、CI から CD、さらに進行的デリバリー(カナリアリリースと自動分析、自動ロールバック)までをつなげ、ソフトウェアデリバリーを完全に自動化する全体像をまとめます。
14
-
15
- 「変更を楽に安全にできて役に立つソフトウェア」を継続的に届けるための土台が、この章のテーマです。
16
-
17
- ### 目次
18
-
19
- 1. [継続的デリバリーとは](#111-継続的デリバリーとは)
20
- 2. [Flux](#112-flux)
21
- 3. [Argo CD](#113-argo-cd)
22
- 4. [PipeCD](#114-pipecd)
23
- 5. [ソフトウェアデリバリーの完全自動化](#115-ソフトウェアデリバリーの完全自動化)
24
-
25
- ---
26
-
27
- ## 11.1 継続的デリバリーとは
28
-
29
- ### CI と CD の違い
30
-
31
- まず、CI と CD の役割を整理します。両者は連続した工程ですが、責務が明確に異なります。
32
-
33
- - CI(Continuous Integration / 継続的インテグレーション)
34
-
35
- 開発者が頻繁にコードを統合し、その都度テストとビルドを自動で実行する活動です。コンテナの文脈では「テストを通し、Docker イメージをビルドしてレジストリに push する」ところまでが CI の責務になります。CI のゴールは「いつでもデプロイ可能な成果物(イメージ)」を作り続けることです。
36
-
37
- - CD(Continuous Delivery / 継続的デリバリー)
38
-
39
- CI が生んだ成果物を、実際に動作する環境へ確実に届ける活動です。コンテナの文脈では「レジストリのイメージを Kubernetes クラスタにデプロイし、望ましい状態を維持する」ところが CD の責務になります。CD のゴールは「成果物をいつでも安全にリリースできる状態」を保つことです。
40
-
41
- CI と CD の境界を図にすると次のようになります。
42
-
43
- ```text
44
- [開発者] --push--> [Git リポジトリ]
45
- |
46
- (CI: テスト/ビルド/push)
47
- v
48
- [コンテナレジストリ] <- ここまでが CI
49
- |
50
- (CD: デプロイ/同期)
51
- v
52
- [Kubernetes クラスタ] <- ここからが CD
53
- ```
54
-
55
- CI については第 10 章で扱いました。この章では、レジストリにイメージが置かれた後の CD に焦点を当てます。
56
-
57
- ### GitOps という考え方
58
-
59
- Kubernetes のデプロイにおいて、近年の標準的なアプローチとなったのが GitOps です。GitOps の中心にあるのは次の 2 つの原則です。
60
-
61
- 1. Git を信頼できる唯一の情報源(Single Source of Truth)とする
62
-
63
- クラスタにあるべき状態(Deployment、Service、ConfigMap など)を、すべて宣言的なマニフェストとして Git リポジトリで管理します。「本番環境がどうあるべきか」を知りたければ Git を見れば良い、という状態を作ります。
64
-
65
- 2. 宣言的マニフェストをクラスタへ自動同期する
66
-
67
- Git に書かれた「あるべき状態」と、クラスタの「現在の状態」をツールが常に比較し、差分があれば自動的に同期して一致させます。
68
-
69
- この考え方の利点は、本書全体を貫く「変更を楽に安全にできる」という価値に直結します。デプロイは `git push`(あるいは Pull Request のマージ)という、開発者が日常的に行う操作に統一されます。誰がいつ何を変更したかは Git の履歴に残り、問題があれば `git revert` で過去の状態に戻せます。手作業の `kubectl apply` に頼らないため、操作ミスや環境ごとの設定のばらつきも減ります。
70
-
71
- ### push 型と pull 型
72
-
73
- CD の同期方式には、大きく分けて push 型と pull 型があります。
74
-
75
- - push 型
76
-
77
- CI/CD パイプライン(GitHub Actions など)の側から、クラスタに対して `kubectl apply` などで変更を「押し込む」方式です。仕組みが理解しやすい反面、パイプライン側にクラスタへの認証情報(kubeconfig など)を持たせる必要があり、クラスタの外から強い権限でアクセスできてしまう点に注意が必要です。
78
-
79
- - pull 型
80
-
81
- クラスタ内に常駐するエージェントが、Git リポジトリを定期的に監視し、変更を検知すると自身でクラスタへ反映する方式です。クラスタの外部に認証情報を渡す必要がなく、エージェントがクラスタ内部から動作するためセキュリティ面で有利です。GitOps を掲げるツールの多くは、この pull 型を採用しています。
82
-
83
- ```text
84
- push 型: [パイプライン] --kubectl apply--> [クラスタ]
85
- pull 型: [クラスタ内エージェント] --watch/pull--> [Git リポジトリ]
86
- ```
87
-
88
- これから紹介する Flux と Argo CD は pull 型の GitOps ツールです。PipeCD も Git を起点とし、クラスタ内の `piped` というエージェントが同期を担うため、pull 型の性質を持ちます。
89
-
90
- ---
91
-
92
- ## 11.2 Flux
93
-
94
- ### Flux の仕組み
95
-
96
- Flux は CNCF(Cloud Native Computing Foundation)の卒業プロジェクトで、pull 型 GitOps を実現するツールです。Flux はモノリシックな単一のコンポーネントではなく、役割ごとに分かれた複数のコントローラ(GitOps Toolkit と呼ばれます)の集合として構成されています。代表的なものは次の 2 つです。
97
-
98
- - source-controller
99
-
100
- Git リポジトリや Helm リポジトリ、OCI レジストリなどの「ソース」を監視し、指定したリビジョンのマニフェストを取得して、クラスタ内のほかのコントローラから参照できるようにします。
101
-
102
- - kustomize-controller
103
-
104
- source-controller が取得したマニフェスト(Kustomize で管理されたものを含む)を、実際にクラスタへ適用します。Git 上の状態とクラスタの状態を継続的に突き合わせ、差分があれば同期します。
105
-
106
- 動作の流れは次のようになります。
107
-
108
- ```text
109
- [Git リポジトリ] --watch--> [source-controller] --取得--> [kustomize-controller] --apply--> [クラスタ]
110
- ```
111
-
112
- 開発者が Git にマニフェストの変更を push すると、source-controller がそれを検知し、kustomize-controller がクラスタへ反映します。クラスタ側で誰かが手動で設定を書き換えても、Flux が Git の状態へ引き戻す(ドリフトの是正)ため、Git が常に正となります。
113
-
114
- ### 配信対象となる Kustomize マニフェストの例
115
-
116
- Flux が配信する対象は、宣言的に書かれた Kubernetes マニフェストです。本書のサンプルリポジトリ `echo-bootstrap`(出典: `apps/cd/echo-bootstrap/`)には、Kustomize で束ねられたマニフェスト群が含まれています。これは GitOps で配信するアプリケーションの典型例として参考になります。
117
-
118
- `apps/cd/echo-bootstrap/kustomization.yaml` は、複数のマニフェストを 1 つのアプリケーションとしてまとめています。
119
-
120
- ```yaml
121
- apiVersion: kustomize.config.k8s.io/v1beta1
122
- kind: Kustomization
123
- namespace: gitops-echo
124
- resources:
125
- - namespace.yaml
126
- - deployment.yaml
127
- - ingress.yaml
128
- - service.yaml
129
- commonLabels:
130
- app.kubernetes.io/name: echo
131
- ```
132
-
133
- 実際に配信される Deployment は `apps/cd/echo-bootstrap/deployment.yaml` に定義されています(抜粋)。
134
-
135
- ```yaml
136
- apiVersion: apps/v1
137
- kind: Deployment
138
- metadata:
139
- name: echo
140
- labels:
141
- app.kubernetes.io/name: echo
142
- spec:
143
- replicas: 1
144
- selector:
145
- matchLabels:
146
- app.kubernetes.io/name: echo
147
- template:
148
- metadata:
149
- labels:
150
- app.kubernetes.io/name: echo
151
- spec:
152
- containers:
153
- - name: nginx
154
- image: ghcr.io/gihyodocker/simple-nginx-proxy:v0.1.0
155
- # ...(環境変数の定義は省略)
156
- - name: echo
157
- image: ghcr.io/gihyodocker/echo:v0.1.0-slim
158
- ```
159
-
160
- このように、`gitops-echo` という名前空間に `echo` という Deployment を配置することが Git 上で宣言されています。Flux はこの Git 上の宣言をクラスタの「あるべき状態」とみなして同期します。
161
-
162
- ### Flux にこのマニフェストを配信させる設定例
163
-
164
- ここからは一般的な例です(`echo-bootstrap` リポジトリには含まれていない、Flux 側の設定の書き方を示します)。Flux にこの `echo-bootstrap` を監視させるには、`GitRepository` と `Kustomization` という 2 つのカスタムリソース(CRD)を Flux 自身に与えます。次は一般的に正しい記述の例です。
165
-
166
- ```yaml
167
- # 例: Git リポジトリを監視対象として登録する(GitRepository CRD)
168
- apiVersion: source.toolkit.fluxcd.io/v1
169
- kind: GitRepository
170
- metadata:
171
- name: echo-bootstrap
172
- namespace: flux-system
173
- spec:
174
- interval: 1m # 1 分ごとにリポジトリをチェックする
175
- url: https://github.com/example/echo-bootstrap
176
- ref:
177
- branch: main # 監視するブランチ(リビジョン)
178
- ---
179
- # 例: 取得したマニフェストをクラスタへ同期する(Kustomization CRD)
180
- apiVersion: kustomize.toolkit.fluxcd.io/v1
181
- kind: Kustomization
182
- metadata:
183
- name: echo
184
- namespace: flux-system
185
- spec:
186
- interval: 5m # 5 分ごとにクラスタとの差分を是正する
187
- sourceRef:
188
- kind: GitRepository
189
- name: echo-bootstrap
190
- path: "./" # kustomization.yaml の場所
191
- prune: true # Git から削除されたリソースはクラスタからも削除する
192
- ```
193
-
194
- `GitRepository` が「どこを見るか(リポジトリとリビジョン)」を、`Kustomization` が「取得したもののどのパスを、どう同期するか」を定義します。`prune: true` を指定すると、Git から消したリソースはクラスタからも削除されるため、Git の状態とクラスタの状態が厳密に一致します。これが GitOps における「Git を唯一の情報源とする」の具体的な姿です。
195
-
196
- ---
197
-
198
- ## 11.3 Argo CD
199
-
200
- ### Argo CD と Application
201
-
202
- Argo CD も pull 型 GitOps を実現する CNCF プロジェクトです。Flux との大きな違いは、Web UI を備え、アプリケーションの同期状態(Synced / OutOfSync)や健全性(Healthy など)を視覚的に確認できる点にあります。
203
-
204
- Argo CD では、同期対象を `Application` というカスタムリソースで表現します。`Application` には「どの Git リポジトリの、どのパスの、どのリビジョンを、どの名前空間に同期するか」を記述します。本節では、Argo CD のデモ用に公開されているサンプル集 `argocd-example-apps`(出典: `apps/cd/argocd-example-apps/`)を引用しながら解説します。
205
-
206
- `Application` の記述は一般的に次のような形になります(一般例。`argocd-example-apps` のアプリを同期対象とした場合)。
207
-
208
- ```yaml
209
- # 例: guestbook を同期対象とする Application
210
- apiVersion: argoproj.io/v1alpha1
211
- kind: Application
212
- metadata:
213
- name: guestbook
214
- namespace: argocd
215
- spec:
216
- project: default
217
- source:
218
- repoURL: https://github.com/argoproj/argocd-example-apps.git
219
- targetRevision: HEAD # 同期対象のリビジョン
220
- path: guestbook # 同期対象の Git パス
221
- destination:
222
- server: https://kubernetes.default.svc
223
- namespace: default
224
- syncPolicy:
225
- automated: # Git の変更を自動で同期する
226
- prune: true
227
- selfHeal: true
228
- ```
229
-
230
- `source.path` と `source.targetRevision` が、まさに「Git のどこを正とするか」を指定する部分です。`syncPolicy.automated` を設定すると、Git の変更を検知して自動同期し、クラスタ側のドリフトも自動是正します。
231
-
232
- ### さまざまなマニフェスト形式
233
-
234
- `argocd-example-apps` の README(出典: `apps/cd/argocd-example-apps/README.md`)には、同じ guestbook アプリをさまざまな形式で表現したサンプルが並んでいます。Argo CD は、プレーンな YAML、Kustomize、Helm のいずれの形式でもそのまま同期できます。
235
-
236
- #### プレーン YAML 形式(guestbook)
237
-
238
- `apps/cd/argocd-example-apps/guestbook/guestbook-ui-deployment.yaml` は、テンプレート機構を使わない素の Kubernetes マニフェストです。
239
-
240
- ```yaml
241
- apiVersion: apps/v1
242
- kind: Deployment
243
- metadata:
244
- name: guestbook-ui
245
- spec:
246
- replicas: 1
247
- revisionHistoryLimit: 3
248
- selector:
249
- matchLabels:
250
- app: guestbook-ui
251
- template:
252
- metadata:
253
- labels:
254
- app: guestbook-ui
255
- spec:
256
- containers:
257
- - image: gcr.io/heptio-images/ks-guestbook-demo:0.2
258
- name: guestbook-ui
259
- ports:
260
- - containerPort: 80
261
- ```
262
-
263
- #### Kustomize 形式(kustomize-guestbook)
264
-
265
- `apps/cd/argocd-example-apps/kustomize-guestbook/kustomization.yaml` は、Kustomize で複数のリソースを束ね、`namePrefix` で名前にプレフィックスを付けています。
266
-
267
- ```yaml
268
- namePrefix: kustomize-
269
-
270
- resources:
271
- - guestbook-ui-deployment.yaml
272
- - guestbook-ui-svc.yaml
273
- apiVersion: kustomize.config.k8s.io/v1beta1
274
- kind: Kustomization
275
- ```
276
-
277
- Argo CD はパスに `kustomization.yaml` があれば、自動的に Kustomize としてビルドしてから同期します。
278
-
279
- #### Helm 形式(helm-guestbook)
280
-
281
- `apps/cd/argocd-example-apps/helm-guestbook/templates/deployment.yaml` は、Helm のテンプレート構文で値を差し込む形式です(抜粋)。
282
-
283
- ```yaml
284
- apiVersion: apps/v1
285
- kind: Deployment
286
- metadata:
287
- name: {{ template "helm-guestbook.fullname" . }}
288
- spec:
289
- replicas: {{ .Values.replicaCount }}
290
- revisionHistoryLimit: 3
291
- template:
292
- spec:
293
- containers:
294
- - name: {{ .Chart.Name }}
295
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
296
- imagePullPolicy: {{ .Values.image.pullPolicy }}
297
- ```
298
-
299
- 対応する値は `apps/cd/argocd-example-apps/helm-guestbook/values.yaml` で定義されています(抜粋)。
300
-
301
- ```yaml
302
- replicaCount: 1
303
-
304
- image:
305
- repository: gcr.io/heptio-images/ks-guestbook-demo
306
- tag: 0.1
307
- pullPolicy: IfNotPresent
308
- ```
309
-
310
- Argo CD はパスに `Chart.yaml` があれば Helm チャートとして認識し、テンプレートを展開してから同期します。このように、Argo CD はアプリケーションの記述形式を問わず、統一的に「Git を正としてクラスタへ同期する」という GitOps の流儀を適用できます。
311
-
312
- ### sync-waves とリソースの適用順序
313
-
314
- 複数のリソースをデプロイするとき、適用の順序が重要になる場合があります。たとえば「データベースのスキーマを更新してから、新しいアプリケーションを起動したい」というケースです。Argo CD はこの順序制御を sync-waves と hook で実現します。
315
-
316
- `apps/cd/argocd-example-apps/sync-waves/manifests.yaml`(出典: `apps/cd/argocd-example-apps/sync-waves/`)から、適用順序を制御している箇所を抜粋します。
317
-
318
- ```yaml
319
- # PreSync フック: 本体の同期に先立って実行される(例: SQL スキーマの更新)
320
- apiVersion: batch/v1
321
- kind: Job
322
- metadata:
323
- generateName: upgrade-sql-schema
324
- annotations:
325
- argocd.argoproj.io/hook: PreSync
326
- spec:
327
- template:
328
- spec:
329
- containers:
330
- - name: upgrade-sql-schema
331
- image: alpine:latest
332
- command: ["sleep", "5"]
333
- restartPolicy: Never
334
- ---
335
- # sync-wave で適用順序を指定する(数値が小さいものから順に適用される)
336
- apiVersion: apps/v1
337
- kind: ReplicaSet
338
- metadata:
339
- name: frontend
340
- annotations:
341
- argocd.argoproj.io/sync-wave: "2"
342
- spec:
343
- # ...(省略)
344
- ```
345
-
346
- ポイントは 2 つのアノテーションです。
347
-
348
- - `argocd.argoproj.io/hook` は、同期のライフサイクル上のどの段階で実行するかを指定します。`PreSync` は本体の同期前、`PostSync` は同期後に実行されます。スキーマ移行のような「アプリより先に終えておきたい処理」は `PreSync` フックに置きます。
349
- - `argocd.argoproj.io/sync-wave` は、リソースを適用する波(wave)を数値で指定します。値が小さい波から順に適用され、各波が健全になってから次の波へ進みます。上記の例では `frontend` に `"2"` が指定されており、より小さい波のリソースが整ってから適用されます。
350
-
351
- 同様に `apps/cd/argocd-example-apps/pre-post-sync/pre-sync-job.yaml`(出典: `apps/cd/argocd-example-apps/pre-post-sync/`)にも PreSync フックの例があります。
352
-
353
- ```yaml
354
- apiVersion: batch/v1
355
- kind: Job
356
- metadata:
357
- name: before
358
- annotations:
359
- argocd.argoproj.io/hook: PreSync
360
- argocd.argoproj.io/hook-delete-policy: HookSucceeded
361
- spec:
362
- template:
363
- spec:
364
- containers:
365
- - name: sleep
366
- image: alpine:latest
367
- command: ["sleep", "10"]
368
- restartPolicy: Never
369
- backoffLimit: 0
370
- ```
371
-
372
- `hook-delete-policy: HookSucceeded` は、フックが成功したらその Job を削除する指定です。一度きりの処理が完了後にクラスタに残らないようにする、後始末のための設定です。
373
-
374
- ### blue-green デプロイの例
375
-
376
- Argo CD のサンプルには、Argo Rollouts と組み合わせた blue-green デプロイの例も含まれています。`apps/cd/argocd-example-apps/blue-green/templates/rollout.yaml`(出典: `apps/cd/argocd-example-apps/blue-green/`)では、標準の `Deployment` の代わりに Argo Rollouts が提供する `Rollout` リソースを使っています(抜粋)。
377
-
378
- ```yaml
379
- apiVersion: argoproj.io/v1alpha1
380
- kind: Rollout
381
- metadata:
382
- name: {{ template "helm-guestbook.fullname" . }}
383
- spec:
384
- replicas: {{ .Values.replicaCount }}
385
- revisionHistoryLimit: 3
386
- strategy:
387
- blueGreen:
388
- activeService: {{ template "helm-guestbook.fullname" . }}
389
- previewService: {{ template "helm-guestbook.fullname" . }}-preview
390
- template:
391
- spec:
392
- containers:
393
- - name: {{ .Chart.Name }}
394
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
395
- ```
396
-
397
- `strategy.blueGreen` がポイントです。
398
-
399
- - `activeService` は、現在ユーザーのトラフィックを受けている本番(active / blue)のサービスです。
400
- - `previewService` は、新バージョンを先行して立ち上げ、本番トラフィックを流す前に検証するための待機(preview / green)のサービスです。
401
-
402
- 新バージョンはまず preview 側で起動し、確認のうえで active を新バージョンへ切り替えます。問題があれば切り替えを止め、即座に旧バージョンへ戻せます。これにより、ダウンタイムを最小化しつつ安全にリリースできます。GitOps(Argo CD による Git からの同期)と、進行的デリバリー(Argo Rollouts による blue-green)が組み合わさっている点が、この例の見どころです。
403
-
404
- ---
405
-
406
- ## 11.4 PipeCD
407
-
408
- ### PipeCD とパイプライン定義
409
-
410
- PipeCD は、Kubernetes だけでなく Terraform、Cloud Run、AWS Lambda、Amazon ECS など複数のプラットフォームへのデプロイを、統一的なパイプラインで扱える CD ツールです。クラスタ内に常駐するエージェント `piped` が Git を監視し、定義されたパイプラインに沿ってデプロイを進めます。
411
-
412
- PipeCD では、アプリケーションごとに `app.pipecd.yaml` というファイルを置き、デプロイのパイプラインを宣言します。本節では公開サンプル集 `pipecd-examples`(出典: `pipecd-examples/README.md`)を引用します。
413
-
414
- ### パイプラインを使わないシンプルなデプロイ
415
-
416
- `pipecd-examples/kubernetes/simple/app.pipecd.yaml`(出典: `pipecd-examples/kubernetes/simple/`)は、パイプラインを定義しない最小構成です。
417
-
418
- ```yaml
419
- apiVersion: pipecd.dev/v1beta1
420
- kind: KubernetesApp
421
- spec:
422
- name: simple
423
- labels:
424
- env: example
425
- team: product
426
- input:
427
- manifests:
428
- - deployment.yaml
429
- - service.yaml
430
- kubectlVersion: 1.18.5
431
- description: |
432
- This app demonstrates how to deploy a Kubernetes application with Quick Sync strategy.
433
- ```
434
-
435
- `pipeline` を指定していないため、PipeCD は Quick Sync という方式で動作します。これは新バージョンをロールアウトし、すべてのトラフィックを一度に新バージョンへ切り替えるシンプルなデプロイです。
436
-
437
- ### カナリアデプロイのステージ
438
-
439
- `pipecd-examples/kubernetes/canary/app.pipecd.yaml`(出典: `pipecd-examples/kubernetes/canary/`)では、`pipeline.stages` にステージを並べてカナリアリリースを定義しています。
440
-
441
- ```yaml
442
- apiVersion: pipecd.dev/v1beta1
443
- kind: KubernetesApp
444
- spec:
445
- name: canary
446
- pipeline:
447
- stages:
448
- # CANARY 変種をデプロイする。レプリカ数は PRIMARY の 10%。
449
- - name: K8S_CANARY_ROLLOUT
450
- with:
451
- replicas: 10%
452
- # 次のステージへ進む前に 10 秒待つ。
453
- - name: WAIT
454
- with:
455
- duration: 10s
456
- # PRIMARY 変種を新バージョンへ更新する。
457
- - name: K8S_PRIMARY_ROLLOUT
458
- # CANARY 変種のワークロードをすべて破棄する。
459
- - name: K8S_CANARY_CLEAN
460
- ```
461
-
462
- カナリアリリースは、新バージョン(CANARY 変種)をまず小さな割合(ここでは 10%)だけ立ち上げ、問題がないことを確かめてから本番(PRIMARY 変種)を一斉に更新する手法です。最後に役目を終えた CANARY を片付けます。各ステージが順番に実行されるため、デプロイの進行を段階的に制御できます。
463
-
464
- ### ブルーグリーンデプロイのステージ
465
-
466
- `pipecd-examples/kubernetes/bluegreen/app.pipecd.yaml`(出典: `pipecd-examples/kubernetes/bluegreen/`)では、トラフィックの切り替えと手動承認を組み合わせています。
467
-
468
- ```yaml
469
- apiVersion: pipecd.dev/v1beta1
470
- kind: KubernetesApp
471
- spec:
472
- name: bluegreen
473
- pipeline:
474
- stages:
475
- # CANARY 変種を PRIMARY と同じレプリカ数でデプロイする。
476
- - name: K8S_CANARY_ROLLOUT
477
- with:
478
- replicas: 100%
479
- # トラフィックをすべて CANARY(新)へ向ける。
480
- - name: K8S_TRAFFIC_ROUTING
481
- with:
482
- canary: 100
483
- # 手動承認を待つ。
484
- - name: WAIT_APPROVAL
485
- # PRIMARY を新バージョンへ更新する。
486
- - name: K8S_PRIMARY_ROLLOUT
487
- # トラフィックをすべて PRIMARY へ戻す。
488
- - name: K8S_TRAFFIC_ROUTING
489
- with:
490
- primary: 100
491
- # CANARY 変種を破棄する。
492
- - name: K8S_CANARY_CLEAN
493
- ```
494
-
495
- `K8S_TRAFFIC_ROUTING` でトラフィックの向き先を切り替え、`WAIT_APPROVAL` で人による最終確認を挟んでいます。新旧両系統を同時に動かしておき、トラフィックの切り替えで瞬時に切り戻せるのがブルーグリーンの利点です。
496
-
497
- ### 分析(analysis)ステージによる自動検証
498
-
499
- PipeCD の強力な機能が、ANALYSIS ステージによる自動検証です。`pipecd-examples/kubernetes/analysis-by-metrics/app.pipecd.yaml`(出典: `pipecd-examples/kubernetes/analysis-by-metrics/`)では、カナリアに流したトラフィックのメトリクスを Prometheus で監視し、品質を自動で判定しています。
500
-
501
- ```yaml
502
- apiVersion: pipecd.dev/v1beta1
503
- kind: KubernetesApp
504
- spec:
505
- name: analysis-by-metrics
506
- pipeline:
507
- stages:
508
- - name: K8S_CANARY_ROLLOUT
509
- with:
510
- replicas: 20%
511
- - name: ANALYSIS
512
- with:
513
- duration: 30m
514
- metrics:
515
- - strategy: THRESHOLD
516
- provider: my-prometheus
517
- interval: 5m
518
- expected:
519
- max: 0.01
520
- query: |
521
- sum by (job) (rate(http_requests_total{status=~"5.*", job="analysis"}[5m]))
522
- /
523
- sum by (job) (rate(http_requests_total{job="analysis"}[5m]))
524
- - name: K8S_PRIMARY_ROLLOUT
525
- - name: K8S_CANARY_CLEAN
526
- ```
527
-
528
- この設定では、20% のトラフィックを新バージョンに流したうえで、30 分間にわたり 5 分ごとに Prometheus へクエリを投げます。クエリはエラー(HTTP 5xx)の割合を計算しており、`expected.max: 0.01`(1%)を超えると分析は失敗と判定されます。分析に成功すれば `K8S_PRIMARY_ROLLOUT` へ進んで本番を更新し、失敗すればパイプラインは中断されます。
529
-
530
- `pipecd-examples` の README には、メトリクスのほかに HTTP リクエストの結果で判定する `analysis-by-http`、ログの内容で判定する `analysis-by-log`、ベースラインと比較する `analysis-with-baseline` といった分析のバリエーションも紹介されています。いずれも「人が目視で確認していた品質チェックを、機械が客観的な指標で自動的に行う」ための仕組みです。これにより、悪いバージョンが本番全体へ広がる前に、自動的にデプロイを止められます。
531
-
532
- ---
533
-
534
- ## 11.5 ソフトウェアデリバリーの完全自動化
535
-
536
- ここまで見てきた要素を組み合わせると、コードの変更からユーザーへの価値提供までを、人手を介さずに自動化する全体像が描けます。第 10 章で構築した CI と接続して、デリバリーのパイプライン全体を振り返ります。
537
-
538
- ### 完全自動化の全体像
539
-
540
- ```text
541
- 1. 開発者がアプリのコードを変更し、Git に push
542
- |
543
- v
544
- 2. CI(第 10 章): テスト実行 → Docker イメージのビルド → レジストリへ push
545
- |
546
- v
547
- 3. マニフェスト更新: 新しいイメージタグをマニフェストリポジトリへ反映(Git にコミット)
548
- |
549
- v
550
- 4. CD(GitOps 自動同期): Flux / Argo CD がマニフェストの変更を検知し、クラスタへ同期
551
- |
552
- v
553
- 5. 進行的デリバリー: カナリア投入 → 自動分析(メトリクス検証)
554
- |
555
- +-- 分析 OK --> 本番(PRIMARY)を更新して完了
556
- |
557
- +-- 分析 NG --> 自動ロールバック(旧バージョンを維持)
558
- ```
559
-
560
- それぞれの段階を、これまでの内容と対応づけて整理します。
561
-
562
- 1. CI(イメージのビルドと push)
563
-
564
- 第 10 章で扱った CI が担います。コードの変更をきっかけにテストを通し、Docker イメージをビルドしてレジストリへ push します。ここで「デプロイ可能な成果物」が生まれます。
565
-
566
- 2. マニフェストの更新
567
-
568
- CI の成果物である新しいイメージタグを、GitOps が監視するマニフェストリポジトリに反映します。`echo-bootstrap` のようなマニフェストリポジトリのイメージ指定を、新しいタグへ書き換えてコミットするイメージです。この「Git へのコミット」が、デプロイのトリガーになります。
569
-
570
- 3. CD(GitOps 自動同期)
571
-
572
- Flux の `source-controller` / `kustomize-controller`、あるいは Argo CD の `Application` が、マニフェストの変更を検知してクラスタへ自動同期します。pull 型なので、クラスタ外に強い権限を渡す必要がありません。Git が唯一の情報源であり続けるため、いつでも `git revert` で過去の状態へ戻せます。
573
-
574
- 4. 進行的デリバリー(カナリア + 自動分析 + 自動ロールバック)
575
-
576
- Argo Rollouts や PipeCD のパイプラインが、新バージョンをいきなり全面展開するのではなく、カナリアとして一部のトラフィックから始めます。PipeCD の `ANALYSIS` ステージのように、メトリクスを自動で検証し、品質基準を満たせば本番を更新し、満たさなければデプロイを中断して旧バージョンを維持します。これが自動ロールバックです。
577
-
578
- このパイプラインの価値は明確です。人手による `kubectl apply` や、目視によるリリース後の監視といった、ミスが起きやすく属人的な作業がなくなります。問題のあるバージョンはユーザー全体に届く前に自動で食い止められ、万一のときは Git の履歴で安全に巻き戻せます。まさに「変更を楽に安全にできて役に立つソフトウェア」を、継続的に届け続けられる状態です。
579
-
580
- ---
581
-
582
- ## まとめ
583
-
584
- この章では、コンテナにおける継続的デリバリー(CD)を扱いました。
585
-
586
- - CI が「デプロイ可能な成果物(イメージ)を作る」工程であるのに対し、CD は「成果物を確実に届ける」工程です。両者は連続しつつも責務が異なります。
587
- - GitOps は、Git を信頼できる唯一の情報源とし、宣言的マニフェストをクラスタへ自動同期する考え方です。同期方式には push 型と pull 型があり、GitOps ツールの多くはセキュリティ面で有利な pull 型を採用します。
588
- - Flux は `source-controller` と `kustomize-controller` が連携し、Git の変更を検知してクラスタへ同期する pull 型ツールです。`echo-bootstrap` のような Kustomize マニフェストを配信対象にできます。
589
- - Argo CD は `Application` リソースで同期対象を定義し、プレーン YAML / Kustomize / Helm のいずれの形式も扱えます。sync-waves と hook でリソースの適用順序を制御でき、Argo Rollouts と組み合わせれば blue-green デプロイも実現できます。
590
- - PipeCD は `app.pipecd.yaml` でパイプラインを宣言し、カナリア・ブルーグリーンの各ステージや、メトリクスによる `ANALYSIS` ステージで品質を自動検証できます。
591
- - これらを組み合わせると、CI(ビルド/push)→ CD(GitOps 自動同期)→ 進行的デリバリー(カナリア + 自動分析 + 自動ロールバック)という、ソフトウェアデリバリーの完全自動化が実現します。
592
-
593
- なお、本章で示した `GitRepository` / `Kustomization` / `Application` の各 CRD のうち、サンプルリポジトリに実ファイルとして含まれていたのは `argocd-example-apps`、`pipecd-examples`、`echo-bootstrap` の配信対象マニフェストです。Flux 側および Argo CD の `Application` の設定例は、ツールの一般的な書き方として示した参考例です。実際に利用する際は、各ツールの公式ドキュメントで最新の API バージョンを確認してください。
594
-
595
- ---
596
-
597
- - 前の章: [第 10 章 最適なコンテナイメージ作成と運用](10-optimal-container-image.md)
598
- - 次の章: [第 12 章 コンテナのさまざまな活用方法](12-container-use-cases.md)
1
+ ---
2
+ type: Article
3
+ title: "第 11 章 コンテナにおける継続的デリバリー"
4
+ description: "前章では CI(継続的インテグレーション)について学び、コードの変更をきっかけにテストとイメージのビルド・push を自動化する仕組みを構築しました。"
5
+ tags: [article, getting-start-docker-kubernetes]
6
+ status: stable
7
+ generated: { by: human:kakimomokuri, at: 2026-06-26T00:29:42Z }
8
+ ---
9
+
10
+ # 第 11 章 コンテナにおける継続的デリバリー
11
+
12
+ ![コンテナにおける継続的デリバリーを説明する 4 コマ漫画](images/chapter-11-comic.png)
13
+
14
+ *コード変更からテスト、ビルド、イメージ公開、クラスタへの反映までを自動化します。*
15
+
16
+ ## はじめに
17
+
18
+ 前章では CI(継続的インテグレーション)について学び、コードの変更をきっかけにテストとイメージのビルド・push を自動化する仕組みを構築しました。しかし、イメージがレジストリに push されただけでは、ユーザーに価値が届いたことにはなりません。ビルドされたイメージを Kubernetes クラスタへ確実にデプロイし、はじめてソフトウェアは「役に立つ」状態になります。
19
+
20
+ この章では、CI に続く工程である CD(継続的デリバリー)を扱います。特に、コンテナと Kubernetes の世界で標準的なアプローチとなった GitOps と、それを実現する代表的なツールである Flux、Argo CD、PipeCD を取り上げます。それぞれのツールが実際にどのようなマニフェストや設定ファイルで動くのかを、公開されているサンプルリポジトリの実コードを引用しながら確認していきます。
21
+
22
+ 最後に、CI から CD、さらに進行的デリバリー(カナリアリリースと自動分析、自動ロールバック)までをつなげ、ソフトウェアデリバリーを完全に自動化する全体像をまとめます。
23
+
24
+ 「変更を楽に安全にできて役に立つソフトウェア」を継続的に届けるための土台が、この章のテーマです。
25
+
26
+ ### 目次
27
+
28
+ 1. [継続的デリバリーとは](#111-継続的デリバリーとは)
29
+ 2. [Flux](#112-flux)
30
+ 3. [Argo CD](#113-argo-cd)
31
+ 4. [PipeCD](#114-pipecd)
32
+ 5. [ソフトウェアデリバリーの完全自動化](#115-ソフトウェアデリバリーの完全自動化)
33
+
34
+ ---
35
+
36
+ ## 11.1 継続的デリバリーとは
37
+
38
+ ### CI と CD の違い
39
+
40
+ まず、CI と CD の役割を整理します。両者は連続した工程ですが、責務が明確に異なります。
41
+
42
+ - CI(Continuous Integration / 継続的インテグレーション)
43
+
44
+ 開発者が頻繁にコードを統合し、その都度テストとビルドを自動で実行する活動です。コンテナの文脈では「テストを通し、Docker イメージをビルドしてレジストリに push する」ところまでが CI の責務になります。CI のゴールは「いつでもデプロイ可能な成果物(イメージ)」を作り続けることです。
45
+
46
+ - CD(Continuous Delivery / 継続的デリバリー)
47
+
48
+ CI が生んだ成果物を、実際に動作する環境へ確実に届ける活動です。コンテナの文脈では「レジストリのイメージを Kubernetes クラスタにデプロイし、望ましい状態を維持する」ところが CD の責務になります。CD のゴールは「成果物をいつでも安全にリリースできる状態」を保つことです。
49
+
50
+ CI と CD の境界を図にすると次のようになります。
51
+
52
+ ```text
53
+ [開発者] --push--> [Git リポジトリ]
54
+ |
55
+ (CI: テスト/ビルド/push)
56
+ v
57
+ [コンテナレジストリ] <- ここまでが CI
58
+ |
59
+ (CD: デプロイ/同期)
60
+ v
61
+ [Kubernetes クラスタ] <- ここからが CD
62
+ ```
63
+
64
+ CI については第 10 章で扱いました。この章では、レジストリにイメージが置かれた後の CD に焦点を当てます。
65
+
66
+ ### GitOps という考え方
67
+
68
+ Kubernetes のデプロイにおいて、近年の標準的なアプローチとなったのが GitOps です。GitOps の中心にあるのは次の 2 つの原則です。
69
+
70
+ 1. Git を信頼できる唯一の情報源(Single Source of Truth)とする
71
+
72
+ クラスタにあるべき状態(Deployment、Service、ConfigMap など)を、すべて宣言的なマニフェストとして Git リポジトリで管理します。「本番環境がどうあるべきか」を知りたければ Git を見れば良い、という状態を作ります。
73
+
74
+ 2. 宣言的マニフェストをクラスタへ自動同期する
75
+
76
+ Git に書かれた「あるべき状態」と、クラスタの「現在の状態」をツールが常に比較し、差分があれば自動的に同期して一致させます。
77
+
78
+ この考え方の利点は、本書全体を貫く「変更を楽に安全にできる」という価値に直結します。デプロイは `git push`(あるいは Pull Request のマージ)という、開発者が日常的に行う操作に統一されます。誰がいつ何を変更したかは Git の履歴に残り、問題があれば `git revert` で過去の状態に戻せます。手作業の `kubectl apply` に頼らないため、操作ミスや環境ごとの設定のばらつきも減ります。
79
+
80
+ ### push 型と pull 型
81
+
82
+ CD の同期方式には、大きく分けて push 型と pull 型があります。
83
+
84
+ - push 型
85
+
86
+ CI/CD パイプライン(GitHub Actions など)の側から、クラスタに対して `kubectl apply` などで変更を「押し込む」方式です。仕組みが理解しやすい反面、パイプライン側にクラスタへの認証情報(kubeconfig など)を持たせる必要があり、クラスタの外から強い権限でアクセスできてしまう点に注意が必要です。
87
+
88
+ - pull 型
89
+
90
+ クラスタ内に常駐するエージェントが、Git リポジトリを定期的に監視し、変更を検知すると自身でクラスタへ反映する方式です。クラスタの外部に認証情報を渡す必要がなく、エージェントがクラスタ内部から動作するためセキュリティ面で有利です。GitOps を掲げるツールの多くは、この pull 型を採用しています。
91
+
92
+ ```text
93
+ push 型: [パイプライン] --kubectl apply--> [クラスタ]
94
+ pull 型: [クラスタ内エージェント] --watch/pull--> [Git リポジトリ]
95
+ ```
96
+
97
+ これから紹介する Flux と Argo CD は pull 型の GitOps ツールです。PipeCD も Git を起点とし、クラスタ内の `piped` というエージェントが同期を担うため、pull 型の性質を持ちます。
98
+
99
+ ---
100
+
101
+ ## 11.2 Flux
102
+
103
+ ### Flux の仕組み
104
+
105
+ Flux は CNCF(Cloud Native Computing Foundation)の卒業プロジェクトで、pull 型 GitOps を実現するツールです。Flux はモノリシックな単一のコンポーネントではなく、役割ごとに分かれた複数のコントローラ(GitOps Toolkit と呼ばれます)の集合として構成されています。代表的なものは次の 2 つです。
106
+
107
+ - source-controller
108
+
109
+ Git リポジトリや Helm リポジトリ、OCI レジストリなどの「ソース」を監視し、指定したリビジョンのマニフェストを取得して、クラスタ内のほかのコントローラから参照できるようにします。
110
+
111
+ - kustomize-controller
112
+
113
+ source-controller が取得したマニフェスト(Kustomize で管理されたものを含む)を、実際にクラスタへ適用します。Git 上の状態とクラスタの状態を継続的に突き合わせ、差分があれば同期します。
114
+
115
+ 動作の流れは次のようになります。
116
+
117
+ ```text
118
+ [Git リポジトリ] --watch--> [source-controller] --取得--> [kustomize-controller] --apply--> [クラスタ]
119
+ ```
120
+
121
+ 開発者が Git にマニフェストの変更を push すると、source-controller がそれを検知し、kustomize-controller がクラスタへ反映します。クラスタ側で誰かが手動で設定を書き換えても、Flux が Git の状態へ引き戻す(ドリフトの是正)ため、Git が常に正となります。
122
+
123
+ ### 配信対象となる Kustomize マニフェストの例
124
+
125
+ Flux が配信する対象は、宣言的に書かれた Kubernetes マニフェストです。本書のサンプルリポジトリ `echo-bootstrap`(出典: `apps/cd/echo-bootstrap/`)には、Kustomize で束ねられたマニフェスト群が含まれています。これは GitOps で配信するアプリケーションの典型例として参考になります。
126
+
127
+ `apps/cd/echo-bootstrap/kustomization.yaml` は、複数のマニフェストを 1 つのアプリケーションとしてまとめています。
128
+
129
+ ```yaml
130
+ apiVersion: kustomize.config.k8s.io/v1beta1
131
+ kind: Kustomization
132
+ namespace: gitops-echo
133
+ resources:
134
+ - namespace.yaml
135
+ - deployment.yaml
136
+ - ingress.yaml
137
+ - service.yaml
138
+ commonLabels:
139
+ app.kubernetes.io/name: echo
140
+ ```
141
+
142
+ 実際に配信される Deployment は `apps/cd/echo-bootstrap/deployment.yaml` に定義されています(抜粋)。
143
+
144
+ ```yaml
145
+ apiVersion: apps/v1
146
+ kind: Deployment
147
+ metadata:
148
+ name: echo
149
+ labels:
150
+ app.kubernetes.io/name: echo
151
+ spec:
152
+ replicas: 1
153
+ selector:
154
+ matchLabels:
155
+ app.kubernetes.io/name: echo
156
+ template:
157
+ metadata:
158
+ labels:
159
+ app.kubernetes.io/name: echo
160
+ spec:
161
+ containers:
162
+ - name: nginx
163
+ image: ghcr.io/gihyodocker/simple-nginx-proxy:v0.1.0
164
+ # ...(環境変数の定義は省略)
165
+ - name: echo
166
+ image: ghcr.io/gihyodocker/echo:v0.1.0-slim
167
+ ```
168
+
169
+ このように、`gitops-echo` という名前空間に `echo` という Deployment を配置することが Git 上で宣言されています。Flux はこの Git 上の宣言をクラスタの「あるべき状態」とみなして同期します。
170
+
171
+ ### Flux にこのマニフェストを配信させる設定例
172
+
173
+ ここからは一般的な例です(`echo-bootstrap` リポジトリには含まれていない、Flux 側の設定の書き方を示します)。Flux にこの `echo-bootstrap` を監視させるには、`GitRepository` と `Kustomization` という 2 つのカスタムリソース(CRD)を Flux 自身に与えます。次は一般的に正しい記述の例です。
174
+
175
+ ```yaml
176
+ # 例: Git リポジトリを監視対象として登録する(GitRepository CRD)
177
+ apiVersion: source.toolkit.fluxcd.io/v1
178
+ kind: GitRepository
179
+ metadata:
180
+ name: echo-bootstrap
181
+ namespace: flux-system
182
+ spec:
183
+ interval: 1m # 1 分ごとにリポジトリをチェックする
184
+ url: https://github.com/example/echo-bootstrap
185
+ ref:
186
+ branch: main # 監視するブランチ(リビジョン)
187
+ ---
188
+ # 例: 取得したマニフェストをクラスタへ同期する(Kustomization CRD)
189
+ apiVersion: kustomize.toolkit.fluxcd.io/v1
190
+ kind: Kustomization
191
+ metadata:
192
+ name: echo
193
+ namespace: flux-system
194
+ spec:
195
+ interval: 5m # 5 分ごとにクラスタとの差分を是正する
196
+ sourceRef:
197
+ kind: GitRepository
198
+ name: echo-bootstrap
199
+ path: "./" # kustomization.yaml の場所
200
+ prune: true # Git から削除されたリソースはクラスタからも削除する
201
+ ```
202
+
203
+ `GitRepository` が「どこを見るか(リポジトリとリビジョン)」を、`Kustomization` が「取得したもののどのパスを、どう同期するか」を定義します。`prune: true` を指定すると、Git から消したリソースはクラスタからも削除されるため、Git の状態とクラスタの状態が厳密に一致します。これが GitOps における「Git を唯一の情報源とする」の具体的な姿です。
204
+
205
+ ---
206
+
207
+ ## 11.3 Argo CD
208
+
209
+ ### Argo CD と Application
210
+
211
+ Argo CD も pull 型 GitOps を実現する CNCF プロジェクトです。Flux との大きな違いは、Web UI を備え、アプリケーションの同期状態(Synced / OutOfSync)や健全性(Healthy など)を視覚的に確認できる点にあります。
212
+
213
+ Argo CD では、同期対象を `Application` というカスタムリソースで表現します。`Application` には「どの Git リポジトリの、どのパスの、どのリビジョンを、どの名前空間に同期するか」を記述します。本節では、Argo CD のデモ用に公開されているサンプル集 `argocd-example-apps`(出典: `apps/cd/argocd-example-apps/`)を引用しながら解説します。
214
+
215
+ `Application` の記述は一般的に次のような形になります(一般例。`argocd-example-apps` のアプリを同期対象とした場合)。
216
+
217
+ ```yaml
218
+ # 例: guestbook を同期対象とする Application
219
+ apiVersion: argoproj.io/v1alpha1
220
+ kind: Application
221
+ metadata:
222
+ name: guestbook
223
+ namespace: argocd
224
+ spec:
225
+ project: default
226
+ source:
227
+ repoURL: https://github.com/argoproj/argocd-example-apps.git
228
+ targetRevision: HEAD # 同期対象のリビジョン
229
+ path: guestbook # 同期対象の Git パス
230
+ destination:
231
+ server: https://kubernetes.default.svc
232
+ namespace: default
233
+ syncPolicy:
234
+ automated: # Git の変更を自動で同期する
235
+ prune: true
236
+ selfHeal: true
237
+ ```
238
+
239
+ `source.path` と `source.targetRevision` が、まさに「Git のどこを正とするか」を指定する部分です。`syncPolicy.automated` を設定すると、Git の変更を検知して自動同期し、クラスタ側のドリフトも自動是正します。
240
+
241
+ ### さまざまなマニフェスト形式
242
+
243
+ `argocd-example-apps` の README(出典: `apps/cd/argocd-example-apps/README.md`)には、同じ guestbook アプリをさまざまな形式で表現したサンプルが並んでいます。Argo CD は、プレーンな YAML、Kustomize、Helm のいずれの形式でもそのまま同期できます。
244
+
245
+ #### プレーン YAML 形式(guestbook)
246
+
247
+ `apps/cd/argocd-example-apps/guestbook/guestbook-ui-deployment.yaml` は、テンプレート機構を使わない素の Kubernetes マニフェストです。
248
+
249
+ ```yaml
250
+ apiVersion: apps/v1
251
+ kind: Deployment
252
+ metadata:
253
+ name: guestbook-ui
254
+ spec:
255
+ replicas: 1
256
+ revisionHistoryLimit: 3
257
+ selector:
258
+ matchLabels:
259
+ app: guestbook-ui
260
+ template:
261
+ metadata:
262
+ labels:
263
+ app: guestbook-ui
264
+ spec:
265
+ containers:
266
+ - image: gcr.io/heptio-images/ks-guestbook-demo:0.2
267
+ name: guestbook-ui
268
+ ports:
269
+ - containerPort: 80
270
+ ```
271
+
272
+ #### Kustomize 形式(kustomize-guestbook)
273
+
274
+ `apps/cd/argocd-example-apps/kustomize-guestbook/kustomization.yaml` は、Kustomize で複数のリソースを束ね、`namePrefix` で名前にプレフィックスを付けています。
275
+
276
+ ```yaml
277
+ namePrefix: kustomize-
278
+
279
+ resources:
280
+ - guestbook-ui-deployment.yaml
281
+ - guestbook-ui-svc.yaml
282
+ apiVersion: kustomize.config.k8s.io/v1beta1
283
+ kind: Kustomization
284
+ ```
285
+
286
+ Argo CD はパスに `kustomization.yaml` があれば、自動的に Kustomize としてビルドしてから同期します。
287
+
288
+ #### Helm 形式(helm-guestbook)
289
+
290
+ `apps/cd/argocd-example-apps/helm-guestbook/templates/deployment.yaml` は、Helm のテンプレート構文で値を差し込む形式です(抜粋)。
291
+
292
+ ```yaml
293
+ apiVersion: apps/v1
294
+ kind: Deployment
295
+ metadata:
296
+ name: {{ template "helm-guestbook.fullname" . }}
297
+ spec:
298
+ replicas: {{ .Values.replicaCount }}
299
+ revisionHistoryLimit: 3
300
+ template:
301
+ spec:
302
+ containers:
303
+ - name: {{ .Chart.Name }}
304
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
305
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
306
+ ```
307
+
308
+ 対応する値は `apps/cd/argocd-example-apps/helm-guestbook/values.yaml` で定義されています(抜粋)。
309
+
310
+ ```yaml
311
+ replicaCount: 1
312
+
313
+ image:
314
+ repository: gcr.io/heptio-images/ks-guestbook-demo
315
+ tag: 0.1
316
+ pullPolicy: IfNotPresent
317
+ ```
318
+
319
+ Argo CD はパスに `Chart.yaml` があれば Helm チャートとして認識し、テンプレートを展開してから同期します。このように、Argo CD はアプリケーションの記述形式を問わず、統一的に「Git を正としてクラスタへ同期する」という GitOps の流儀を適用できます。
320
+
321
+ ### sync-waves とリソースの適用順序
322
+
323
+ 複数のリソースをデプロイするとき、適用の順序が重要になる場合があります。たとえば「データベースのスキーマを更新してから、新しいアプリケーションを起動したい」というケースです。Argo CD はこの順序制御を sync-waves と hook で実現します。
324
+
325
+ `apps/cd/argocd-example-apps/sync-waves/manifests.yaml`(出典: `apps/cd/argocd-example-apps/sync-waves/`)から、適用順序を制御している箇所を抜粋します。
326
+
327
+ ```yaml
328
+ # PreSync フック: 本体の同期に先立って実行される(例: SQL スキーマの更新)
329
+ apiVersion: batch/v1
330
+ kind: Job
331
+ metadata:
332
+ generateName: upgrade-sql-schema
333
+ annotations:
334
+ argocd.argoproj.io/hook: PreSync
335
+ spec:
336
+ template:
337
+ spec:
338
+ containers:
339
+ - name: upgrade-sql-schema
340
+ image: alpine:latest
341
+ command: ["sleep", "5"]
342
+ restartPolicy: Never
343
+ ---
344
+ # sync-wave で適用順序を指定する(数値が小さいものから順に適用される)
345
+ apiVersion: apps/v1
346
+ kind: ReplicaSet
347
+ metadata:
348
+ name: frontend
349
+ annotations:
350
+ argocd.argoproj.io/sync-wave: "2"
351
+ spec:
352
+ # ...(省略)
353
+ ```
354
+
355
+ ポイントは 2 つのアノテーションです。
356
+
357
+ - `argocd.argoproj.io/hook` は、同期のライフサイクル上のどの段階で実行するかを指定します。`PreSync` は本体の同期前、`PostSync` は同期後に実行されます。スキーマ移行のような「アプリより先に終えておきたい処理」は `PreSync` フックに置きます。
358
+ - `argocd.argoproj.io/sync-wave` は、リソースを適用する波(wave)を数値で指定します。値が小さい波から順に適用され、各波が健全になってから次の波へ進みます。上記の例では `frontend` に `"2"` が指定されており、より小さい波のリソースが整ってから適用されます。
359
+
360
+ 同様に `apps/cd/argocd-example-apps/pre-post-sync/pre-sync-job.yaml`(出典: `apps/cd/argocd-example-apps/pre-post-sync/`)にも PreSync フックの例があります。
361
+
362
+ ```yaml
363
+ apiVersion: batch/v1
364
+ kind: Job
365
+ metadata:
366
+ name: before
367
+ annotations:
368
+ argocd.argoproj.io/hook: PreSync
369
+ argocd.argoproj.io/hook-delete-policy: HookSucceeded
370
+ spec:
371
+ template:
372
+ spec:
373
+ containers:
374
+ - name: sleep
375
+ image: alpine:latest
376
+ command: ["sleep", "10"]
377
+ restartPolicy: Never
378
+ backoffLimit: 0
379
+ ```
380
+
381
+ `hook-delete-policy: HookSucceeded` は、フックが成功したらその Job を削除する指定です。一度きりの処理が完了後にクラスタに残らないようにする、後始末のための設定です。
382
+
383
+ ### blue-green デプロイの例
384
+
385
+ Argo CD のサンプルには、Argo Rollouts と組み合わせた blue-green デプロイの例も含まれています。`apps/cd/argocd-example-apps/blue-green/templates/rollout.yaml`(出典: `apps/cd/argocd-example-apps/blue-green/`)では、標準の `Deployment` の代わりに Argo Rollouts が提供する `Rollout` リソースを使っています(抜粋)。
386
+
387
+ ```yaml
388
+ apiVersion: argoproj.io/v1alpha1
389
+ kind: Rollout
390
+ metadata:
391
+ name: {{ template "helm-guestbook.fullname" . }}
392
+ spec:
393
+ replicas: {{ .Values.replicaCount }}
394
+ revisionHistoryLimit: 3
395
+ strategy:
396
+ blueGreen:
397
+ activeService: {{ template "helm-guestbook.fullname" . }}
398
+ previewService: {{ template "helm-guestbook.fullname" . }}-preview
399
+ template:
400
+ spec:
401
+ containers:
402
+ - name: {{ .Chart.Name }}
403
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
404
+ ```
405
+
406
+ `strategy.blueGreen` がポイントです。
407
+
408
+ - `activeService` は、現在ユーザーのトラフィックを受けている本番(active / blue)のサービスです。
409
+ - `previewService` は、新バージョンを先行して立ち上げ、本番トラフィックを流す前に検証するための待機(preview / green)のサービスです。
410
+
411
+ 新バージョンはまず preview 側で起動し、確認のうえで active を新バージョンへ切り替えます。問題があれば切り替えを止め、即座に旧バージョンへ戻せます。これにより、ダウンタイムを最小化しつつ安全にリリースできます。GitOps(Argo CD による Git からの同期)と、進行的デリバリー(Argo Rollouts による blue-green)が組み合わさっている点が、この例の見どころです。
412
+
413
+ ---
414
+
415
+ ## 11.4 PipeCD
416
+
417
+ ### PipeCD とパイプライン定義
418
+
419
+ PipeCD は、Kubernetes だけでなく Terraform、Cloud Run、AWS Lambda、Amazon ECS など複数のプラットフォームへのデプロイを、統一的なパイプラインで扱える CD ツールです。クラスタ内に常駐するエージェント `piped` が Git を監視し、定義されたパイプラインに沿ってデプロイを進めます。
420
+
421
+ PipeCD では、アプリケーションごとに `app.pipecd.yaml` というファイルを置き、デプロイのパイプラインを宣言します。本節では公開サンプル集 `pipecd-examples`(出典: `pipecd-examples/README.md`)を引用します。
422
+
423
+ ### パイプラインを使わないシンプルなデプロイ
424
+
425
+ `pipecd-examples/kubernetes/simple/app.pipecd.yaml`(出典: `pipecd-examples/kubernetes/simple/`)は、パイプラインを定義しない最小構成です。
426
+
427
+ ```yaml
428
+ apiVersion: pipecd.dev/v1beta1
429
+ kind: KubernetesApp
430
+ spec:
431
+ name: simple
432
+ labels:
433
+ env: example
434
+ team: product
435
+ input:
436
+ manifests:
437
+ - deployment.yaml
438
+ - service.yaml
439
+ kubectlVersion: 1.18.5
440
+ description: |
441
+ This app demonstrates how to deploy a Kubernetes application with Quick Sync strategy.
442
+ ```
443
+
444
+ `pipeline` を指定していないため、PipeCD は Quick Sync という方式で動作します。これは新バージョンをロールアウトし、すべてのトラフィックを一度に新バージョンへ切り替えるシンプルなデプロイです。
445
+
446
+ ### カナリアデプロイのステージ
447
+
448
+ `pipecd-examples/kubernetes/canary/app.pipecd.yaml`(出典: `pipecd-examples/kubernetes/canary/`)では、`pipeline.stages` にステージを並べてカナリアリリースを定義しています。
449
+
450
+ ```yaml
451
+ apiVersion: pipecd.dev/v1beta1
452
+ kind: KubernetesApp
453
+ spec:
454
+ name: canary
455
+ pipeline:
456
+ stages:
457
+ # CANARY 変種をデプロイする。レプリカ数は PRIMARY の 10%。
458
+ - name: K8S_CANARY_ROLLOUT
459
+ with:
460
+ replicas: 10%
461
+ # 次のステージへ進む前に 10 秒待つ。
462
+ - name: WAIT
463
+ with:
464
+ duration: 10s
465
+ # PRIMARY 変種を新バージョンへ更新する。
466
+ - name: K8S_PRIMARY_ROLLOUT
467
+ # CANARY 変種のワークロードをすべて破棄する。
468
+ - name: K8S_CANARY_CLEAN
469
+ ```
470
+
471
+ カナリアリリースは、新バージョン(CANARY 変種)をまず小さな割合(ここでは 10%)だけ立ち上げ、問題がないことを確かめてから本番(PRIMARY 変種)を一斉に更新する手法です。最後に役目を終えた CANARY を片付けます。各ステージが順番に実行されるため、デプロイの進行を段階的に制御できます。
472
+
473
+ ### ブルーグリーンデプロイのステージ
474
+
475
+ `pipecd-examples/kubernetes/bluegreen/app.pipecd.yaml`(出典: `pipecd-examples/kubernetes/bluegreen/`)では、トラフィックの切り替えと手動承認を組み合わせています。
476
+
477
+ ```yaml
478
+ apiVersion: pipecd.dev/v1beta1
479
+ kind: KubernetesApp
480
+ spec:
481
+ name: bluegreen
482
+ pipeline:
483
+ stages:
484
+ # CANARY 変種を PRIMARY と同じレプリカ数でデプロイする。
485
+ - name: K8S_CANARY_ROLLOUT
486
+ with:
487
+ replicas: 100%
488
+ # トラフィックをすべて CANARY(新)へ向ける。
489
+ - name: K8S_TRAFFIC_ROUTING
490
+ with:
491
+ canary: 100
492
+ # 手動承認を待つ。
493
+ - name: WAIT_APPROVAL
494
+ # PRIMARY を新バージョンへ更新する。
495
+ - name: K8S_PRIMARY_ROLLOUT
496
+ # トラフィックをすべて PRIMARY へ戻す。
497
+ - name: K8S_TRAFFIC_ROUTING
498
+ with:
499
+ primary: 100
500
+ # CANARY 変種を破棄する。
501
+ - name: K8S_CANARY_CLEAN
502
+ ```
503
+
504
+ `K8S_TRAFFIC_ROUTING` でトラフィックの向き先を切り替え、`WAIT_APPROVAL` で人による最終確認を挟んでいます。新旧両系統を同時に動かしておき、トラフィックの切り替えで瞬時に切り戻せるのがブルーグリーンの利点です。
505
+
506
+ ### 分析(analysis)ステージによる自動検証
507
+
508
+ PipeCD の強力な機能が、ANALYSIS ステージによる自動検証です。`pipecd-examples/kubernetes/analysis-by-metrics/app.pipecd.yaml`(出典: `pipecd-examples/kubernetes/analysis-by-metrics/`)では、カナリアに流したトラフィックのメトリクスを Prometheus で監視し、品質を自動で判定しています。
509
+
510
+ ```yaml
511
+ apiVersion: pipecd.dev/v1beta1
512
+ kind: KubernetesApp
513
+ spec:
514
+ name: analysis-by-metrics
515
+ pipeline:
516
+ stages:
517
+ - name: K8S_CANARY_ROLLOUT
518
+ with:
519
+ replicas: 20%
520
+ - name: ANALYSIS
521
+ with:
522
+ duration: 30m
523
+ metrics:
524
+ - strategy: THRESHOLD
525
+ provider: my-prometheus
526
+ interval: 5m
527
+ expected:
528
+ max: 0.01
529
+ query: |
530
+ sum by (job) (rate(http_requests_total{status=~"5.*", job="analysis"}[5m]))
531
+ /
532
+ sum by (job) (rate(http_requests_total{job="analysis"}[5m]))
533
+ - name: K8S_PRIMARY_ROLLOUT
534
+ - name: K8S_CANARY_CLEAN
535
+ ```
536
+
537
+ この設定では、20% のトラフィックを新バージョンに流したうえで、30 分間にわたり 5 分ごとに Prometheus へクエリを投げます。クエリはエラー(HTTP 5xx)の割合を計算しており、`expected.max: 0.01`(1%)を超えると分析は失敗と判定されます。分析に成功すれば `K8S_PRIMARY_ROLLOUT` へ進んで本番を更新し、失敗すればパイプラインは中断されます。
538
+
539
+ `pipecd-examples` の README には、メトリクスのほかに HTTP リクエストの結果で判定する `analysis-by-http`、ログの内容で判定する `analysis-by-log`、ベースラインと比較する `analysis-with-baseline` といった分析のバリエーションも紹介されています。いずれも「人が目視で確認していた品質チェックを、機械が客観的な指標で自動的に行う」ための仕組みです。これにより、悪いバージョンが本番全体へ広がる前に、自動的にデプロイを止められます。
540
+
541
+ ---
542
+
543
+ ## 11.5 ソフトウェアデリバリーの完全自動化
544
+
545
+ ここまで見てきた要素を組み合わせると、コードの変更からユーザーへの価値提供までを、人手を介さずに自動化する全体像が描けます。第 10 章で構築した CI と接続して、デリバリーのパイプライン全体を振り返ります。
546
+
547
+ ### 完全自動化の全体像
548
+
549
+ ```text
550
+ 1. 開発者がアプリのコードを変更し、Git に push
551
+ |
552
+ v
553
+ 2. CI(第 10 章): テスト実行 → Docker イメージのビルド → レジストリへ push
554
+ |
555
+ v
556
+ 3. マニフェスト更新: 新しいイメージタグをマニフェストリポジトリへ反映(Git にコミット)
557
+ |
558
+ v
559
+ 4. CD(GitOps 自動同期): Flux / Argo CD がマニフェストの変更を検知し、クラスタへ同期
560
+ |
561
+ v
562
+ 5. 進行的デリバリー: カナリア投入 → 自動分析(メトリクス検証)
563
+ |
564
+ +-- 分析 OK --> 本番(PRIMARY)を更新して完了
565
+ |
566
+ +-- 分析 NG --> 自動ロールバック(旧バージョンを維持)
567
+ ```
568
+
569
+ それぞれの段階を、これまでの内容と対応づけて整理します。
570
+
571
+ 1. CI(イメージのビルドと push)
572
+
573
+ 第 10 章で扱った CI が担います。コードの変更をきっかけにテストを通し、Docker イメージをビルドしてレジストリへ push します。ここで「デプロイ可能な成果物」が生まれます。
574
+
575
+ 2. マニフェストの更新
576
+
577
+ CI の成果物である新しいイメージタグを、GitOps が監視するマニフェストリポジトリに反映します。`echo-bootstrap` のようなマニフェストリポジトリのイメージ指定を、新しいタグへ書き換えてコミットするイメージです。この「Git へのコミット」が、デプロイのトリガーになります。
578
+
579
+ 3. CD(GitOps 自動同期)
580
+
581
+ Flux の `source-controller` / `kustomize-controller`、あるいは Argo CD の `Application` が、マニフェストの変更を検知してクラスタへ自動同期します。pull 型なので、クラスタ外に強い権限を渡す必要がありません。Git が唯一の情報源であり続けるため、いつでも `git revert` で過去の状態へ戻せます。
582
+
583
+ 4. 進行的デリバリー(カナリア + 自動分析 + 自動ロールバック)
584
+
585
+ Argo Rollouts や PipeCD のパイプラインが、新バージョンをいきなり全面展開するのではなく、カナリアとして一部のトラフィックから始めます。PipeCD の `ANALYSIS` ステージのように、メトリクスを自動で検証し、品質基準を満たせば本番を更新し、満たさなければデプロイを中断して旧バージョンを維持します。これが自動ロールバックです。
586
+
587
+ このパイプラインの価値は明確です。人手による `kubectl apply` や、目視によるリリース後の監視といった、ミスが起きやすく属人的な作業がなくなります。問題のあるバージョンはユーザー全体に届く前に自動で食い止められ、万一のときは Git の履歴で安全に巻き戻せます。まさに「変更を楽に安全にできて役に立つソフトウェア」を、継続的に届け続けられる状態です。
588
+
589
+ ---
590
+
591
+ ## まとめ
592
+
593
+ この章では、コンテナにおける継続的デリバリー(CD)を扱いました。
594
+
595
+ - CI が「デプロイ可能な成果物(イメージ)を作る」工程であるのに対し、CD は「成果物を確実に届ける」工程です。両者は連続しつつも責務が異なります。
596
+ - GitOps は、Git を信頼できる唯一の情報源とし、宣言的マニフェストをクラスタへ自動同期する考え方です。同期方式には push 型と pull 型があり、GitOps ツールの多くはセキュリティ面で有利な pull 型を採用します。
597
+ - Flux は `source-controller` と `kustomize-controller` が連携し、Git の変更を検知してクラスタへ同期する pull 型ツールです。`echo-bootstrap` のような Kustomize マニフェストを配信対象にできます。
598
+ - Argo CD は `Application` リソースで同期対象を定義し、プレーン YAML / Kustomize / Helm のいずれの形式も扱えます。sync-waves と hook でリソースの適用順序を制御でき、Argo Rollouts と組み合わせれば blue-green デプロイも実現できます。
599
+ - PipeCD は `app.pipecd.yaml` でパイプラインを宣言し、カナリア・ブルーグリーンの各ステージや、メトリクスによる `ANALYSIS` ステージで品質を自動検証できます。
600
+ - これらを組み合わせると、CI(ビルド/push)→ CD(GitOps 自動同期)→ 進行的デリバリー(カナリア + 自動分析 + 自動ロールバック)という、ソフトウェアデリバリーの完全自動化が実現します。
601
+
602
+ なお、本章で示した `GitRepository` / `Kustomization` / `Application` の各 CRD のうち、サンプルリポジトリに実ファイルとして含まれていたのは `argocd-example-apps`、`pipecd-examples`、`echo-bootstrap` の配信対象マニフェストです。Flux 側および Argo CD の `Application` の設定例は、ツールの一般的な書き方として示した参考例です。実際に利用する際は、各ツールの公式ドキュメントで最新の API バージョンを確認してください。
603
+
604
+ ---
605
+
606
+ - 前の章: [第 10 章 最適なコンテナイメージ作成と運用](10-optimal-container-image.md)
607
+ - 次の章: [第 12 章 コンテナのさまざまな活用方法](12-container-use-cases.md)