hyperi-ci 2.2.2__tar.gz → 2.3.7__tar.gz

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 (293) hide show
  1. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.github/workflows/python-ci.yml +20 -0
  2. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.github/workflows/rust-ci.yml +7 -3
  3. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.gitignore +3 -0
  4. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/CHANGELOG.md +84 -0
  5. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/PKG-INFO +4 -2
  6. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/README.md +3 -0
  7. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/STATE.md +50 -0
  8. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/TODO.md +25 -0
  9. hyperi_ci-2.3.7/VERSION +1 -0
  10. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/pyproject.toml +27 -5
  11. hyperi_ci-2.3.7/src/hyperi_ci/argocd/__init__.py +20 -0
  12. hyperi_ci-2.3.7/src/hyperi_ci/argocd/gitops_push.py +241 -0
  13. hyperi_ci-2.3.7/src/hyperi_ci/argocd/stage.py +219 -0
  14. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/cli.py +306 -12
  15. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/stage.py +53 -1
  16. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/deployment/detect.py +73 -7
  17. hyperi_ci-2.3.7/src/hyperi_ci/deployment/overlay/__init__.py +46 -0
  18. hyperi_ci-2.3.7/src/hyperi_ci/deployment/overlay/anchors/__init__.py +12 -0
  19. hyperi_ci-2.3.7/src/hyperi_ci/deployment/overlay/anchors/argocd.py +160 -0
  20. hyperi_ci-2.3.7/src/hyperi_ci/deployment/overlay/anchors/dockerfile.py +177 -0
  21. hyperi_ci-2.3.7/src/hyperi_ci/deployment/overlay/anchors/helm.py +201 -0
  22. hyperi_ci-2.3.7/src/hyperi_ci/deployment/overlay/cli.py +311 -0
  23. hyperi_ci-2.3.7/src/hyperi_ci/deployment/overlay/errors.py +87 -0
  24. hyperi_ci-2.3.7/src/hyperi_ci/deployment/overlay/model.py +299 -0
  25. hyperi_ci-2.3.7/src/hyperi_ci/deployment/overlay/render.py +75 -0
  26. hyperi_ci-2.3.7/src/hyperi_ci/deployment/topology/__init__.py +43 -0
  27. hyperi_ci-2.3.7/src/hyperi_ci/deployment/topology/resolve.py +205 -0
  28. hyperi_ci-2.3.7/src/hyperi_ci/deployment/topology/stitch.py +288 -0
  29. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/dispatch.py +29 -0
  30. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/.gitbook.yaml +6 -0
  31. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/.gitignore +18 -0
  32. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/CODEOWNERS +11 -0
  33. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/LICENSE +91 -0
  34. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/README.md +99 -0
  35. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/argocd/README.md +77 -0
  36. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/concepts/architecture.md +73 -0
  37. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/concepts/overview.md +44 -0
  38. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/how-to/add-app.md +90 -0
  39. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/how-to/add-environment.md +80 -0
  40. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/how-to/add-topology.md +100 -0
  41. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/index.md +28 -0
  42. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/operations/disaster-recovery.md +88 -0
  43. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/operations/rollback.md +69 -0
  44. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/quickstart.md +67 -0
  45. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/reference/sync-waves.md +58 -0
  46. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/docs/reference/topology-schema.md +135 -0
  47. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/mkdocs.yml +48 -0
  48. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/pull_request_template.md +25 -0
  49. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/terraform/README.md +51 -0
  50. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/terraform/aws/modules/.gitkeep +0 -0
  51. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/terraform/rancher/clusters/.gitkeep +0 -0
  52. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/terraform/rancher/modules/.gitkeep +0 -0
  53. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/topologies/README.md +39 -0
  54. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/values/.gitkeep +0 -0
  55. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/workflows/docs.yaml +53 -0
  56. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/workflows/stitch-and-publish.yaml +60 -0
  57. hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/workflows/validate.yaml +72 -0
  58. hyperi_ci-2.3.7/src/hyperi_ci/helm/__init__.py +21 -0
  59. hyperi_ci-2.3.7/src/hyperi_ci/helm/stage.py +476 -0
  60. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/init.py +105 -0
  61. hyperi_ci-2.3.7/src/hyperi_ci/init_gitops.py +206 -0
  62. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/push.py +45 -0
  63. hyperi_ci-2.3.7/tests/__init__.py +0 -0
  64. hyperi_ci-2.3.7/tests/argocd/__init__.py +0 -0
  65. hyperi_ci-2.3.7/tests/argocd/test_gitops_push.py +168 -0
  66. hyperi_ci-2.3.7/tests/argocd/test_stage.py +147 -0
  67. hyperi_ci-2.3.7/tests/deployment/__init__.py +0 -0
  68. hyperi_ci-2.3.7/tests/deployment/overlay/__init__.py +0 -0
  69. hyperi_ci-2.3.7/tests/deployment/overlay/test_argocd_anchors.py +193 -0
  70. hyperi_ci-2.3.7/tests/deployment/overlay/test_cli.py +221 -0
  71. hyperi_ci-2.3.7/tests/deployment/overlay/test_dockerfile_anchors.py +195 -0
  72. hyperi_ci-2.3.7/tests/deployment/overlay/test_helm_anchors.py +317 -0
  73. hyperi_ci-2.3.7/tests/deployment/overlay/test_model.py +251 -0
  74. hyperi_ci-2.3.7/tests/deployment/topology/__init__.py +0 -0
  75. hyperi_ci-2.3.7/tests/deployment/topology/test_resolve.py +114 -0
  76. hyperi_ci-2.3.7/tests/deployment/topology/test_stitch.py +248 -0
  77. hyperi_ci-2.3.7/tests/helm/__init__.py +0 -0
  78. hyperi_ci-2.3.7/tests/helm/test_stage.py +221 -0
  79. hyperi_ci-2.3.7/tests/helm/test_stage_topology_mode.py +359 -0
  80. hyperi_ci-2.3.7/tests/integration/__init__.py +0 -0
  81. hyperi_ci-2.3.7/tests/unit/__init__.py +0 -0
  82. hyperi_ci-2.3.7/tests/unit/deployment/__init__.py +0 -0
  83. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/deployment/test_detect_tier.py +99 -0
  84. hyperi_ci-2.3.7/tests/unit/test_cli_init_gitops.py +38 -0
  85. hyperi_ci-2.3.7/tests/unit/test_cli_stitch.py +81 -0
  86. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_commit_validation.py +8 -2
  87. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_init.py +52 -0
  88. hyperi_ci-2.3.7/tests/unit/test_init_gitops.py +62 -0
  89. hyperi_ci-2.3.7/tests/unit/test_init_topology.py +64 -0
  90. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_push.py +85 -0
  91. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/uv.lock +267 -93
  92. hyperi_ci-2.2.2/VERSION +0 -1
  93. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/.ai-version +0 -0
  94. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/commands/doco.md +0 -0
  95. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/commands/load.md +0 -0
  96. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/commands/review.md +0 -0
  97. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/commands/save.md +0 -0
  98. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/commands/setup-claude.md +0 -0
  99. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/commands/simplify.md +0 -0
  100. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/commands/standards.md +0 -0
  101. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/UNIVERSAL.md +0 -0
  102. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/ai-conduct.md +0 -0
  103. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/ansible.md +0 -0
  104. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/bash.md +0 -0
  105. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/chars-policy.md +0 -0
  106. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/ci.md +0 -0
  107. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/clickhouse-sql.md +0 -0
  108. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/code-header.md +0 -0
  109. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/code-style.md +0 -0
  110. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/config-and-logging.md +0 -0
  111. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/cpp.md +0 -0
  112. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/design-principles.md +0 -0
  113. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/dfe-metrics.md +0 -0
  114. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/docker.md +0 -0
  115. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/error-handling.md +0 -0
  116. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/git.md +0 -0
  117. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/golang.md +0 -0
  118. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/issue-management.md +0 -0
  119. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/k8s.md +0 -0
  120. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/licensing.md +0 -0
  121. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/mocks-policy.md +0 -0
  122. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/pki.md +0 -0
  123. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/python.md +0 -0
  124. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/repo-naming.md +0 -0
  125. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/rust.md +0 -0
  126. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/security.md +0 -0
  127. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/sql-clickhouse.md +0 -0
  128. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/terraform.md +0 -0
  129. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/testing.md +0 -0
  130. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/typescript.md +0 -0
  131. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/rules/universal.md +0 -0
  132. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/settings.json +0 -0
  133. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/ai-common/SKILL.md +0 -0
  134. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/ai-guidelines/SKILL.md +0 -0
  135. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/bleeding-edge/SKILL.md +0 -0
  136. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/ci-check/SKILL.md +0 -0
  137. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/ci-logs/SKILL.md +0 -0
  138. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/ci-watch/SKILL.md +0 -0
  139. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/deps/SKILL.md +0 -0
  140. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/docs-audit/SKILL.md +0 -0
  141. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/documentation/SKILL.md +0 -0
  142. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/python/SKILL.md +0 -0
  143. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/release/SKILL.md +0 -0
  144. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/standards/SKILL.md +0 -0
  145. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/test-review/SKILL.md +0 -0
  146. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.claude/skills/verification/SKILL.md +0 -0
  147. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.gitattributes +0 -0
  148. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.github/actions/predict-version/action.yml +0 -0
  149. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.github/workflows/_release-tail.yml +0 -0
  150. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.github/workflows/ci.yml +0 -0
  151. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.github/workflows/go-ci.yml +0 -0
  152. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.github/workflows/ts-ci.yml +0 -0
  153. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.gitmodules +0 -0
  154. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.hyperi-ci.yaml +0 -0
  155. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.mcp.json +0 -0
  156. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/.releaserc.yaml +0 -0
  157. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/AI-TRAINING-POLICY.md +0 -0
  158. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/CLAUDE.md +0 -0
  159. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/LICENSE +0 -0
  160. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/config/commit-types.yaml +0 -0
  161. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/config/org.yaml +0 -0
  162. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/config/runners.yaml +0 -0
  163. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/config/secrets-access.yaml +0 -0
  164. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/config/versions.yaml +0 -0
  165. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/ARC-RUNNERS.md +0 -0
  166. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/ARCHITECTURE.md +0 -0
  167. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/CI-LESSONS.md +0 -0
  168. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/DESIGN.md +0 -0
  169. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/JFROG-MIGRATION.md +0 -0
  170. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/MIGRATION-GUIDE.md +0 -0
  171. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/PGO-WORKLOAD-GUIDE.md +0 -0
  172. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/deployment-contract.md +0 -0
  173. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/migration/deployment-contract-tier3.md +0 -0
  174. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/rust.md +0 -0
  175. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/docs/typescript.md +0 -0
  176. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/renovate.json +0 -0
  177. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/robots.txt +0 -0
  178. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/scripts/pre-commit-versions.sh +0 -0
  179. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/scripts/setup-rust-dev.py +0 -0
  180. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/scripts/sync-secrets-access.py +0 -0
  181. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/scripts/update-versions.py +0 -0
  182. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/__init__.py +0 -0
  183. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/common.py +0 -0
  184. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/config/defaults.yaml +0 -0
  185. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/config/native-deps/golang.yaml +0 -0
  186. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/config/native-deps/python.yaml +0 -0
  187. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/config/native-deps/rust.yaml +0 -0
  188. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/config/native-deps/typescript.yaml +0 -0
  189. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/config/org.yaml +0 -0
  190. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/config/toolchains/gcc.yaml +0 -0
  191. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/config/toolchains/llvm.yaml +0 -0
  192. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/config.py +0 -0
  193. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/__init__.py +0 -0
  194. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/binary_stage.py +0 -0
  195. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/build.py +0 -0
  196. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/compose.py +0 -0
  197. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/detect.py +0 -0
  198. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/labels.py +0 -0
  199. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/manifest.py +0 -0
  200. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/registry.py +0 -0
  201. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/container/templates.py +0 -0
  202. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/deployment/__init__.py +0 -0
  203. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/deployment/cli.py +0 -0
  204. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/deployment/contract.py +0 -0
  205. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/deployment/registry.py +0 -0
  206. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/deployment/scaffold.py +0 -0
  207. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/deployment/stage.py +0 -0
  208. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/detect.py +0 -0
  209. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/gh.py +0 -0
  210. /hyperi_ci-2.2.2/tests/__init__.py → /hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/argocd/applicationsets/.gitkeep +0 -0
  211. /hyperi_ci-2.2.2/tests/integration/__init__.py → /hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/argocd/appprojects/.gitkeep +0 -0
  212. /hyperi_ci-2.2.2/tests/unit/__init__.py → /hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/argocd/bootstrap/.gitkeep +0 -0
  213. /hyperi_ci-2.2.2/tests/unit/deployment/__init__.py → /hyperi_ci-2.3.7/src/hyperi_ci/gitops_templates/terraform/aws/environments/.gitkeep +0 -0
  214. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/install_deps.py +0 -0
  215. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/__init__.py +0 -0
  216. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/_build_common.py +0 -0
  217. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/golang/__init__.py +0 -0
  218. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/golang/build.py +0 -0
  219. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/golang/publish.py +0 -0
  220. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/golang/quality.py +0 -0
  221. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/golang/test.py +0 -0
  222. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/python/__init__.py +0 -0
  223. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/python/build.py +0 -0
  224. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/python/publish.py +0 -0
  225. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/python/quality.py +0 -0
  226. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/python/test.py +0 -0
  227. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/quality_common.py +0 -0
  228. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/rust/__init__.py +0 -0
  229. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/rust/build.py +0 -0
  230. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/rust/optimize.py +0 -0
  231. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/rust/pgo.py +0 -0
  232. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/rust/publish.py +0 -0
  233. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/rust/quality.py +0 -0
  234. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/rust/test.py +0 -0
  235. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/typescript/__init__.py +0 -0
  236. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/typescript/_common.py +0 -0
  237. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/typescript/build.py +0 -0
  238. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/typescript/install_deps.py +0 -0
  239. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/typescript/publish.py +0 -0
  240. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/typescript/quality.py +0 -0
  241. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/languages/typescript/test.py +0 -0
  242. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/logs.py +0 -0
  243. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/migrate.py +0 -0
  244. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/native_deps.py +0 -0
  245. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/publish/__init__.py +0 -0
  246. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/publish/binaries.py +0 -0
  247. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/publish/dispatch.py +0 -0
  248. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/publish_binaries.py +0 -0
  249. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/quality/__init__.py +0 -0
  250. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/quality/commit_validation.py +0 -0
  251. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/quality/gitleaks.py +0 -0
  252. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/release.py +0 -0
  253. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/trigger.py +0 -0
  254. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/upgrade.py +0 -0
  255. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/src/hyperi_ci/watch.py +0 -0
  256. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/templates/pgo-workload/README.md +0 -0
  257. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/templates/pgo-workload/grpc-server.sh +0 -0
  258. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/templates/pgo-workload/http-server.sh +0 -0
  259. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/templates/pgo-workload/kafka-consumer.sh +0 -0
  260. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/templates/pgo-workload/kafka-producer.sh +0 -0
  261. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/templates/pgo-workload/multi-protocol.sh +0 -0
  262. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/integration/test_rust_build_optimize.py +0 -0
  263. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/deployment/test_contract.py +0 -0
  264. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/deployment/test_emit_artefacts_cli.py +0 -0
  265. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/deployment/test_registry_cascade.py +0 -0
  266. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/deployment/test_scaffold.py +0 -0
  267. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/deployment/test_stage.py +0 -0
  268. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_cli.py +0 -0
  269. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_common.py +0 -0
  270. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_config.py +0 -0
  271. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_container_binary_stage.py +0 -0
  272. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_container_build.py +0 -0
  273. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_container_compose.py +0 -0
  274. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_container_detect.py +0 -0
  275. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_container_labels.py +0 -0
  276. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_container_manifest.py +0 -0
  277. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_container_registry.py +0 -0
  278. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_container_stage.py +0 -0
  279. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_container_templates.py +0 -0
  280. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_detect.py +0 -0
  281. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_dispatch_alias.py +0 -0
  282. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_dispatch_status.py +0 -0
  283. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_gh.py +0 -0
  284. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_migrate.py +0 -0
  285. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_native_deps.py +0 -0
  286. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_publish.py +0 -0
  287. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_rust_optimize.py +0 -0
  288. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_rust_pgo.py +0 -0
  289. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_rust_quality.py +0 -0
  290. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_typescript_quality.py +0 -0
  291. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_upgrade.py +0 -0
  292. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_watch.py +0 -0
  293. {hyperi_ci-2.2.2 → hyperi_ci-2.3.7}/tests/unit/test_workflow_consistency.py +0 -0
@@ -162,6 +162,26 @@ jobs:
162
162
  strategy:
163
163
  matrix:
164
164
  os: ${{ fromJson(startsWith(github.head_ref || github.ref_name, 'renovate/') && format('["{0}"]', vars.GH_RUNNER_RENOVATE || 'ubuntu-latest') || (inputs.runner-mode || vars.GH_RUNNER_MODE) == 'free' && '["ubuntu-latest"]' || inputs.test-matrix || format('["{0}"]', inputs.runner-test || vars.GH_RUNNER_PYTHON || vars.GH_RUNNER_DEFAULT || 'ubuntu-latest')) }}
165
+ # Service containers required by integration tests.
166
+ # Always-on: harmless overhead for consumers that don't use them
167
+ # (job runs `psql` etc. against localhost ports). pylib's
168
+ # tests/conftest.py postgres fixture finds these via the
169
+ # `postgresql://postgres:postgres@localhost:5432/hyperi_pylib_test`
170
+ # DSN; matches pylib's docker-compose.postgres.yml.
171
+ services:
172
+ postgres:
173
+ image: postgres:18-alpine
174
+ env:
175
+ POSTGRES_USER: postgres
176
+ POSTGRES_PASSWORD: postgres
177
+ POSTGRES_DB: hyperi_pylib_test
178
+ ports:
179
+ - 5432:5432
180
+ options: >-
181
+ --health-cmd "pg_isready -U postgres -d hyperi_pylib_test"
182
+ --health-interval 5s
183
+ --health-timeout 5s
184
+ --health-retries 10
165
185
  steps:
166
186
  - name: Docker Hub login
167
187
  if: ${{ vars.DOCKERHUB_USERNAME != '' }}
@@ -91,9 +91,13 @@ concurrency:
91
91
  env:
92
92
  HYPERCI_PUBLISH_TARGET: ${{ inputs.publish-target }}
93
93
  HYPERCI_INSTALL: uvx --no-cache --refresh hyperi-ci
94
- # When dispatched with a tag, this is a release-channel build —
95
- # enables Tier 2 (PGO + BOLT) build optimisation.
96
- HYPERCI_CHANNEL: ${{ inputs.tag && 'release' || '' }}
94
+ # When dispatched with a tag (legacy workflow_dispatch path) OR when
95
+ # the caller declared `publish-target: both` (new `hyperi-ci push
96
+ # --release` path), this is a release-channel build enables Tier 2
97
+ # (PGO + BOLT) build optimisation. Pre-2026-05-20 this only matched
98
+ # the workflow_dispatch path; consumers on the new push-trigger flow
99
+ # silently fell through to spike → Tier 1. See plan note for context.
100
+ HYPERCI_CHANNEL: ${{ (inputs.tag != '' || inputs.publish-target == 'both') && 'release' || '' }}
97
101
 
98
102
  jobs:
99
103
  # ---------------------------------------------------------------------------
@@ -35,3 +35,6 @@ Thumbs.db
35
35
 
36
36
  # AI agent working files (not committed)
37
37
  docs/superpowers/
38
+
39
+ # Git worktrees
40
+ .worktrees/
@@ -1,3 +1,87 @@
1
+ ## [2.3.7](https://github.com/hyperi-io/hyperi-ci/compare/v2.3.6...v2.3.7) (2026-05-20)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **push:** stage auto-modified lockfiles into release-marker commit ([e5e1dd7](https://github.com/hyperi-io/hyperi-ci/commit/e5e1dd73d56350f4e25ea75e4f27ea718c7930c2))
7
+
8
+ ## [2.3.6](https://github.com/hyperi-io/hyperi-ci/compare/v2.3.5...v2.3.6) (2026-05-20)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **init:** suppress false-positive semgrep importlib.resources warning ([382f7b9](https://github.com/hyperi-io/hyperi-ci/commit/382f7b913eb3428f5ad307a202b07d012d7ebf71))
14
+
15
+ ## [2.3.5](https://github.com/hyperi-io/hyperi-ci/compare/v2.3.4...v2.3.5) (2026-05-20)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **deployment:** D-rule cleanup in topology + cli docstrings ([88fc7c9](https://github.com/hyperi-io/hyperi-ci/commit/88fc7c9bf2fd779d78b29d160c076a0dba23ed66))
21
+
22
+ ## [2.3.4](https://github.com/hyperi-io/hyperi-ci/compare/v2.3.3...v2.3.4) (2026-05-20)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * **init:** add module docstring + finalise Raises section formatting ([d7f7bb4](https://github.com/hyperi-io/hyperi-ci/commit/d7f7bb4f54bc0a06b7932508922e0a58be437d71))
28
+
29
+ ## [2.3.3](https://github.com/hyperi-io/hyperi-ci/compare/v2.3.2...v2.3.3) (2026-05-20)
30
+
31
+
32
+ ### Bug Fixes
33
+
34
+ * **cli:** add hyperi-ci init-topology subcommand ([599fb0c](https://github.com/hyperi-io/hyperi-ci/commit/599fb0cc5075a7c066e7c6c0ff8fbfbd4bd1bdef))
35
+ * **cli:** add hyperi-ci stitch subcommand ([38decd0](https://github.com/hyperi-io/hyperi-ci/commit/38decd0e155aca1846d59092d9127c3140a985c2))
36
+ * **deployment:** add ChartVersionResolver with semver range matching ([6a90869](https://github.com/hyperi-io/hyperi-ci/commit/6a9086929292375d7521dc86a0ada6f4888e2121))
37
+ * **deployment:** generate umbrella Chart.yaml with resolved deps ([e06a155](https://github.com/hyperi-io/hyperi-ci/commit/e06a155a1383cc7860c8dc586e5c287b5523de8a))
38
+ * **deployment:** implement full stitch (values, glue, helm dep update + lint) ([944ef28](https://github.com/hyperi-io/hyperi-ci/commit/944ef280b84cca9f4042ffc7287b9c238719031c))
39
+ * **deployment:** wire ORAS for OCI chart tag listing ([11069bf](https://github.com/hyperi-io/hyperi-ci/commit/11069bff3f8c6ef92eac1af702dd2248a6f678bf))
40
+ * **helm:** add topology-mode to helm stage (stitcher integration) ([ca532d3](https://github.com/hyperi-io/hyperi-ci/commit/ca532d32f65ffdaa55ebb4bc84d423e63657c75d))
41
+ * **init:** add gitops repo scaffolding templates ([1a3a519](https://github.com/hyperi-io/hyperi-ci/commit/1a3a519b72be300d9850dfddac067410f4f6a5ef))
42
+ * **init:** add init_gitops module + CLI subcommand ([67d08a2](https://github.com/hyperi-io/hyperi-ci/commit/67d08a234e61820cc65ba1380214bb38cac6b3d2))
43
+ * **init:** seed gitops docs with reference content ([79bab6b](https://github.com/hyperi-io/hyperi-ci/commit/79bab6b140735fade60a78cef014cdda20d0da31))
44
+
45
+ ## [2.3.2](https://github.com/hyperi-io/hyperi-ci/compare/v2.3.1...v2.3.2) (2026-05-20)
46
+
47
+
48
+ ### Bug Fixes
49
+
50
+ * **ci:** gate release channel on publish-target=both for new push-trigger path ([c25787b](https://github.com/hyperi-io/hyperi-ci/commit/c25787b38b726c2fe1fe9db843c9b2f5ce5b0dce))
51
+ * **deps:** bump hyperi-pylib floor to >=2.28.2 (topology subsystem) ([3026bcc](https://github.com/hyperi-io/hyperi-ci/commit/3026bcc3f5f1722cc958e9ce939d0d4fc9919ece))
52
+
53
+ ## [2.3.1](https://github.com/hyperi-io/hyperi-ci/compare/v2.3.0...v2.3.1) (2026-05-20)
54
+
55
+
56
+ ### Bug Fixes
57
+
58
+ * **ci:** add postgres services container to python-ci test job ([1d979fc](https://github.com/hyperi-io/hyperi-ci/commit/1d979fc0e2b633093a2b886ed40a8c4c1c307d70))
59
+ * **init:** generate CONTRIBUTING.md template explaining the two paths ([35bd157](https://github.com/hyperi-io/hyperi-ci/commit/35bd157f4ec780088d864a0422da161534a5be4b))
60
+
61
+ # [2.3.0](https://github.com/hyperi-io/hyperi-ci/compare/v2.2.3...v2.3.0) (2026-05-15)
62
+
63
+
64
+ ### Bug Fixes
65
+
66
+ * docstring polish (D102/D105/D205/D401) on overlay framework ([249b525](https://github.com/hyperi-io/hyperi-ci/commit/249b525e724928f6fe4b70f88f6ad13c5fcff60b))
67
+ * ruff cleanups (D413, D401, N802, E741) on overlay framework files ([b276ef5](https://github.com/hyperi-io/hyperi-ci/commit/b276ef5afd16cc31b3c75e919725dcc98d262322))
68
+ * ruff format on overlay framework files ([78a84f5](https://github.com/hyperi-io/hyperi-ci/commit/78a84f5a3d8c985198e0136e8f2b7a51004674ce))
69
+ * **test:** make feat-gate tests env-independent (clear HYPERCI_ALLOW_FEAT) ([7262309](https://github.com/hyperi-io/hyperi-ci/commit/726230953c0002fa3ef5733386748b11008c211a))
70
+
71
+
72
+ ### Features
73
+
74
+ * deployment-artefact overlay framework + helm/argocd stages ([ff63b37](https://github.com/hyperi-io/hyperi-ci/commit/ff63b375e587346ae0340af808b53dcbd47dca57))
75
+
76
+ ## [2.2.3](https://github.com/hyperi-io/hyperi-ci/compare/v2.2.2...v2.2.3) (2026-05-13)
77
+
78
+
79
+ ### Bug Fixes
80
+
81
+ * **deployment:** exclude self-name from tier detection ([f61921b](https://github.com/hyperi-io/hyperi-ci/commit/f61921b9b0dcfe36c3c1809b0bacbedee4c78386))
82
+ * **deps:** declare typer explicitly in runtime dependencies ([895a4a6](https://github.com/hyperi-io/hyperi-ci/commit/895a4a637e2f7f55bd74e2276ddb51f9184fc7cd))
83
+ * **deps:** remove editable pylib source override to unblock Dependabot graph ([a4f1b28](https://github.com/hyperi-io/hyperi-ci/commit/a4f1b28551758e0e1287bf931f60e52194076021))
84
+
1
85
  ## [2.2.2](https://github.com/hyperi-io/hyperi-ci/compare/v2.2.1...v2.2.2) (2026-05-13)
2
86
 
3
87
 
@@ -1,12 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperi-ci
3
- Version: 2.2.2
3
+ Version: 2.3.7
4
4
  Summary: HyperI CI/CD CLI tool — multi-language build, test, and publish automation
5
5
  License: Proprietary
6
6
  License-File: LICENSE
7
7
  Requires-Python: >=3.12
8
- Requires-Dist: hyperi-pylib[metrics]>=2.28.0
8
+ Requires-Dist: hyperi-pylib[metrics]>=2.28.2
9
+ Requires-Dist: oras>=0.2.42
9
10
  Requires-Dist: packaging>=26.0
10
11
  Requires-Dist: pydantic>=2.13
11
12
  Requires-Dist: pyyaml>=6.0
12
13
  Requires-Dist: tomli-w>=1.2.0
14
+ Requires-Dist: typer>=0.25
@@ -251,6 +251,9 @@ No code changes, no workflow changes.
251
251
  | `hyperi-ci run quality\|test\|build\|generate\|container\|publish` | Run a single stage locally |
252
252
  | `hyperi-ci init-contract --app-name <name>` | Scaffold `ci/deployment-contract.json` (Tier 3) |
253
253
  | `hyperi-ci emit-artefacts <output-dir>` | Generate Dockerfile + chart + ArgoCD app from contract |
254
+ | `hyperi-ci stitch <dir>` | Compose a deployment topology into an umbrella Helm chart |
255
+ | `hyperi-ci init-gitops <dir>` | Scaffold a new gitops monorepo |
256
+ | `hyperi-ci init-topology <name>` | Scaffold a new topology in existing gitops repo |
254
257
  | `hyperi-ci check-commit --list` | Show all accepted commit types |
255
258
  | `hyperi-ci detect` | Show detected language |
256
259
  | `hyperi-ci config` | Show merged config |
@@ -2,6 +2,25 @@
2
2
 
3
3
  Static context for AI assistants. For tasks and progress see `TODO.md`.
4
4
 
5
+ ## HARD RULES (READ FIRST)
6
+
7
+ ### No "later branch fix" commits
8
+
9
+ **Never add a commit on a feature branch that fixes / cleans up / corrects an
10
+ earlier commit on the same branch (or in any parent branch you forked from).**
11
+
12
+ If commits 1, 2, 3 land on a feature branch and commit 1 turns out to be
13
+ sloppy, you DO NOT add commit 4 that says "fix the noise from commit 1". You
14
+ go back, rewrite commits 1-3 atomically, and force-push the cleaned-up
15
+ branch. Each commit on a branch MUST stand alone as a clean, atomic change.
16
+
17
+ This stays true at least until the branch is opened as a formal upstream PR —
18
+ and even then, prefer rebase-clean over apologetic follow-up commits.
19
+
20
+ Pinned at top per Derek 2026-05-20.
21
+
22
+ ---
23
+
5
24
  ## Flaky Test = Fix the Test
6
25
 
7
26
  **CI runs are 20-30 minutes on Rust projects. Re-running a flaky test
@@ -274,11 +293,42 @@ uv run hyperi-ci push --no-ci # Push, skip CI
274
293
  uv run hyperi-ci publish --list # List unpublished version tags
275
294
  uv run hyperi-ci publish v1.3.0 # Retroactive: dispatch publish on existing tag
276
295
  uv run hyperi-ci check-commit --list # List accepted commit types
296
+ uv run hyperi-ci stitch <dir> # Compose a deployment topology into an umbrella Helm chart
297
+ uv run hyperi-ci init-gitops <dir> # Scaffold a new gitops monorepo
298
+ uv run hyperi-ci init-topology <name> # Scaffold a new topology in existing gitops repo
277
299
  ```
278
300
 
279
301
  `--release` and `release` are kept as deprecated aliases of `--publish` /
280
302
  `publish` for back-compat; will be removed in v4.0.
281
303
 
304
+ ## Gitops & Helm Topology Stitching
305
+
306
+ The `stitch` subcommand and associated `init-gitops` / `init-topology`
307
+ commands support a **gitops workflow** for managing Helm deployments
308
+ across multiple applications.
309
+
310
+ - **`hyperi-ci stitch <topology-dir>`** — composes a deployment topology
311
+ into an umbrella Helm chart. Reads `<dir>/topology.yaml`, resolves
312
+ `apps[]` semver ranges against OCI registries, generates `Chart.yaml`
313
+ + `values.yaml` + glue templates, runs `helm dep update` + `helm lint`.
314
+ Output is ready for `helm package` or `helm repo add`.
315
+
316
+ - **`hyperi-ci init-gitops <dir> [--org NAME]`** — scaffolds a new gitops
317
+ monorepo skeleton with `topologies/`, `argocd/`, `values/`, `terraform/`,
318
+ `docs/` (MkDocs Material), `.github/workflows/`, README, CODEOWNERS,
319
+ and LICENSE.
320
+
321
+ - **`hyperi-ci init-topology <name> [--app NAME ...]`** — scaffolds a new
322
+ topology directory inside an existing gitops repo, creating `topology.yaml`,
323
+ `values.yaml`, `glue/`, and README.
324
+
325
+ ### Helm Stage Topology Mode
326
+
327
+ The Helm stage gains a `topology_mode` opt-in (via `publish.helm.topology_mode: true`
328
+ in `.hyperi-ci.yaml`) that switches from per-app chart emission to topology
329
+ stitching for gitops-repo CI. When enabled, the stage calls `hyperi-ci stitch`
330
+ instead of running per-app chart generators.
331
+
282
332
  `--bump-patch` / `--bump-minor` are for the case where you want to ship
283
333
  a release whose commits aren't release-worthy under conventional-commits
284
334
  rules (e.g. a docs-only PR you want to release, or a force-rebuild).
@@ -221,6 +221,31 @@ RUN hyperi-ci prime-image --distro noble --all
221
221
 
222
222
  ### High Priority
223
223
 
224
+ - [ ] **GitOps repo bootstrap (`hyperi-io/gitops`)** — full spec at
225
+ [`docs/superpowers/specs/2026-05-15-gitops-repo-bootstrap-spec.md`](docs/superpowers/specs/2026-05-15-gitops-repo-bootstrap-spec.md).
226
+ Public monorepo, single ApplicationSet with git-generator scanning
227
+ `applications/*/*.yaml`, directory-per-env (no branch-per-env),
228
+ branch protection on `applications/*/prod.yaml`. Manual steps
229
+ (org admin creates repo + cluster admin applies bootstrap
230
+ ApplicationSet) plus an optional `hyperi-ci init-gitops`
231
+ subcommand to scaffold the initial layout. Lands in parallel
232
+ with overlay framework Phase 3 (ArgoCD overlays) — gitops repo
233
+ must exist before hyperi-ci can push Application YAMLs into it.
234
+
235
+ - [ ] **Deployment-artefact overlay framework** — full spec at
236
+ [`docs/superpowers/specs/2026-05-15-deployment-overlay-framework-spec.md`](docs/superpowers/specs/2026-05-15-deployment-overlay-framework-spec.md).
237
+ Three-mode design (contract / contract+amendments / BYO) for
238
+ Dockerfile + Helm + ArgoCD. Phased: **Phase 1 Dockerfile**
239
+ unblocks `dfe-transform-vector` v1.0.13 release (currently uses
240
+ a per-consumer `emit_dockerfile()` stop-gap restored from the
241
+ eroded commit 2345818 pattern). Phase 2 Helm + Phase 3 ArgoCD
242
+ are designed but implement-on-pull. Distribution targets
243
+ decided 2026-05-15: containers → GHCR (existing), Helm →
244
+ GHCR OCI (`oci://ghcr.io/hyperi-io/helm-charts`), ArgoCD →
245
+ central public `hyperi-io/gitops` repo with ApplicationSet
246
+ git-generator on `applications/*/*.yaml`. Spec includes
247
+ bootstrap notes for the new gitops repo.
248
+
224
249
  - [ ] Validate TypeScript pipeline end-to-end (after Rust)
225
250
  - Standalone fixture: github.com/hyperi-io/ci-test-ts-app (cloned at /projects/ci-test-ts-app)
226
251
  - Need a real consumer TypeScript project to cut over
@@ -0,0 +1 @@
1
+ 2.3.7
@@ -18,11 +18,17 @@ dependencies = [
18
18
  # The [metrics] extra is required because pylib's __init__.py
19
19
  # eagerly imports hyperi_pylib.metrics.prometheus → psutil.
20
20
  # Architectural fix (lazy metrics import) is tracked in pylib.
21
- "hyperi-pylib[metrics]>=2.28.0",
21
+ "hyperi-pylib[metrics]>=2.28.2",
22
+ "oras>=0.2.42",
22
23
  "packaging>=26.0",
23
24
  "pydantic>=2.13",
24
25
  "pyyaml>=6.0",
25
26
  "tomli-w>=1.2.0",
27
+ # typer is used directly by src/hyperi_ci/cli.py — declare
28
+ # explicitly rather than relying on the transitive pull from
29
+ # hyperi-pylib's CLI infra. If pylib ever drops typer, this
30
+ # keeps us pinned to a known surface.
31
+ "typer>=0.25",
26
32
  ]
27
33
 
28
34
  [project.scripts]
@@ -39,12 +45,16 @@ pattern = "(?P<version>.+)"
39
45
  [tool.hatch.build.targets.wheel]
40
46
  packages = ["src/hyperi_ci"]
41
47
 
48
+ [tool.hatch.build.targets.wheel.force-include]
49
+ "src/hyperi_ci/gitops_templates" = "hyperi_ci/gitops_templates"
50
+
42
51
  [tool.ruff]
43
52
  line-length = 88
44
53
  target-version = "py312"
45
54
  extend-exclude = [
46
- "test-projects", # vendored fixture trees (node_modules, .venv etc.)
47
- "hyperi-ai", # submodule, not our code
55
+ "test-projects", # vendored fixture trees (node_modules, .venv etc.)
56
+ "hyperi-ai", # submodule, not our code
57
+ "src/hyperi_ci/gitops_templates", # template data files, not Python source
48
58
  ]
49
59
 
50
60
  [tool.ruff.lint]
@@ -83,8 +93,20 @@ source = ["hyperi_ci"]
83
93
  # Keep this low so `pytest --cov` reports without failing the run.
84
94
  fail_under = 30
85
95
 
86
- [tool.uv.sources]
87
- hyperi-pylib = { path = "/projects/hyperi-pylib", editable = true }
96
+ # NOTE: no [tool.uv.sources] block here on purpose.
97
+ #
98
+ # Tempting to point `hyperi-pylib` at a local editable checkout
99
+ # (/projects/hyperi-pylib) so dev changes flow through `uv sync`,
100
+ # but that breaks two things:
101
+ # - Dependabot's update_graph job can't resolve the path inside its
102
+ # container — fails on every push to main, leaving the dep-graph
103
+ # stale and GitHub's vulnerability banner inaccurate.
104
+ # - Reproducibility for anyone whose checkout isn't at that exact
105
+ # path.
106
+ #
107
+ # For local pylib co-development, run from this repo:
108
+ # uv pip install -e /path/to/hyperi-pylib
109
+ # Manual install is per-developer scratch state; not in pyproject.
88
110
 
89
111
  [dependency-groups]
90
112
  dev = [
@@ -0,0 +1,20 @@
1
+ # Project: HyperI CI
2
+ # File: src/hyperi_ci/argocd/__init__.py
3
+ # Purpose: ArgoCD Application generation + push into central GitOps repo
4
+ #
5
+ # License: Proprietary - HYPERI PTY LIMITED
6
+ # Copyright: (c) 2026 HYPERI PTY LIMITED
7
+ """ArgoCD stage: generate Application YAML + push into hyperi-io/gitops.
8
+
9
+ Stage flow (per overlay-framework spec section 10.5):
10
+
11
+ 1. Invoke consumer's ``emit-argocd`` subcommand
12
+ 2. Apply ``publish.argocd.overlays`` to the YAML
13
+ 3. Clone the GitOps repo into a temp dir
14
+ 4. Write the Application YAML to ``applications/<app>/<env>.yaml``
15
+ 5. git commit + push (or open a PR per env policy)
16
+
17
+ The GitOps repo (hyperi-io/gitops) is the public single-source-of-truth
18
+ for ArgoCD cluster state. Its bootstrap spec lives at
19
+ ``docs/superpowers/specs/2026-05-15-gitops-repo-bootstrap-spec.md``.
20
+ """
@@ -0,0 +1,241 @@
1
+ # Project: HyperI CI
2
+ # File: src/hyperi_ci/argocd/gitops_push.py
3
+ # Purpose: Clone GitOps repo, write Application YAML, commit + push (or PR)
4
+ #
5
+ # License: Proprietary - HYPERI PTY LIMITED
6
+ # Copyright: (c) 2026 HYPERI PTY LIMITED
7
+ """Push an ArgoCD Application YAML into the central GitOps repo.
8
+
9
+ Modes per env config:
10
+
11
+ * ``direct`` (default): clone main, write file, commit, push to main.
12
+ Used for dev / staging environments.
13
+ * ``pr``: clone main, write file on a branch, push branch, open PR.
14
+ Used for prod environments where a human approver is required.
15
+
16
+ Concurrency: relies on the GitHub Actions concurrency group at the
17
+ workflow level to serialise gitops pushes per-app per-env. This module
18
+ itself is single-shot (one push per invocation).
19
+
20
+ Auth: requires ``GITOPS_TOKEN`` (preferred) or ``GITHUB_TOKEN``
21
+ with ``contents: write`` to the gitops repo.
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import json
27
+ import os
28
+ import subprocess
29
+ import tempfile
30
+ import time
31
+ from dataclasses import dataclass
32
+ from pathlib import Path
33
+
34
+ from hyperi_ci.common import error, info, success
35
+
36
+
37
+ @dataclass(frozen=True, slots=True)
38
+ class GitopsPushConfig:
39
+ """Per-call configuration for a gitops push."""
40
+
41
+ repo: str # "hyperi-io/gitops"
42
+ path: str # "applications/dfe-loader/dev.yaml"
43
+ content: str # the Application YAML
44
+ commit_message: str
45
+ push_mode: str # "direct" | "pr"
46
+ branch_main: str = "main"
47
+
48
+
49
+ def push(cfg: GitopsPushConfig) -> int:
50
+ """Execute the push. Returns exit code."""
51
+ token = (
52
+ os.environ.get("GITOPS_TOKEN")
53
+ or os.environ.get("GITHUB_TOKEN")
54
+ or os.environ.get("GITHUB_WRITE_TOKEN")
55
+ )
56
+ if not token:
57
+ error(
58
+ f"No GITOPS_TOKEN / GITHUB_TOKEN in environment — can't push to {cfg.repo}"
59
+ )
60
+ return 1
61
+
62
+ info(f" argocd: pushing {cfg.path} to {cfg.repo} (mode={cfg.push_mode})")
63
+
64
+ with tempfile.TemporaryDirectory(prefix="hyperi-gitops-") as tmpdir:
65
+ clone_dir = Path(tmpdir) / "gitops"
66
+ rc = _git_clone(cfg.repo, clone_dir, token=token)
67
+ if rc != 0:
68
+ return rc
69
+
70
+ target = clone_dir / cfg.path
71
+ target.parent.mkdir(parents=True, exist_ok=True)
72
+ existing = target.read_text(encoding="utf-8") if target.exists() else None
73
+ if existing == cfg.content:
74
+ info(f" argocd: {cfg.path} already up-to-date — no push needed")
75
+ return 0
76
+ target.write_text(cfg.content, encoding="utf-8", newline="\n")
77
+
78
+ if cfg.push_mode == "pr":
79
+ return _push_pr(
80
+ clone_dir=clone_dir,
81
+ target=target,
82
+ cfg=cfg,
83
+ token=token,
84
+ )
85
+ return _push_direct(clone_dir=clone_dir, cfg=cfg, token=token)
86
+
87
+
88
+ # ---- internals ----------------------------------------------------------
89
+
90
+
91
+ def _git_clone(repo: str, dest: Path, *, token: str) -> int:
92
+ """Clone via HTTPS + token. Shallow clone (depth=1) for speed."""
93
+ url = f"https://x-access-token:{token}@github.com/{repo}.git"
94
+ proc = _run_git(["clone", "--depth=1", "--no-tags", url, str(dest)], cwd=Path.cwd())
95
+ if proc.returncode != 0:
96
+ # Don't print the URL (contains the token).
97
+ error(f"git clone {repo} failed (exit {proc.returncode})")
98
+ if proc.stderr:
99
+ # Strip the token from any URLs in stderr.
100
+ sanitised = proc.stderr.replace(token, "***")
101
+ error(sanitised.rstrip())
102
+ return proc.returncode
103
+ _git_setup_identity(dest)
104
+ return 0
105
+
106
+
107
+ def _git_setup_identity(repo: Path) -> None:
108
+ """Configure a default committer identity inside the cloned repo."""
109
+ actor = os.environ.get("GITHUB_ACTOR", "hyperi-ci")
110
+ email = f"{actor}@users.noreply.github.com"
111
+ _run_git(["config", "user.name", actor], cwd=repo, check=True)
112
+ _run_git(["config", "user.email", email], cwd=repo, check=True)
113
+
114
+
115
+ def _push_direct(
116
+ *,
117
+ clone_dir: Path,
118
+ cfg: GitopsPushConfig,
119
+ token: str,
120
+ ) -> int:
121
+ rel = Path(cfg.path)
122
+ proc = _run_git(["add", str(rel)], cwd=clone_dir)
123
+ if proc.returncode != 0:
124
+ error(proc.stderr.rstrip() if proc.stderr else "git add failed")
125
+ return proc.returncode
126
+ proc = _run_git(["commit", "-m", cfg.commit_message], cwd=clone_dir)
127
+ if proc.returncode != 0:
128
+ # `nothing to commit` is a no-op success
129
+ if "nothing to commit" in (proc.stdout or "") + (proc.stderr or ""):
130
+ info(" argocd: nothing to commit — content unchanged")
131
+ return 0
132
+ error(proc.stderr.rstrip() if proc.stderr else "git commit failed")
133
+ return proc.returncode
134
+
135
+ proc = _run_git(["push", "origin", cfg.branch_main], cwd=clone_dir)
136
+ if proc.returncode != 0:
137
+ error(proc.stderr.replace(token, "***").rstrip())
138
+ return proc.returncode
139
+
140
+ success(f" argocd: pushed {cfg.path} to {cfg.repo}@{cfg.branch_main}")
141
+ return 0
142
+
143
+
144
+ def _push_pr(
145
+ *,
146
+ clone_dir: Path,
147
+ target: Path,
148
+ cfg: GitopsPushConfig,
149
+ token: str,
150
+ ) -> int:
151
+ """Create a branch, push it, open a PR via GitHub API."""
152
+ branch_name = (
153
+ f"hyperi-ci/{cfg.path.replace('/', '-').replace('.yaml', '')}"
154
+ f"-{int(time.time())}"
155
+ )
156
+ proc = _run_git(["checkout", "-b", branch_name], cwd=clone_dir)
157
+ if proc.returncode != 0:
158
+ error(proc.stderr.rstrip())
159
+ return proc.returncode
160
+
161
+ proc = _run_git(["add", cfg.path], cwd=clone_dir)
162
+ if proc.returncode != 0:
163
+ error(proc.stderr.rstrip())
164
+ return proc.returncode
165
+ proc = _run_git(["commit", "-m", cfg.commit_message], cwd=clone_dir)
166
+ if proc.returncode != 0:
167
+ if "nothing to commit" in (proc.stdout or "") + (proc.stderr or ""):
168
+ info(" argocd: nothing to commit on PR branch — no PR opened")
169
+ return 0
170
+ error(proc.stderr.rstrip())
171
+ return proc.returncode
172
+
173
+ proc = _run_git(["push", "origin", branch_name], cwd=clone_dir)
174
+ if proc.returncode != 0:
175
+ error(proc.stderr.replace(token, "***").rstrip())
176
+ return proc.returncode
177
+
178
+ return _open_pr(cfg=cfg, branch=branch_name, token=token)
179
+
180
+
181
+ def _open_pr(*, cfg: GitopsPushConfig, branch: str, token: str) -> int:
182
+ """Open a GitHub PR via the REST API."""
183
+ title = cfg.commit_message.splitlines()[0]
184
+ body = (
185
+ f"Automated push from hyperi-ci.\n\n"
186
+ f"Updates `{cfg.path}` in this gitops repo.\n\n"
187
+ f"Merge to apply the change to the corresponding ArgoCD env.\n"
188
+ )
189
+ payload = {
190
+ "title": title,
191
+ "head": branch,
192
+ "base": cfg.branch_main,
193
+ "body": body,
194
+ }
195
+ cmd = [
196
+ "curl",
197
+ "-fsSL",
198
+ "-X",
199
+ "POST",
200
+ "-H",
201
+ f"Authorization: Bearer {token}",
202
+ "-H",
203
+ "Accept: application/vnd.github+json",
204
+ "-H",
205
+ "X-GitHub-Api-Version: 2022-11-28",
206
+ f"https://api.github.com/repos/{cfg.repo}/pulls",
207
+ "-d",
208
+ json.dumps(payload),
209
+ ]
210
+ proc = subprocess.run(
211
+ cmd,
212
+ capture_output=True,
213
+ text=True,
214
+ encoding="utf-8",
215
+ errors="replace",
216
+ check=False,
217
+ )
218
+ if proc.returncode != 0:
219
+ error(proc.stderr.replace(token, "***").rstrip())
220
+ return proc.returncode
221
+ try:
222
+ pr = json.loads(proc.stdout)
223
+ url = pr.get("html_url")
224
+ success(f" argocd: opened PR {url}")
225
+ except json.JSONDecodeError:
226
+ success(f" argocd: PR opened (response: {proc.stdout[:200]})")
227
+ return 0
228
+
229
+
230
+ def _run_git(
231
+ args: list[str], *, cwd: Path, check: bool = False
232
+ ) -> subprocess.CompletedProcess[str]:
233
+ return subprocess.run(
234
+ ["git", *args],
235
+ cwd=cwd,
236
+ capture_output=True,
237
+ text=True,
238
+ encoding="utf-8",
239
+ errors="replace",
240
+ check=check,
241
+ )